MCUXpresso_LPC55S69/middleware/usb/host/usb_host_ip3516hs.c
2022-04-08 22:42:47 +08:00

4069 lines
169 KiB
C

/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "usb_host_config.h"
#if (defined(USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
#include "usb_host.h"
#include "usb_host_hci.h"
#include "fsl_device_registers.h"
#include "usb_host_ip3516hs.h"
#include "usb_host_devices.h"
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "usb_phy.h"
#endif
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
((defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)))
#include "usb_hsdcd.h"
#endif
#if ((USB_HOST_CONFIG_IP3516HS_MAX_ISO >= 256) || (USB_HOST_CONFIG_IP3516HS_MAX_INT >= 256) || \
(USB_HOST_CONFIG_IP3516HS_MAX_ATL >= 256))
#error "This driver doesn't support same type pipe exceed 255."
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
#define USB_HOST_IP3516HS_TEST_DESCRIPTOR_LENGTH (18U)
#define USB_HOST_IP3516HS_PORTSC_PTC_J_STATE (0x01U)
#define USB_HOST_IP3516HS_PORTSC_PTC_K_STATE (0x02U)
#define USB_HOST_IP3516HS_PORTSC_PTC_SE0_NAK (0x03U)
#define USB_HOST_IP3516HS_PORTSC_PTC_PACKET (0x04U)
#define USB_HOST_IP3516HS_PORTSC_PTC_FORCE_ENABLE (0x05U)
#endif
/* reset recovery time (ms) */
#define USB_HOST_IP3516HS_PORT_RESET_RECOVERY_DELAY (11U)
/*******************************************************************************
* Prototypes
******************************************************************************/
static usb_status_t USB_HostIp3516HsGetBuffer(usb_host_ip3516hs_state_struct_t *usbHostState,
uint32_t length,
uint32_t MaxPacketSize,
uint32_t *index,
uint32_t *bufferLength);
static usb_status_t USB_HostIp3516HsFreeBuffer(usb_host_ip3516hs_state_struct_t *usbHostState,
uint32_t index,
uint32_t bufferLength);
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
/*!
* @brief suspend bus.
*
* @param usbHostState ip3516hs instance pointer.
*/
static void USB_HostIp3516HsSuspendBus(usb_host_ip3516hs_state_struct_t *usbHostState);
/*!
* @brief resume bus.
*
* @param usbHostState ip3516hs instance pointer.
*/
static void USB_HostIp3516HsResumeBus(usb_host_ip3516hs_state_struct_t *usbHostState);
extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
usb_host_transfer_t *transfer,
void *param);
static void USB_HostIp3516HsDelay(usb_host_ip3516hs_state_struct_t *usbHostState, uint32_t ms);
static void USB_HostIp3516HsTestModeInit(usb_device_handle deviceHandle);
#endif
/*******************************************************************************
* Variables
******************************************************************************/
USB_GLOBAL_DEDICATED_RAM USB_RAM_ADDRESS_ALIGNMENT(1024) static usb_host_ip3516hs_ptd_struct_t
s_UsbHostIp3516HsPtd[USB_HOST_CONFIG_IP3516HS];
static usb_host_ip3516hs_state_struct_t s_UsbHostIp3516HsState[USB_HOST_CONFIG_IP3516HS];
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U)) || \
(defined(USB_HOST_CONFIG_IP3516HS_MAX_INT) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static uint8_t s_SlotMaxBandwidth[8] = {125, 125, 125, 125, 125, 125, 50, 0};
#endif
USB_GLOBAL_DEDICATED_RAM static uint8_t s_UsbHostIp3516HsBufferArray[80][64];
/*******************************************************************************
* Code
******************************************************************************/
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
static usb_status_t USB_HostIp3516HsTestSetMode(usb_host_ip3516hs_state_struct_t *usbHostState, uint32_t testMode)
{
uint32_t Ip3516HsortSC;
Ip3516HsortSC = usbHostState->usbRegBase->PORTSC1;
Ip3516HsortSC &= ~((uint32_t)USBHSH_PORTSC1_PTC_MASK); /* clear test mode bits */
Ip3516HsortSC |= (testMode << USBHSH_PORTSC1_PTC_SHIFT); /* set test mode bits */
usbHostState->usbRegBase->PORTSC1 = Ip3516HsortSC;
return kStatus_USB_Success;
}
static void USB_HostIp3516HsTestSuspendResume(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint8_t timeCount;
timeCount = 15U * 8U; /* 15s */
while (0U != (timeCount--))
{
USB_HostIp3516HsDelay(usbHostState, 1000U);
}
USB_HostIp3516HsSuspendBus(usbHostState);
timeCount = 15U * 8U; /* 15s */
while (0U != (timeCount--))
{
USB_HostIp3516HsDelay(usbHostState, 1000U);
}
USB_HostIp3516HsResumeBus(usbHostState);
}
static void USB_HostIp3516HsTestCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
(void)USB_HostFreeTransfer(param, transfer);
usb_host_ip3516hs_state_struct_t *usbHostState = (usb_host_ip3516hs_state_struct_t *)param;
if (1U == usbHostState->complianceTestStart)
{
uint8_t timeCount;
usbHostState->complianceTest = 0U;
usbHostState->complianceTestStart = 0U;
timeCount = 15U * 8U; /* 15s */
while (0U != (timeCount--))
{
USB_HostIp3516HsDelay(usbHostState, 1000U);
}
(void)usb_echo("test_single_step_get_dev_desc_data finished\r\n");
}
}
static void USB_HostIp3516HsTestSingleStepGetDeviceDesc(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_device_handle deviceHandle)
{
usb_host_process_descriptor_param_t getDescriptorParam;
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
usb_host_transfer_t *transfer;
uint8_t timeCount;
/* disable periodic shedule */
usbHostState->usbRegBase->USBCMD &= ~(USB_HOST_IP3516HS_USBCMD_INT_EN_MASK | USB_HOST_IP3516HS_USBCMD_ISO_EN_MASK);
timeCount = 15U * 8U; /* 15s */
while (0U != (timeCount--))
{
USB_HostIp3516HsDelay(usbHostState, 1000U);
}
/* malloc one transfer */
if (USB_HostMallocTransfer(usbHostState->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("allocate transfer error\r\n");
#endif
return;
}
getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
getDescriptorParam.descriptorLength = 18;
getDescriptorParam.descriptorBuffer = (uint8_t *)&deviceInstance->deviceDescriptor;
getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
getDescriptorParam.descriptorIndex = 0;
getDescriptorParam.languageId = 0;
transfer->callbackFn = USB_HostIp3516HsTestCallback;
transfer->callbackParam = usbHostState->hostHandle;
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
transfer->setupPacket->wIndex = 0;
transfer->setupPacket->wLength = 0;
transfer->setupPacket->wValue = 0;
(void)USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
}
static void USB_HostIp3516HsTestSingleStepGetDeviceDescData(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_device_handle deviceHandle)
{
static uint8_t buffer[USB_HOST_IP3516HS_TEST_DESCRIPTOR_LENGTH];
usb_host_process_descriptor_param_t getDescriptorParam;
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
usb_host_transfer_t *transfer;
/* disable periodic shedule */
usbHostState->usbRegBase->USBCMD &= ~(USB_HOST_IP3516HS_USBCMD_INT_EN_MASK | USB_HOST_IP3516HS_USBCMD_ISO_EN_MASK);
/* malloc one transfer */
if (USB_HostMallocTransfer(usbHostState->hostHandle, &transfer) != kStatus_USB_Success)
{
#ifdef HOST_ECHO
usb_echo("allocate transfer error\r\n");
#endif
return;
}
usbHostState->complianceTestStart = 1;
getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
getDescriptorParam.descriptorLength = 18;
getDescriptorParam.descriptorBuffer = (uint8_t *)buffer;
getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
getDescriptorParam.descriptorIndex = 0;
getDescriptorParam.languageId = 0;
transfer->callbackFn = USB_HostIp3516HsTestCallback;
transfer->callbackParam = (void *)usbHostState;
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
transfer->setupPacket->wIndex = 0;
transfer->setupPacket->wLength = 0;
transfer->setupPacket->wValue = 0;
(void)USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
return;
}
static void USB_HostIp3516HsTestModeInit(usb_device_handle deviceHandle)
{
uint32_t productId;
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
usb_host_ip3516hs_state_struct_t *usbHostState =
(usb_host_ip3516hs_state_struct_t *)(((usb_host_instance_t *)(deviceInstance->hostHandle))->controllerHandle);
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDevicePID, &productId);
(void)usb_echo("usb host Ip3516hs test mode init product id:0x%x\r\n", productId);
switch (productId)
{
case 0x0101U:
(void)USB_HostIp3516HsTestSetMode(usbHostState, USB_HOST_IP3516HS_PORTSC_PTC_SE0_NAK);
break;
case 0x0102U:
(void)USB_HostIp3516HsTestSetMode(usbHostState, USB_HOST_IP3516HS_PORTSC_PTC_J_STATE);
break;
case 0x0103U:
(void)USB_HostIp3516HsTestSetMode(usbHostState, USB_HOST_IP3516HS_PORTSC_PTC_K_STATE);
break;
case 0x0104U:
(void)USB_HostIp3516HsTestSetMode(usbHostState, USB_HOST_IP3516HS_PORTSC_PTC_PACKET);
break;
case 0x0105U:
(void)usb_echo("set test mode FORCE_ENALBE\r\n");
(void)USB_HostIp3516HsTestSetMode(usbHostState, USB_HOST_IP3516HS_PORTSC_PTC_FORCE_ENABLE);
break;
case 0x0106U:
USB_HostIp3516HsTestSuspendResume(usbHostState);
break;
case 0x0107U:
(void)usb_echo("start test SINGLE_STEP_GET_DEV_DESC\r\n");
USB_HostIp3516HsTestSingleStepGetDeviceDesc(usbHostState, deviceHandle);
break;
case 0x0108U:
(void)usb_echo("start test SINGLE_STEP_GET_DEV_DESC_DATA\r\n");
USB_HostIp3516HsTestSingleStepGetDeviceDescData(usbHostState, deviceHandle);
break;
default:
/*default*/
break;
}
return;
}
static void USB_HostIp3516HsSuspendBus(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t portStatus;
portStatus = usbHostState->usbRegBase->PORTSC1;
USB_HostIp3516HsLock();
if (0U != (portStatus & USB_HOST_IP3516HS_PORTSC1_PED_MASK))
{
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_SUS_L1_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_SUSP_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
}
USB_HostIp3516HsUnlock();
}
static void USB_HostIp3516HsResumeBus(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t portStatus;
USB_HostIp3516HsLock();
/* Resume port */
portStatus = usbHostState->usbRegBase->PORTSC1;
if (portStatus & USB_HOST_IP3516HS_PORTSC1_PED_MASK)
{
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC);
portStatus |= USB_HOST_IP3516HS_PORTSC1_FPR_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
/**resume 21ms = 168/8*/
USB_HostIp3516HsDelay(usbHostState, 168U);
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
}
USB_HostIp3516HsUnlock();
}
#endif
static void USB_HostOhciDisableIsr(usb_host_ip3516hs_state_struct_t *usbHostState)
{
OSA_SR_ALLOC();
/* Enter critical */
OSA_ENTER_CRITICAL();
if (0U == usbHostState->isrLevel)
{
NVIC_DisableIRQ((IRQn_Type)usbHostState->isrNumber);
}
usbHostState->isrLevel++;
OSA_EXIT_CRITICAL();
}
static void USB_HostOhciEnableIsr(usb_host_ip3516hs_state_struct_t *usbHostState)
{
OSA_SR_ALLOC();
/* Enter critical */
OSA_ENTER_CRITICAL();
usbHostState->isrLevel--;
if (0U == usbHostState->isrLevel)
{
NVIC_EnableIRQ((IRQn_Type)usbHostState->isrNumber);
}
OSA_EXIT_CRITICAL();
}
static void USB_HostIp3516HsDelay(usb_host_ip3516hs_state_struct_t *usbHostState, uint32_t ms)
{
/* note: the max delay time cannot exceed half of max value (0x4000) */
uint32_t sofStart;
uint32_t SofEnd;
uint32_t distance;
sofStart = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
do
{
SofEnd = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
distance = (uint32_t)(
(SofEnd - sofStart + (USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK >> USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT) + 1U) &
(USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK >> USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT));
} while ((distance) < (ms)); /* compute the distance between sofStart and SofEnd */
}
/*seperate bus control to standlone alone function for misra Rule17.2*/
static usb_status_t USB_HostIp3516HsControlBusReset(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t portStatus = usbHostState->usbRegBase->PORTSC1;
usb_status_t status = kStatus_USB_Success;
portStatus &= ~USB_HOST_IP3516HS_PORTSC1_WIC;
usbHostState->usbRegBase->PORTSC1 = portStatus | USB_HOST_IP3516HS_PORTSC1_PR_MASK;
USB_HostIp3516HsDelay(usbHostState, 200);
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_PR_MASK);
usbHostState->usbRegBase->PORTSC1 = portStatus;
while (0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_PR_MASK))
{
__NOP();
}
return status;
}
static usb_status_t USB_HostIp3516HsControlBus(usb_host_ip3516hs_state_struct_t *usbHostState, uint8_t busControl)
{
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
uint32_t portStatus = usbHostState->usbRegBase->PORTSC1;
#endif
usb_status_t status = kStatus_USB_Success;
usb_host_bus_control_t controlCode = (usb_host_bus_control_t)busControl;
switch (controlCode)
{
case kUSB_HostBusReset:
(void)USB_HostIp3516HsControlBusReset(usbHostState);
break;
case kUSB_HostBusRestart:
break;
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
case kUSB_HostBusSuspend:
if (0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_CCS_MASK))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_SUS_L1_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_SUSP_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
usbHostState->matchTick = hostPointer->hwTick;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsStartSuspend;
while ((hostPointer->hwTick - usbHostState->matchTick) <= 5U)
{
}
portStatus = usbHostState->usbRegBase->USBCMD;
portStatus &= ~USB_HOST_IP3516HS_USBCMD_RS_MASK;
usbHostState->usbRegBase->USBCMD = portStatus;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventSuspended); /* call host callback function */
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsSuspended;
}
else
{
status = kStatus_USB_Error;
}
break;
case kUSB_HostBusResume:
if (0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_CCS_MASK))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsStartResume;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC);
portStatus |= USB_HOST_IP3516HS_PORTSC1_FPR_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
usbHostState->matchTick = hostPointer->hwTick;
while ((hostPointer->hwTick - usbHostState->matchTick) <= 20U)
{
}
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventResumed); /* call host callback function */
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
else
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
status = kStatus_USB_Error;
}
break;
#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
case kUSB_HostBusL1Sleep:
if (0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_CCS_MASK))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
portStatus = usbHostState->usbRegBase->USBCMD;
portStatus &= ~(USB_HOST_IP3516HS_USBCMD_HIRD_MASK | USB_HOST_IP3516HS_USBCMD_LPM_RWU_MASK);
portStatus |= (uint32_t)(
((uint32_t)usbHostState->hirdValue << USB_HOST_IP3516HS_USBCMD_HIRD_SHIFT) |
((uint32_t)usbHostState->L1remoteWakeupEnable << USB_HOST_IP3516HS_USBCMD_LPM_RWU_SHIFT));
usbHostState->usbRegBase->USBCMD = portStatus;
usb_host_device_instance_t *deviceInstance;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsL1StartSleep;
deviceInstance = (usb_host_device_instance_t *)hostPointer->suspendedDevice;
usbHostState->usbRegBase->PORTSC1 |= (uint32_t)(
(uint32_t)USB_HOST_IP3516HS_PORTSC1_SUSP_MASK | (uint32_t)USB_HOST_IP3516HS_PORTSC1_SUS_L1_MASK |
(((uint32_t)deviceInstance->setAddress << USB_HOST_IP3516HS_PORTSC1_DEV_ADD_SHIFT) &
(uint32_t)USB_HOST_IP3516HS_PORTSC1_DEV_ADD_MASK));
#if (defined(FSL_FEATURE_USBHSH_VERSION) && (FSL_FEATURE_USBHSH_VERSION >= 300U))
#else
while (0U == (usbHostState->usbRegBase->PORTSC1 &
(uint32_t)((uint32_t)USB_HOST_IP3516HS_PORTSC1_SUSP_MASK |
(uint32_t)USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK)))
{
__NOP();
}
portStatus = usbHostState->usbRegBase->PORTSC1;
if ((0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_SUSP_MASK)) &&
(0x00U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT)))
{
usbHostState->matchTick = hostPointer->hwTick;
while ((hostPointer->hwTick - usbHostState->matchTick) <= 4U)
{
}
portStatus = usbHostState->usbRegBase->USBCMD;
portStatus &= ~USB_HOST_IP3516HS_USBCMD_RS_MASK;
usbHostState->usbRegBase->USBCMD = portStatus;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsL1Sleeped;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1Sleeped); /* call host callback function */
}
else if (0x02U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT))
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(
hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1SleepNotSupport); /* call host callback function */
}
else if (0x01U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT))
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1SleepNYET); /* call host callback function */
}
else if (0x03U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT))
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1SleepError); /* call host callback function */
}
else
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
#endif
}
else
{
status = kStatus_USB_Error;
}
break;
case kUSB_HostBusL1Resume:
if (0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_CCS_MASK))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsStartResume;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC);
portStatus |= USB_HOST_IP3516HS_PORTSC1_FPR_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
while (0U != ((portStatus)&USB_HOST_IP3516HS_PORTSC1_FPR_MASK))
{
portStatus = (usbHostState->usbRegBase->PORTSC1);
portStatus = portStatus & USB_HOST_IP3516HS_PORTSC1_FPR_MASK;
}
usbHostState->matchTick = hostPointer->hwTick;
while ((hostPointer->hwTick - usbHostState->matchTick) <= 5U)
{
}
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1Resumed); /* call host callback function */
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
else
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
status = kStatus_USB_Error;
}
break;
#endif
#endif
case kUSB_HostBusEnableAttach:
if (0UL != (usbHostState->usbRegBase->HCSPARAMS &
USB_HOST_IP3516HS_HCSPARAMS_PPC_MASK)) /* Ports have power port switches */
{
/* only has one port */
uint32_t tmp = usbHostState->usbRegBase->PORTSC1;
tmp &= (~USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_PP_MASK);
usbHostState->usbRegBase->PORTSC1 = (tmp); /* turn on port power */
tmp = usbHostState->usbRegBase->PORTSC1;
tmp &= (~USB_HOST_IP3516HS_PORTSC1_WIC);
usbHostState->usbRegBase->PORTSC1 = (tmp | USB_HOST_IP3516HS_PORTSC1_PP_MASK); /* turn on port power */
}
(void)USB_HostIp3516HsControlBusReset(usbHostState);
usbHostState->portState[0].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortDetached;
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_PORT_CHANGE);
break;
case kUSB_HostBusDisableAttach:
break;
default:
status = kStatus_USB_Error;
break;
}
return status;
}
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U)) || \
(defined(USB_HOST_CONFIG_IP3516HS_MAX_INT) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static uint32_t USB_HostIp3516HsBusTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength)
{
uint32_t result = (3167U + ((1000U * dataLength) * 7U * 8U / 6U)) / 1000U;
if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */
{
if (speed == USB_SPEED_HIGH)
{
result = 2083U * (38U * 8U + result) + USB_HOST_IP3516HS_TIME_DELAY;
}
else if (speed == USB_SPEED_FULL)
{
if (direction == USB_IN)
{
result = 7268000U + 83540U * result + USB_HOST_IP3516HS_TIME_DELAY;
}
else
{
result = 6265000U + 83540U * result + USB_HOST_IP3516HS_TIME_DELAY;
}
}
else
{
/*no action*/
}
}
else
{
if (speed == USB_SPEED_HIGH)
{
result = 2083U * (55U * 8U + result) + USB_HOST_IP3516HS_TIME_DELAY;
}
else if (speed == USB_SPEED_FULL)
{
result = 9107000U + 83540U * result + USB_HOST_IP3516HS_TIME_DELAY;
}
else if (speed == USB_SPEED_LOW)
{
if (direction == USB_IN)
{
result = 64060000U + 2000U * USB_HOST_IP3516HS_HUB_LS_SETUP_TIME_DELAY + 676670U * result +
USB_HOST_IP3516HS_TIME_DELAY;
}
else
{
result = 64107000U + 2000U * USB_HOST_IP3516HS_HUB_LS_SETUP_TIME_DELAY + 667000U * result +
USB_HOST_IP3516HS_TIME_DELAY;
}
}
else
{
/*no action*/
}
}
result /= 1000000U;
if (result == 0U)
{
result = 1U;
}
else
{
/*no action*/
}
return result;
}
#endif
static usb_status_t USB_HostIp3516HsGetNewPipe(usb_host_ip3516hs_pipe_struct_t **pipeQueue,
usb_host_ip3516hs_pipe_struct_t **pipe)
{
usb_status_t error = kStatus_USB_Busy;
void *p;
OSA_SR_ALLOC();
/* get a pipe instance */
/* Enter critical */
OSA_ENTER_CRITICAL();
if (NULL != (*pipeQueue))
{
*pipe = *pipeQueue;
p = (void *)((*pipe)->pipeCommon.next);
*pipeQueue = (usb_host_ip3516hs_pipe_struct_t *)p;
error = kStatus_USB_Success;
}
/* Exit critical */
OSA_EXIT_CRITICAL();
return error;
}
static usb_status_t USB_HostIp3516HsRemovePipe(usb_host_ip3516hs_pipe_struct_t **pipeQueue,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_host_ip3516hs_pipe_struct_t *p = *pipeQueue;
usb_host_ip3516hs_pipe_struct_t *pre;
void *temp;
OSA_SR_ALLOC();
/* get a pipe instance */
/* Enter critical */
OSA_ENTER_CRITICAL();
pre = NULL;
while (NULL != p)
{
if (p != pipe)
{
pre = p;
temp = (void *)p->pipeCommon.next;
p = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
else
{
if (NULL != pre)
{
pre->pipeCommon.next = p->pipeCommon.next;
}
else
{
temp = (void *)p->pipeCommon.next;
*pipeQueue = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
break;
}
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsInsertPipe(usb_host_ip3516hs_pipe_struct_t **pipeQueue,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_host_ip3516hs_pipe_struct_t *p = *pipeQueue;
void *temp;
OSA_SR_ALLOC();
pipe->pipeCommon.next = NULL;
/* get a pipe instance */
/* Enter critical */
OSA_ENTER_CRITICAL();
while (NULL != p)
{
if (p != pipe)
{
temp = (void *)p->pipeCommon.next;
p = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
else
{
break;
}
}
if (NULL == p)
{
temp = (void *)(*pipeQueue);
pipe->pipeCommon.next = (usb_host_pipe_t *)temp;
*pipeQueue = pipe;
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsPortChange(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t portStatus;
uint8_t i = 0U;
for (i = 0U; i < usbHostState->portNumber; i++)
{
portStatus = usbHostState->usbRegBase->PORTSC1;
if (0U != (portStatus & USB_HOST_IP3516HS_PORTSC1_CSC_MASK))
{
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
if ((uint8_t)kBus_Ip3516HsIdle != usbHostState->busSuspendStatus)
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
#endif
uint32_t sofStart =
(uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
uint32_t sof;
while (1U == 1U)
{
portStatus = usbHostState->usbRegBase->PORTSC1;
if (0U != (portStatus & USB_HOST_IP3516HS_PORTSC1_CSC_MASK))
{
portStatus &= ~USB_HOST_IP3516HS_PORTSC1_WIC;
usbHostState->usbRegBase->PORTSC1 = portStatus | USB_HOST_IP3516HS_PORTSC1_CSC_MASK;
}
sof = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
if ((((sof + USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK + 1U) - sofStart) &
USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) > 1U)
{
break;
}
}
}
portStatus = usbHostState->usbRegBase->PORTSC1;
if (0U != (portStatus & USB_HOST_IP3516HS_PORTSC1_CCS_MASK))
{
uint32_t index;
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
/* set the charger type as SDP to disable the DCD function because the usb host start to works. */
uint8_t chargerType = (uint8_t)kUSB_DcdSDP;
#endif
if (kUSB_DeviceIp3516HsPortDetached !=
(usb_host_ip3516hs_port_state_t)usbHostState->portState[i].portStatus)
{
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
if (((uint8_t)kBus_Ip3516HsSuspended == usbHostState->busSuspendStatus))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsStartResume;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(
hostPointer->suspendedDevice, NULL,
(uint32_t)kUSB_HostEventDetectResume); /* call host callback function */
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC);
portStatus |= USB_HOST_IP3516HS_PORTSC1_FPR_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
usbHostState->matchTick = hostPointer->hwTick;
while ((hostPointer->hwTick - usbHostState->matchTick) <= 20U)
{
}
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventResumed); /* call host callback function */
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
if (((uint8_t)kBus_Ip3516HsL1Sleeped == usbHostState->busSuspendStatus))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsStartResume;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(
hostPointer->suspendedDevice, NULL,
(uint32_t)kUSB_HostEventDetectResume); /* call host callback function */
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
usbHostState->matchTick = hostPointer->hwTick;
while (0U != ((portStatus)&USB_HOST_IP3516HS_PORTSC1_FPR_MASK))
{
portStatus = (usbHostState->usbRegBase->PORTSC1);
portStatus = portStatus & USB_HOST_IP3516HS_PORTSC1_FPR_MASK;
if ((hostPointer->hwTick - usbHostState->matchTick) >= 1U)
{
break;
}
}
portStatus = usbHostState->usbRegBase->PORTSC1;
portStatus &= ~(USB_HOST_IP3516HS_PORTSC1_WIC | USB_HOST_IP3516HS_PORTSC1_FPR_MASK);
portStatus |= USB_HOST_IP3516HS_PORTSC1_PP_MASK | USB_HOST_IP3516HS_PORTSC1_PED_MASK;
usbHostState->usbRegBase->PORTSC1 = portStatus;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(
hostPointer->suspendedDevice, NULL,
(uint32_t)kUSB_HostEventL1Resumed); /* call host callback function */
hostPointer->suspendedDevice = NULL;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
#if (defined(FSL_FEATURE_USBHSH_VERSION) && (FSL_FEATURE_USBHSH_VERSION >= 300U))
else if (((uint8_t)kBus_Ip3516HsL1StartSleep == usbHostState->busSuspendStatus))
{
usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
portStatus = usbHostState->usbRegBase->PORTSC1;
if ((0U != (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_SUSP_MASK)) &&
(0x00U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT)))
{
portStatus = usbHostState->usbRegBase->USBCMD;
portStatus &= ~USB_HOST_IP3516HS_USBCMD_RS_MASK;
usbHostState->usbRegBase->USBCMD = portStatus;
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsL1Sleeped;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1Sleeped); /* call host callback function */
}
else if (0x02U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT))
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(
hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1SleepNotSupport); /* call host callback function */
}
else if (0x01U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT))
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1SleepNYET); /* call host callback function */
}
else if (0x03U == ((portStatus & USB_HOST_IP3516HS_PORTSC1_SUS_STAT_MASK) >>
USB_HOST_IP3516HS_PORTSC1_SUS_STAT_SHIFT))
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
/* call host callback function, function is initialized in USB_HostInit */
(void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
kUSB_HostEventL1SleepError); /* call host callback function */
}
else
{
usbHostState->busSuspendStatus = (uint8_t)kBus_Ip3516HsIdle;
}
}
#else
#endif
else
{
/* no action */
}
#endif
#endif
break;
}
for (index = 0U; index < USB_HOST_IP3516HS_PORT_CONNECT_DEBOUNCE_DELAY; index++)
{
USB_HostIp3516HsDelay(usbHostState, 8U);
if (0U == (usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_CCS_MASK))
{
break;
}
}
portStatus = usbHostState->usbRegBase->PORTSC1;
/* CCS is cleared ?*/
if ((0U == (portStatus & USB_HOST_IP3516HS_PORTSC1_CCS_MASK)) ||
(index < USB_HOST_IP3516HS_PORT_CONNECT_DEBOUNCE_DELAY))
{
usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortDetached;
continue;
}
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
USB_HSDCD_Control(usbHostState->dcdHandle, kUSB_HostHSDcdSetType, &(chargerType));
#endif
(void)USB_HostIp3516HsControlBus(usbHostState, (uint8_t)kUSB_HostBusReset);
USB_HostIp3516HsDelay(usbHostState, 81U);
usbHostState->portState[i].portSpeed =
(uint8_t)((usbHostState->usbRegBase->PORTSC1 & USB_HOST_IP3516HS_PORTSC1_PSPD_MASK) >>
USB_HOST_IP3516HS_PORTSC1_PSPD_SHIFT);
if (0x00U == usbHostState->portState[i].portSpeed)
{
usbHostState->portState[i].portSpeed = USB_SPEED_LOW;
}
else if (0x01U == usbHostState->portState[i].portSpeed)
{
usbHostState->portState[i].portSpeed = USB_SPEED_FULL;
}
else
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
/* enable phy disconnection */
USB_EhcihostPhyDisconnectDetectCmd((uint8_t)kUSB_ControllerIp3516Hs0 + usbHostState->controllerId, 1U);
#endif
}
/* do bus recovery delay */
USB_HostIp3516HsDelay(usbHostState, USB_HOST_IP3516HS_PORT_RESET_RECOVERY_DELAY * 8U);
usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortPhyAttached;
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_ATTACH);
}
else
{
if ((uint8_t)kUSB_DeviceIp3516HsPortDetached == usbHostState->portState[i].portStatus)
{
continue;
}
if ((uint8_t)kUSB_DeviceIp3516HsPortAttached == usbHostState->portState[i].portStatus)
{
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
/* disable phy disconnection */
USB_EhcihostPhyDisconnectDetectCmd((uint8_t)kUSB_ControllerIp3516Hs0 + usbHostState->controllerId, 0U);
#endif
usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortPhyDetached;
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
USB_HSDCD_Control(usbHostState->dcdHandle, kUSB_HostHSDcdSetType, &(usbHostState->chargerType));
#endif
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_DETACH);
}
else
{
usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortDetached;
}
}
}
return kStatus_USB_Success;
}
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U)) || \
(defined(USB_HOST_CONFIG_IP3516HS_MAX_INT) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static usb_status_t USB_HostIp3516HsFillSlotBusTime(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe,
uint32_t startUFrame,
uint8_t *slotTime,
uint8_t *ssSlot,
uint8_t *csSlot)
{
uint8_t slots = (uint8_t)((pipe->pipeCommon.maxPacketSize + 187U) / 188U);
uint8_t startSlot = (uint8_t)(startUFrame % 8UL);
for (uint8_t i = 0; i < 8U; i++)
{
slotTime[i] = 0U;
}
*ssSlot = 0U;
*csSlot = 0U;
if (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType)
{
if (USB_OUT == pipe->pipeCommon.direction)
{
if ((startSlot + slots) > 7U)
{
return kStatus_USB_Error;
}
for (uint8_t i = 0; i < (slots); i++)
{
slotTime[startSlot + i] = 125U;
*ssSlot |= (uint8_t)(1UL << (startSlot + i));
}
slotTime[startSlot + slots - 1U] = (uint8_t)(((pipe->pipeCommon.maxPacketSize % 188U) * 125U) / 188U);
}
else
{
if ((startSlot + slots + 1U) > 8U)
{
return kStatus_USB_Error;
}
*ssSlot = 1U << startSlot;
for (uint8_t i = 0U; i < (slots); i++)
{
slotTime[startSlot + 1U + i] = 125U;
*csSlot |= (uint8_t)(1UL << (startSlot + 1U + i));
}
slotTime[startSlot + 1U + slots - 1U] = (uint8_t)(((pipe->pipeCommon.maxPacketSize % 188U) * 125U) / 188U);
}
}
else if (USB_ENDPOINT_INTERRUPT == pipe->pipeCommon.pipeType)
{
if ((startSlot + 3U + 2U) > 8U)
{
return kStatus_USB_Error;
}
*ssSlot = 1U << startSlot;
for (uint8_t i = 0U; i < 3U; i++)
{
*csSlot |= (uint8_t)(1UL << (startSlot + 2U + i));
}
if (USB_OUT == pipe->pipeCommon.direction)
{
slotTime[startSlot] = (uint8_t)pipe->busNoneHsTime;
}
else
{
for (uint8_t i = 0U; i < 3U; i++)
{
slotTime[startSlot + 2U + i] = (uint8_t)pipe->busNoneHsTime;
}
}
}
else
{
/*no action*/
}
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsFindStartFrame(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_host_ip3516hs_pipe_struct_t *p;
uint32_t startUFrame;
uint32_t frame;
uint32_t total = 0U;
void *temp;
uint8_t slotTime[8];
uint8_t speed = ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed;
pipe->startUFrame = 0U;
if (NULL == usbHostState->pipeListInUsing)
{
return kStatus_USB_Success;
}
for (startUFrame = 0U; startUFrame < ((uint32_t)pipe->pipeCommon.interval); startUFrame++)
{
for (frame = startUFrame; frame < USB_HOST_IP3516HS_MAX_UFRAME; frame += pipe->pipeCommon.interval)
{
total = pipe->busHsTime;
/* using temp for misra 14.2, 10.4*/
temp = (void *)usbHostState->pipeListInUsing;
while (NULL != temp)
{
p = (usb_host_ip3516hs_pipe_struct_t *)temp;
temp = (void *)p->pipeCommon.next;
if ((frame >= p->startUFrame) && ((p->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
(p->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)))
{
if (USB_SPEED_HIGH == speed)
{
if (0U == ((frame - p->startUFrame) % p->pipeCommon.interval))
{
total += p->busHsTime;
}
else
{
}
}
else
{
if (USB_OUT == p->pipeCommon.direction)
{
if (0U == ((frame - p->startUFrame) % p->pipeCommon.interval))
{
total += p->busHsTime;
}
else
{
}
}
else
{
for (uint32_t cs = 0U; cs < 8U; cs++)
{
if (0U != (p->csSlot & (1U << cs)))
{
if (0U == ((frame - (cs + (uint32_t)(((uint32_t)p->startUFrame) & 0xFFF8U))) %
(uint32_t)(p->pipeCommon.interval)))
{
total += p->busHsTime;
}
else
{
}
}
}
}
}
}
}
if ((float)total > USB_HOST_IP3516HS_PERIODIC_BANDWIDTH)
{
break;
}
}
do
{
if ((frame >= USB_HOST_IP3516HS_MAX_UFRAME) && (USB_SPEED_HIGH != speed))
{
uint32_t hsHubNumber;
usb_status_t error;
uint8_t totalSlotTime[8];
uint8_t deviceSlotTime[8];
hsHubNumber = 0U;
frame = startUFrame;
for (uint32_t i = 0; i < 8U; i++)
{
totalSlotTime[i] = 0U;
deviceSlotTime[i] = 0U;
slotTime[i] = 0U;
}
error = USB_HostIp3516HsFillSlotBusTime(usbHostState, pipe, startUFrame, slotTime, &pipe->ssSlot,
&pipe->csSlot);
if (kStatus_USB_Success != error)
{
break;
}
/* compute FS/LS bandwidth that blong to same high-speed hub, because FS/LS bandwidth is allocated from
* first parent high-speed hub */
(void)USB_HostHelperGetPeripheralInformation(pipe->pipeCommon.deviceHandle,
(uint32_t)kUSB_HostGetDeviceHSHubNumber, &hsHubNumber);
for (frame = startUFrame; frame < USB_HOST_IP3516HS_MAX_UFRAME; frame += pipe->pipeCommon.interval)
{
total = 0U;
temp = (void *)usbHostState->pipeListInUsing;
while (NULL != temp)
{
p = (usb_host_ip3516hs_pipe_struct_t *)temp;
temp = (void *)p->pipeCommon.next;
if ((frame >= p->startUFrame) && ((p->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
(p->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)))
{
uint32_t deviceHsHubNumber = 0U;
(void)USB_HostHelperGetPeripheralInformation(p->pipeCommon.deviceHandle,
(uint32_t)kUSB_HostGetDeviceHSHubNumber,
&deviceHsHubNumber);
if ((deviceHsHubNumber == hsHubNumber) &&
(0U == (((frame & 0xFFFFFFF8U) - (p->startUFrame & 0xFFF8U)) % p->pipeCommon.interval)))
{
uint8_t ss;
uint8_t cs;
(void)USB_HostIp3516HsFillSlotBusTime(usbHostState, pipe, startUFrame, deviceSlotTime,
&ss, &cs);
for (uint32_t i = 0; i < 8U; i++)
{
totalSlotTime[i] += deviceSlotTime[i];
}
}
}
}
for (uint32_t i = 0; i < 8U; i++)
{
if ((totalSlotTime[i] + slotTime[i]) > s_SlotMaxBandwidth[i])
{
break;
}
}
}
}
} while (0U == 1U);
if (frame >= USB_HOST_IP3516HS_MAX_UFRAME)
{
pipe->startUFrame = (uint16_t)startUFrame;
return kStatus_USB_Success;
}
}
return kStatus_USB_BandwidthFail;
}
static usb_status_t USB_HostIp3516BaudWidthCheck(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_status_t error;
uint8_t speed = ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed;
OSA_SR_ALLOC();
pipe->busHsTime = (uint16_t)USB_HostIp3516HsBusTime(
USB_SPEED_HIGH, pipe->pipeCommon.pipeType, pipe->pipeCommon.direction,
((uint32_t)pipe->pipeCommon.maxPacketSize) * ((uint32_t)pipe->pipeCommon.numberPerUframe));
if (USB_SPEED_HIGH != speed)
{
uint32_t thinkTime = 0U;
pipe->busNoneHsTime = (uint16_t)USB_HostIp3516HsBusTime(
speed, pipe->pipeCommon.pipeType, pipe->pipeCommon.direction, pipe->pipeCommon.maxPacketSize);
(void)USB_HostHelperGetPeripheralInformation(pipe->pipeCommon.deviceHandle, (uint32_t)kUSB_HostGetHubThinkTime,
&thinkTime); /* Get the hub think time */
pipe->busNoneHsTime += (uint16_t)(thinkTime * 7U / (6U * 12U));
}
OSA_ENTER_CRITICAL();
error = USB_HostIp3516HsFindStartFrame(usbHostState, pipe);
OSA_EXIT_CRITICAL();
return error;
}
#endif
static usb_status_t USB_HostIp3516HsOpenControlBulkPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_host_ip3516hs_atl_struct_t *atl;
OSA_SR_ALLOC();
/* Enter critical */
OSA_ENTER_CRITICAL();
for (uint8_t i = 0;
i < (sizeof(s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl) / sizeof(usb_host_ip3516hs_atl_struct_t));
i++)
{
if (0U == s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[i].control1Union.stateBitField.MaxPacketLength)
{
pipe->tdIndex = i;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[i].control1Union.stateBitField.MaxPacketLength =
pipe->pipeCommon.maxPacketSize;
break;
}
}
/* Exit critical */
OSA_EXIT_CRITICAL();
if (0xFFU == pipe->tdIndex)
{
return kStatus_USB_Busy;
}
atl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex];
atl->control1Union.stateBitField.Mult = pipe->pipeCommon.numberPerUframe;
atl->control2Union.stateBitField.EP = pipe->pipeCommon.endpointAddress;
atl->control2Union.stateBitField.DeviceAddress =
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->setAddress;
if (USB_SPEED_HIGH == usbHostState->portState[0].portSpeed)
{
atl->control2Union.stateBitField.S =
(USB_SPEED_HIGH == ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed) ? 0U : 1U;
}
else
{
atl->control2Union.stateBitField.S = 0U;
}
atl->control2Union.stateBitField.RL = 0xFU;
atl->stateUnion.stateBitField.NakCnt = 0xFU;
atl->control2Union.stateBitField.SE =
(USB_SPEED_LOW == ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed) ? 2U : 0U;
atl->control2Union.stateBitField.PortNumber =
#if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB > 0U))
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->hsHubPort;
#else
0U;
#endif
atl->control2Union.stateBitField.HubAddress =
#if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB > 0U))
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->hsHubNumber;
#else
0U;
#endif
atl->dataUnion.dataBitField.I = 1U;
atl->stateUnion.stateBitField.EpType = pipe->pipeCommon.pipeType;
atl->stateUnion.stateBitField.DT = 0U;
atl->stateUnion.stateBitField.P = 0U;
return kStatus_USB_Success;
}
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
static usb_status_t USB_HostIp3516HsOpenIsoPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_host_ip3516hs_ptl_struct_t *ptl;
usb_host_ip3516hs_sptl_struct_t *sptl;
uint32_t count = 0;
void *temp;
usb_status_t error;
OSA_SR_ALLOC();
error = USB_HostIp3516BaudWidthCheck(usbHostState, pipe);
if (kStatus_USB_Success != error)
{
return error;
}
/* Enter critical */
OSA_ENTER_CRITICAL();
for (uint32_t i = 0U; i < USB_HOST_CONFIG_IP3516HS_MAX_ISO; i++)
{
for (uint32_t j = i;
(j < (USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER + i)) && (j < USB_HOST_CONFIG_IP3516HS_MAX_ISO); j++)
{
if (0U ==
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[j].control1Union.stateBitField.MaxPacketLength)
{
count++;
}
}
if (count >= USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER)
{
pipe->tdIndex = (uint8_t)i;
for (uint32_t j = i;
(j < (USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER + i)) && (j < USB_HOST_CONFIG_IP3516HS_MAX_ISO); j++)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[j].control1Union.stateBitField.MaxPacketLength =
pipe->pipeCommon.maxPacketSize;
}
break;
}
else
{
count = 0;
}
}
/* Exit critical */
OSA_EXIT_CRITICAL();
if (0xFFU == pipe->tdIndex)
{
return kStatus_USB_Busy;
}
for (uint32_t j = pipe->tdIndex; (j < ((uint32_t)USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER + pipe->tdIndex)) &&
(j < USB_HOST_CONFIG_IP3516HS_MAX_ISO);
j++)
{
ptl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[j];
temp = (void *)ptl;
sptl = (usb_host_ip3516hs_sptl_struct_t *)temp;
ptl->control1Union.stateBitField.Mult = pipe->pipeCommon.numberPerUframe;
ptl->control2Union.stateBitField.EP = pipe->pipeCommon.endpointAddress;
ptl->control2Union.stateBitField.DeviceAddress =
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->setAddress;
if (USB_SPEED_HIGH == usbHostState->portState[0].portSpeed)
{
ptl->control2Union.stateBitField.S =
(USB_SPEED_HIGH == ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed) ? 0U : 1U;
}
else
{
ptl->control2Union.stateBitField.S = 0U;
}
ptl->control2Union.stateBitField.RL = 0U;
ptl->stateUnion.stateBitField.NakCnt = 0U;
ptl->control2Union.stateBitField.SE =
(USB_SPEED_LOW == ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed) ? 2U : 0U;
if (0U != ptl->control2Union.stateBitField.S)
{
sptl->control2Union.stateBitField.PortNumber =
#if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB > 0U))
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->hsHubPort;
#else
0U;
#endif
sptl->control2Union.stateBitField.HubAddress =
#if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB > 0U))
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->hsHubNumber;
#else
0U;
#endif
}
else
{
sptl->control2Union.stateBitField.PortNumber = 0U;
sptl->control2Union.stateBitField.HubAddress = 0U;
}
ptl->dataUnion.dataBitField.NrBytesToTransfer = 0U;
ptl->dataUnion.dataBitField.I = 1U;
ptl->stateUnion.stateBitField.EpType = pipe->pipeCommon.pipeType;
ptl->stateUnion.stateBitField.DT = 0U;
ptl->stateUnion.stateBitField.P = 0U;
}
return kStatus_USB_Success;
}
#endif
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_INT) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static usb_status_t USB_HostIp3516HsOpenInterruptPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
usb_host_ip3516hs_ptl_struct_t *ptl;
usb_host_ip3516hs_sptl_struct_t *sptl;
usb_status_t error;
void *temp;
OSA_SR_ALLOC();
error = USB_HostIp3516BaudWidthCheck(usbHostState, pipe);
if (kStatus_USB_Success != error)
{
return error;
}
/* Enter critical */
OSA_ENTER_CRITICAL();
for (uint8_t i = 0; i < USB_HOST_CONFIG_IP3516HS_MAX_INT; i++)
{
if (0U ==
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].control1Union.stateBitField.MaxPacketLength)
{
pipe->tdIndex = i;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].control1Union.stateBitField.MaxPacketLength =
pipe->pipeCommon.maxPacketSize;
break;
}
}
/* Exit critical */
OSA_EXIT_CRITICAL();
if (0xFFU == pipe->tdIndex)
{
pipe->pipeCommon.open = 0U;
/* release the pipe */
(void)USB_HostIp3516HsInsertPipe(&usbHostState->pipeList, pipe);
return kStatus_USB_Busy;
}
ptl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[pipe->tdIndex];
temp = (void *)ptl;
sptl = (usb_host_ip3516hs_sptl_struct_t *)temp;
ptl->control1Union.stateBitField.Mult = pipe->pipeCommon.numberPerUframe;
ptl->control2Union.stateBitField.EP = pipe->pipeCommon.endpointAddress;
ptl->control2Union.stateBitField.DeviceAddress =
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->setAddress;
if (USB_SPEED_HIGH == usbHostState->portState[0].portSpeed)
{
ptl->control2Union.stateBitField.S =
(USB_SPEED_HIGH == ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed) ? 0U : 1U;
}
else
{
ptl->control2Union.stateBitField.S = 0U;
}
ptl->control2Union.stateBitField.RL = 0xFU;
ptl->stateUnion.stateBitField.NakCnt = 0xFU;
ptl->control2Union.stateBitField.SE =
(USB_SPEED_LOW == ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed) ? 2U : 0U;
if (0U != ptl->control2Union.stateBitField.S)
{
sptl->control2Union.stateBitField.PortNumber =
#if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB > 0U))
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->hsHubPort;
#else
0U;
#endif
sptl->control2Union.stateBitField.HubAddress =
#if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB > 0U))
((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->hsHubNumber;
#else
0U;
#endif
}
else
{
sptl->control2Union.stateBitField.PortNumber = 0U;
sptl->control2Union.stateBitField.HubAddress = 0U;
}
ptl->dataUnion.dataBitField.I = 1U;
ptl->stateUnion.stateBitField.EpType = pipe->pipeCommon.pipeType;
ptl->stateUnion.stateBitField.DT = 0U;
ptl->stateUnion.stateBitField.P = 0U;
return kStatus_USB_Success;
}
#endif
static usb_status_t USB_HostIp3516HsCancelPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe,
usb_host_transfer_t *tr)
{
usb_host_transfer_t *trCurrent;
usb_host_transfer_t *trPos;
usb_host_transfer_t *trPre;
uint32_t startUFrame;
uint32_t currentUFrame;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
indexLength_t indexLength;
#endif
usb_status_t trStatus = kStatus_USB_Success;
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
case USB_ENDPOINT_CONTROL:
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
usbHostState->usbRegBase->INT_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
usbHostState->usbRegBase->ISO_PTD_SKIP_MAP |= ((1UL << USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER) - 1U)
<< pipe->tdIndex;
break;
#endif
default:
/*no action*/
break;
}
startUFrame = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
currentUFrame = startUFrame;
while (currentUFrame == startUFrame)
{
currentUFrame = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
}
USB_HostIp3516HsLock();
trCurrent = pipe->trList;
trPre = NULL;
while (NULL != trCurrent)
{
trPos = trCurrent->next;
if ((NULL == tr) || (tr == trCurrent))
{
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
case USB_ENDPOINT_CONTROL:
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if (1U ==
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.H)
{
trStatus = kStatus_USB_TransferStall;
}
else if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.B) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.X))
{
trStatus = kStatus_USB_TransferFailed;
}
else
{
if (((trCurrent->transferSofar != trCurrent->transferLength) ||
(pipe->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)) &&
(kStatus_USB_Success == trStatus))
{
if (kStatus_USB_Success == (usb_status_t)trCurrent->union1.transferResult)
{
trStatus = kStatus_USB_TransferCancel;
}
else
{
trStatus = kStatus_USB_TransferFailed;
trCurrent->union1.transferResult = (int32_t)kStatus_USB_Success;
}
}
}
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.A = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].control1Union.stateBitField.V =
0U;
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if (0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.H)
{
trStatus = kStatus_USB_TransferStall;
}
else if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.B) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.X))
{
trStatus = kStatus_USB_TransferFailed;
}
else
{
if ((0U == trCurrent->transferSofar) && (kStatus_USB_Success == trStatus))
{
trStatus = kStatus_USB_TransferCancel;
}
}
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.A = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.control1Union.stateBitField.V = 0U;
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
indexLength.indexLength = trCurrent->union2.frame;
trCurrent->union2.frame = 0;
if (0U != indexLength.indexLength)
{
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if (0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.H)
{
trStatus = kStatus_USB_TransferStall;
}
else if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.B) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.X))
{
trStatus = kStatus_USB_TransferFailed;
}
else
{
if ((0U == trCurrent->transferSofar) && (kStatus_USB_Success == trStatus))
{
trStatus = kStatus_USB_TransferCancel;
}
}
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.A = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.control1Union.stateBitField.V = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.dataUnion.dataBitField.NrBytesToTransfer = 0U;
}
else
{
trStatus = kStatus_USB_TransferCancel;
}
pipe->bufferIndex = indexLength.state.bufferIndex;
pipe->bufferLength = indexLength.state.bufferLength;
break;
#endif
default:
/*no action*/
break;
}
if (0UL != pipe->bufferLength)
{
(void)USB_HostIp3516HsFreeBuffer(usbHostState, pipe->bufferIndex, pipe->bufferLength);
pipe->bufferLength = 0U;
}
if (NULL != trPre)
{
trPre->next = trPos;
}
else
{
pipe->trList = trPos;
}
pipe->cutOffTime = USB_HOST_IP3516HS_TRANSFER_TIMEOUT_GAP;
pipe->isBusy = 0U;
/* callback function is different from the current condition */
trCurrent->callbackFn(trCurrent->callbackParam, trCurrent, trStatus); /* transfer callback */
}
else
{
trPre = trCurrent;
}
trCurrent = trPos;
}
USB_HostIp3516HsUnlock();
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
case USB_ENDPOINT_CONTROL:
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
usbHostState->usbRegBase->INT_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
usbHostState->usbRegBase->ISO_PTD_SKIP_MAP &=
~(((1UL << USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER) - 1U) << pipe->tdIndex);
break;
#endif
default:
/*no action*/
break;
}
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsCloseControlBulkPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
OSA_SR_ALLOC();
(void)USB_HostIp3516HsCancelPipe(usbHostState, pipe, NULL);
/* Enter critical */
OSA_ENTER_CRITICAL();
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].control1Union.stateBitField.V = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].control1Union.stateBitField.MaxPacketLength =
0U;
/* Exit critical */
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
static usb_status_t USB_HostIp3516HsCloseIsoPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
OSA_SR_ALLOC();
(void)USB_HostIp3516HsCancelPipe(usbHostState, pipe, NULL);
/* Enter critical */
OSA_ENTER_CRITICAL();
for (uint32_t i = 0; i < USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER; i++)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[pipe->tdIndex + i].control1Union.stateBitField.V = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[pipe->tdIndex + i]
.control1Union.stateBitField.MaxPacketLength = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[pipe->tdIndex + i]
.dataUnion.dataBitField.NrBytesToTransfer = 0U;
}
/* Exit critical */
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static usb_status_t USB_HostIp3516HsCloseInterruptPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe)
{
OSA_SR_ALLOC();
(void)USB_HostIp3516HsCancelPipe(usbHostState, pipe, NULL);
/* Enter critical */
OSA_ENTER_CRITICAL();
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[pipe->tdIndex].control1Union.stateBitField.V = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.control1Union.stateBitField.MaxPacketLength = 0U;
/* Exit critical */
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
#endif
static usb_status_t USB_HostIp3516HsGetBuffer(usb_host_ip3516hs_state_struct_t *usbHostState,
uint32_t length,
uint32_t MaxPacketSize,
uint32_t *index,
uint32_t *bufferLength)
{
uint32_t i;
uint32_t startIndex = 0xFFFFFFFFU;
uint32_t freeBufferSize = 0U;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
for (i = 0U; i < (sizeof(s_UsbHostIp3516HsBufferArray) / (sizeof(uint8_t) * 64U)); i++)
{
if (0U != (usbHostState->bufferArrayBitMap[i >> 5U] & (1UL << (i % 32U))))
{
freeBufferSize = 0U;
startIndex = 0xFFFFFFFFU;
}
else
{
freeBufferSize += 64U;
if (0xFFFFFFFFU == startIndex)
{
startIndex = i;
}
if (length <= freeBufferSize)
{
break;
}
}
}
if (0xFFFFFFFFU != startIndex)
{
*index = startIndex;
*bufferLength = freeBufferSize;
for (; startIndex <= i; startIndex++)
{
usbHostState->bufferArrayBitMap[startIndex >> 5U] |= (1UL << (startIndex % 32U));
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
if (MaxPacketSize >= length)
{
OSA_EXIT_CRITICAL();
return kStatus_USB_Busy;
}
for (i = 0U; i < (sizeof(s_UsbHostIp3516HsBufferArray) / (sizeof(uint8_t) * 64U)); i++)
{
if (0U != (usbHostState->bufferArrayBitMap[i >> 5U] & (1UL << (i % 32U))))
{
freeBufferSize = 0U;
startIndex = 0xFFFFFFFFU;
}
else
{
freeBufferSize += 64U;
if (0xFFFFFFFFU == startIndex)
{
startIndex = i;
}
if (length <= MaxPacketSize)
{
break;
}
}
}
if (0xFFFFFFFFU != startIndex)
{
*index = startIndex;
*bufferLength = freeBufferSize;
for (; startIndex <= i; startIndex++)
{
usbHostState->bufferArrayBitMap[startIndex >> 5U] |= (1UL << (startIndex % 32U));
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Busy;
}
static usb_status_t USB_HostIp3516HsFreeBuffer(usb_host_ip3516hs_state_struct_t *usbHostState,
uint32_t index,
uint32_t bufferLength)
{
uint32_t i;
uint32_t indexCount = (bufferLength - 1U) / 64U + 1U;
if ((indexCount + index) > (sizeof(s_UsbHostIp3516HsBufferArray) / (sizeof(uint8_t) * 64U)))
{
indexCount = (sizeof(s_UsbHostIp3516HsBufferArray) / (sizeof(uint8_t) * 64U)) - index;
}
for (i = index; i < (index + indexCount); i++)
{
usbHostState->bufferArrayBitMap[i >> 5U] &= ~(1UL << (i % 32U));
}
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsWriteControlPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe,
usb_host_transfer_t *tr)
{
usb_host_ip3516hs_atl_struct_t *atl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex];
uint8_t *bufferAddress;
uint32_t transferLength;
usb_status_t status = kStatus_USB_Success;
usb_host_ip3516hs_transfer_status_t transferStstus;
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
uint8_t timeCount;
#endif
OSA_SR_ALLOC();
if (1U == pipe->isBusy)
{
return kStatus_USB_Success;
}
OSA_ENTER_CRITICAL();
pipe->isBusy = 1U;
OSA_EXIT_CRITICAL();
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
if (1U == usbHostState->complianceTest)
{
timeCount = 15 * 8; /* 15s */
while (0U != (timeCount--))
{
USB_HostIp3516HsDelay(usbHostState, 1000U);
}
}
#endif
transferStstus = (usb_host_ip3516hs_transfer_status_t)tr->setupStatus;
switch (transferStstus)
{
case kStatus_UsbHostIp3516Hs_Idle:
if (0U != pipe->bufferLength)
{
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
}
else
{
transferLength = pipe->pipeCommon.maxPacketSize;
if (kStatus_USB_Success == USB_HostIp3516HsGetBuffer(usbHostState, transferLength,
pipe->pipeCommon.maxPacketSize, &pipe->bufferIndex,
&pipe->bufferLength))
{
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
}
else
{
OSA_ENTER_CRITICAL();
pipe->isBusy = 2U;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
for (uint8_t i = 0; i < 8U; i++)
{
bufferAddress[i] = ((uint8_t *)tr->setupPacket)[i];
}
atl->control2Union.stateBitField.RL = 0U;
atl->stateUnion.stateBitField.P = 0U;
atl->stateUnion.stateBitField.NakCnt = 0U;
atl->stateUnion.stateBitField.Cerr = 0x3U;
atl->dataUnion.dataBitField.NrBytesToTransfer = 8U;
atl->stateUnion.stateBitField.NrBytesToTransfer = 0U;
atl->dataUnion.dataBitField.DataStartAddress = ((uint32_t)(bufferAddress)) & 0x0000FFFFU;
atl->dataUnion.dataBitField.I = 1U;
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_SETUP;
atl->stateUnion.stateBitField.DT = 0x00U;
atl->stateUnion.stateBitField.SC = 0x00U;
tr->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_Setup;
atl->control1Union.stateBitField.V = 0x01U;
atl->stateUnion.stateBitField.A = 0x01U;
break;
case kStatus_UsbHostIp3516Hs_Data2:
case kStatus_UsbHostIp3516Hs_Setup:
transferLength = (tr->transferLength - tr->transferSofar);
if (transferLength > pipe->bufferLength)
{
transferLength = pipe->bufferLength;
}
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
if (USB_OUT == tr->direction)
{
for (uint32_t i = 0; i < transferLength; i++)
{
bufferAddress[i] = tr->transferBuffer[tr->transferSofar + i];
}
}
atl->control2Union.stateBitField.RL = 0U;
atl->stateUnion.stateBitField.NakCnt = 0U;
atl->stateUnion.stateBitField.Cerr = 0x3U;
atl->dataUnion.dataBitField.NrBytesToTransfer = transferLength;
atl->stateUnion.stateBitField.NrBytesToTransfer = 0U;
atl->dataUnion.dataBitField.DataStartAddress = ((uint32_t)(bufferAddress)) & 0x0000FFFFU;
atl->dataUnion.dataBitField.I = 1U;
atl->stateUnion.stateBitField.SC = 0x00U;
if (0U != transferLength)
{
if (USB_IN == tr->direction)
{
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_IN;
atl->stateUnion.stateBitField.P = 0x00U;
}
else
{
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_OUT;
}
if (transferLength < (tr->transferLength - tr->transferSofar))
{
tr->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_Data2;
}
else
{
tr->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_Data;
}
}
else
{
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_IN;
tr->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_State;
}
atl->control1Union.stateBitField.V = 0x01U;
atl->stateUnion.stateBitField.A = 0x01U;
break;
case kStatus_UsbHostIp3516Hs_Data:
tr->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_State;
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
atl->control2Union.stateBitField.RL = 0U;
atl->stateUnion.stateBitField.NakCnt = 0U;
atl->stateUnion.stateBitField.Cerr = 0x3U;
atl->dataUnion.dataBitField.NrBytesToTransfer = 0;
atl->stateUnion.stateBitField.NrBytesToTransfer = 0U;
atl->dataUnion.dataBitField.DataStartAddress = ((uint32_t)(bufferAddress)) & 0x0000FFFFU;
atl->dataUnion.dataBitField.I = 1U;
atl->stateUnion.stateBitField.DT = 1U;
atl->stateUnion.stateBitField.P = 0x00U;
atl->stateUnion.stateBitField.SC = 0x00U;
if (USB_OUT == tr->direction)
{
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_IN;
}
else
{
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_OUT;
}
atl->control1Union.stateBitField.V = 0x01U;
atl->stateUnion.stateBitField.A = 0x01U;
break;
default:
status = kStatus_USB_Error;
tr->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_Idle;
OSA_ENTER_CRITICAL();
pipe->isBusy = 0U;
OSA_EXIT_CRITICAL();
break;
}
return status;
}
static usb_status_t USB_HostIp3516HsWriteBulkPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe,
usb_host_transfer_t *tr)
{
usb_host_ip3516hs_atl_struct_t *atl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex];
uint32_t transferLength;
uint8_t *bufferAddress;
OSA_SR_ALLOC();
if (1U == pipe->isBusy)
{
return kStatus_USB_Success;
}
OSA_ENTER_CRITICAL();
pipe->isBusy = 1U;
OSA_EXIT_CRITICAL();
transferLength = (tr->transferLength - tr->transferSofar);
if (0U != pipe->bufferLength)
{
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
}
else
{
if (transferLength > 4096U)
{
transferLength = 4096U;
}
if (kStatus_USB_Success == USB_HostIp3516HsGetBuffer(usbHostState, transferLength,
pipe->pipeCommon.maxPacketSize, &pipe->bufferIndex,
&pipe->bufferLength))
{
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
}
else
{
OSA_ENTER_CRITICAL();
pipe->isBusy = 2U;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
}
if (transferLength > pipe->bufferLength)
{
transferLength = pipe->bufferLength;
}
/*transferLength should be positive*/
if ((USB_OUT == tr->direction) && (transferLength > 0U))
{
(void)memcpy((void *)bufferAddress, (void *)(&tr->transferBuffer[tr->transferSofar]), transferLength);
}
atl->control2Union.stateBitField.RL = 0U;
atl->stateUnion.stateBitField.NakCnt = 0U;
atl->stateUnion.stateBitField.Cerr = 0x3U;
atl->dataUnion.dataBitField.NrBytesToTransfer = transferLength;
atl->stateUnion.stateBitField.NrBytesToTransfer = 0U;
atl->dataUnion.dataBitField.DataStartAddress = ((uint32_t)(bufferAddress)) & 0x0000FFFFU;
atl->dataUnion.dataBitField.I = 1U;
atl->stateUnion.stateBitField.SC = 0x00U;
if (USB_IN == tr->direction)
{
atl->stateUnion.stateBitField.P = 0x00U;
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_IN;
}
else
{
atl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_OUT;
}
atl->control1Union.stateBitField.V = 0x01U;
atl->stateUnion.stateBitField.A = 0x01U;
return kStatus_USB_Success;
}
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
static usb_status_t USB_HostIp3516HsWriteIsoPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe,
usb_host_transfer_t *tr)
{
usb_host_ip3516hs_ptl_struct_t *ptl;
usb_host_ip3516hs_sptl_struct_t *sptl;
usb_host_transfer_t *currentTr;
uint32_t transferLength;
uint32_t currentUFrame;
uint32_t insertUFrame;
uint32_t primedUFrame;
uint32_t tdIndex;
indexLength_t indexLength;
uint8_t *bufferAddress;
void *temp;
uint8_t speed = ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
currentTr = tr;
while (NULL != currentTr)
{
transferLength = (currentTr->transferLength - currentTr->transferSofar);
indexLength.indexLength = currentTr->union2.frame;
if (0U == indexLength.indexLength)
{
uint32_t bufferIndex;
uint32_t bufferLength;
tdIndex = 0xFFU;
for (uint32_t i = 0U; i < (USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER); i++)
{
ptl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[pipe->tdIndex + i];
if (0U == ptl->dataUnion.dataBitField.NrBytesToTransfer)
{
tdIndex = pipe->tdIndex + i;
temp = (void *)ptl;
sptl = (usb_host_ip3516hs_sptl_struct_t *)temp;
break;
}
}
if (0xFFUL == tdIndex)
{
break;
}
if (kStatus_USB_Success == USB_HostIp3516HsGetBuffer(usbHostState, transferLength,
pipe->pipeCommon.maxPacketSize, &bufferIndex,
&bufferLength))
{
indexLength.state.bufferIndex = bufferIndex;
indexLength.state.bufferLength = bufferLength;
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[indexLength.state.bufferIndex][0];
}
else
{
break;
}
indexLength.state.tdIndex = tdIndex;
currentTr->union2.frame = indexLength.indexLength;
}
else
{
currentTr = currentTr->next;
continue;
}
if (transferLength > indexLength.state.bufferLength)
{
transferLength = indexLength.state.bufferLength;
}
if (USB_OUT == currentTr->direction)
{
for (uint32_t i = 0; i < transferLength; i++)
{
bufferAddress[i] = currentTr->transferBuffer[currentTr->transferSofar + i];
}
}
if (USB_SPEED_HIGH != speed)
{
if (transferLength > pipe->pipeCommon.maxPacketSize)
{
transferLength = pipe->pipeCommon.maxPacketSize;
}
}
ptl->control2Union.stateBitField.RL = 0U;
ptl->stateUnion.stateBitField.NakCnt = 0U;
ptl->stateUnion.stateBitField.Cerr = 0U;
ptl->dataUnion.dataBitField.NrBytesToTransfer = transferLength;
ptl->stateUnion.stateBitField.NrBytesToTransfer = 0U;
ptl->dataUnion.dataBitField.DataStartAddress = ((uint32_t)(bufferAddress)) & 0x0000FFFFU;
ptl->dataUnion.dataBitField.I = 1U;
ptl->stateUnion.stateBitField.SC = 0x00U;
ptl->stateUnion.stateBitField.H = 0U;
ptl->stateUnion.stateBitField.X = 0U;
ptl->stateUnion.stateBitField.B = 0U;
if (USB_IN == currentTr->direction)
{
ptl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_IN;
}
else
{
ptl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_OUT;
}
ptl->statusUnion.status = 0U;
ptl->isoInUnion1.isoIn = 0U;
ptl->isoInUnion2.isoIn = 0U;
ptl->isoInUnion3.isoIn = 0U;
currentUFrame = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
currentUFrame = currentUFrame & 0xFFU;
primedUFrame = ((uint32_t)pipe->lastPrimedIndex + pipe->pipeCommon.interval) & 0xFFU;
if (primedUFrame < currentUFrame)
{
primedUFrame = primedUFrame + 0x100U;
}
if (primedUFrame >= (currentUFrame + USB_HOST_IP3516HS_PERIODIC_TRANSFER_GAP))
{
primedUFrame = primedUFrame & 0xFFU;
insertUFrame = primedUFrame;
}
else
{
insertUFrame =
pipe->startUFrame + ((currentUFrame - pipe->startUFrame + USB_HOST_IP3516HS_PERIODIC_TRANSFER_GAP +
pipe->pipeCommon.interval - 1U) &
(~(pipe->pipeCommon.interval - 1U)));
}
pipe->lastPrimedIndex = (uint16_t)insertUFrame;
if (USB_SPEED_HIGH == speed)
{
uint32_t primedLength = currentTr->transferSofar;
ptl->control1Union.stateBitField.uFrame = insertUFrame & 0xF8U;
ptl->statusUnion.statusBitField.uSA = 0U;
for (uint16_t i = (uint16_t)(insertUFrame & 0x07UL); (i < 8U); i += pipe->pipeCommon.interval)
{
primedLength += (uint32_t)pipe->pipeCommon.maxPacketSize * pipe->pipeCommon.numberPerUframe;
ptl->statusUnion.statusBitField.uSA |= 1UL << i;
if (primedLength >= currentTr->transferLength)
{
break;
}
}
}
else
{
if (0U != (ptl->control2Union.stateBitField.S))
{
#if (defined(FSL_FEATURE_USBHSH_VERSION) && (FSL_FEATURE_USBHSH_VERSION >= 300U))
if (USB_IN == currentTr->direction)
{
if (transferLength <= 192U)
{
sptl->control1Union.stateBitField.MaxPacketLength = transferLength;
}
else
{
sptl->control1Union.stateBitField.MaxPacketLength = 192U;
}
}
else
#endif
{
if (transferLength <= 188U)
{
#if (defined(FSL_FEATURE_USBHSH_VERSION) && (FSL_FEATURE_USBHSH_VERSION >= 300U))
sptl->control1Union.stateBitField.MaxPacketLength = transferLength;
#else
sptl->control1Union.stateBitField.MaxPacketLength = transferLength + 1U;
#endif
}
else
{
sptl->control1Union.stateBitField.MaxPacketLength = 188U;
}
}
}
else
{
sptl->control1Union.stateBitField.MaxPacketLength = pipe->pipeCommon.maxPacketSize;
}
sptl->control1Union.stateBitField.uFrame = insertUFrame & 0xF8U;
sptl->statusUnion.statusBitField.uSA = pipe->ssSlot;
sptl->isoInUnion1.bitField.uSCS = pipe->csSlot;
}
ptl->control1Union.stateBitField.V = 0x01U;
ptl->stateUnion.stateBitField.A = 0x01U;
currentTr = currentTr->next;
}
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static usb_status_t USB_HostIp3516HsWriteInterruptPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
usb_host_ip3516hs_pipe_struct_t *pipe,
usb_host_transfer_t *tr)
{
usb_host_ip3516hs_ptl_struct_t *ptl = &s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[pipe->tdIndex];
usb_host_ip3516hs_sptl_struct_t *sptl;
uint32_t transferLength;
uint32_t currentUFrame;
uint32_t insertUFrame;
uint8_t *bufferAddress;
void *temp;
uint8_t speed = ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed;
temp = (void *)ptl;
sptl = (usb_host_ip3516hs_sptl_struct_t *)temp;
OSA_SR_ALLOC();
if (1U == pipe->isBusy)
{
return kStatus_USB_Success;
}
OSA_ENTER_CRITICAL();
pipe->isBusy = 1U;
OSA_EXIT_CRITICAL();
transferLength = (tr->transferLength - tr->transferSofar);
if (transferLength > pipe->pipeCommon.maxPacketSize)
{
transferLength = pipe->pipeCommon.maxPacketSize;
}
if (kStatus_USB_Success == USB_HostIp3516HsGetBuffer(usbHostState, transferLength, pipe->pipeCommon.maxPacketSize,
&pipe->bufferIndex, &pipe->bufferLength))
{
bufferAddress = (uint8_t *)&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0];
}
else
{
OSA_ENTER_CRITICAL();
pipe->isBusy = 2U;
OSA_EXIT_CRITICAL();
return kStatus_USB_Success;
}
if (USB_OUT == tr->direction)
{
for (uint32_t i = 0; i < transferLength; i++)
{
bufferAddress[i] = tr->transferBuffer[tr->transferSofar + i];
}
}
ptl->control2Union.stateBitField.RL = 0U;
ptl->stateUnion.stateBitField.NakCnt = 0x0FU;
ptl->stateUnion.stateBitField.Cerr = 0x3U;
ptl->dataUnion.dataBitField.NrBytesToTransfer = transferLength;
ptl->stateUnion.stateBitField.NrBytesToTransfer = 0U;
ptl->dataUnion.dataBitField.DataStartAddress = ((uint32_t)(bufferAddress)) & 0x0000FFFFU;
ptl->dataUnion.dataBitField.I = 1U;
ptl->stateUnion.stateBitField.P = 0x00U;
ptl->stateUnion.stateBitField.SC = 0x00U;
if (USB_IN == tr->direction)
{
ptl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_IN;
}
else
{
ptl->stateUnion.stateBitField.Token = USB_HOST_IP3516HS_PTD_TOKEN_OUT;
}
ptl->statusUnion.status = 0U;
ptl->isoInUnion1.isoIn = 0U;
ptl->isoInUnion2.isoIn = 0U;
ptl->isoInUnion3.isoIn = 0U;
currentUFrame = (uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
currentUFrame = currentUFrame & 0xFFU;
insertUFrame = pipe->startUFrame + ((currentUFrame - pipe->startUFrame + USB_HOST_IP3516HS_PERIODIC_TRANSFER_GAP +
pipe->pipeCommon.interval - 1U) &
(~(pipe->pipeCommon.interval - 1U)));
ptl->control1Union.stateBitField.uFrame = (insertUFrame & 0xF8U);
switch (pipe->pipeCommon.interval)
{
case 1:
case 2:
case 4:
case 8:
break;
case 16:
ptl->control1Union.stateBitField.uFrame |= 1U;
break;
case 32:
ptl->control1Union.stateBitField.uFrame |= 2U;
break;
case 64:
ptl->control1Union.stateBitField.uFrame |= 3U;
break;
case 128:
ptl->control1Union.stateBitField.uFrame |= 4U;
break;
case 256:
ptl->control1Union.stateBitField.uFrame |= 5U;
break;
default:
/*no action*/
break;
}
if (USB_SPEED_HIGH == speed)
{
for (uint32_t i = (insertUFrame & 0x07U); i < 8U; i += pipe->pipeCommon.interval)
{
ptl->statusUnion.statusBitField.uSA |= 1UL << i;
}
}
else
{
sptl->statusUnion.statusBitField.uSA = pipe->ssSlot;
sptl->isoInUnion1.bitField.uSCS = pipe->csSlot;
}
ptl->control1Union.stateBitField.V = 0x01U;
ptl->stateUnion.stateBitField.A = 0x01U;
return kStatus_USB_Success;
}
#endif
static usb_host_ip3516hs_pipe_struct_t *USB_HostIp3516HsGetPipe(usb_host_ip3516hs_state_struct_t *usbHostState,
uint8_t pipeType,
uint8_t tdIndex)
{
usb_host_ip3516hs_pipe_struct_t *p = usbHostState->pipeListInUsing;
void *temp;
OSA_SR_ALLOC();
OSA_ENTER_CRITICAL();
while (p != NULL)
{
if ((p->pipeCommon.pipeType == pipeType) && (p->tdIndex == tdIndex))
{
OSA_EXIT_CRITICAL();
return p;
}
if ((p->pipeCommon.pipeType == pipeType) && (USB_ENDPOINT_ISOCHRONOUS == pipeType) && (p->tdIndex >= tdIndex) &&
(tdIndex < (p->tdIndex + USB_HOST_IP3516HS_ISO_MULTIPLE_TRANSFER)))
{
OSA_EXIT_CRITICAL();
return p;
}
temp = (void *)p->pipeCommon.next;
p = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
OSA_EXIT_CRITICAL();
return NULL;
}
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
static usb_status_t USB_HostIp3516HsCheckIsoTransferSofar(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t tokenDoneBits = usbHostState->usbRegBase->ISO_PTD_DONE_MAP;
usb_host_ip3516hs_pipe_struct_t *p;
if (0U == tokenDoneBits)
{
return kStatus_USB_Success;
}
for (uint8_t i = 0; i < 32U; i++)
{
if (0U != (tokenDoneBits & (1UL << i)))
{
if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[i].stateUnion.stateBitField.A) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[i].control1Union.stateBitField.V))
{
continue;
}
p = USB_HostIp3516HsGetPipe(usbHostState, USB_ENDPOINT_ISOCHRONOUS, i);
if (NULL != p)
{
p->isBusy = 0U;
#if 0
if (NULL != p->trList)
{
usb_host_transfer_t *trCurrent = p->trList;
if ((s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[p->tdIndex].stateUnion.stateBitField.B) ||
(s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[p->tdIndex].stateUnion.stateBitField.X))
{
trCurrent->union1.transferResult = kStatus_USB_TransferFailed;
}
else
{
trCurrent->union1.transferResult = kStatus_USB_Success;
}
if (USB_IN == trCurrent->direction)
{
memcpy(&trCurrent->transferBuffer[trCurrent->transferSofar], &s_UsbHostIp3516HsBufferArray[p->bufferIndex][0], s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[p->tdIndex].stateUnion.stateBitField.NrBytesToTransfer);
}
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[p->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if (p->trList)
{
p->currentTr = p->trList->next;
}
else
{
p->currentTr = NULL;
}
if (p->currentTr)
{
uint32_t trValue = (uint32_t)p->currentTr;
USB_HostIp3516HsWriteIsoPipe(usbHostState, p, (usb_host_transfer_t *)trValue);
}
}
#endif
}
}
}
usbHostState->usbRegBase->ISO_PTD_DONE_MAP = tokenDoneBits;
return kStatus_USB_Success;
}
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
static usb_status_t USB_HostIp3516HsCheckIntTransferSofar(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t tokenDoneBits = usbHostState->usbRegBase->INT_PTD_DONE_MAP;
usb_host_ip3516hs_pipe_struct_t *p;
if (0U == tokenDoneBits)
{
return kStatus_USB_Success;
}
for (uint8_t i = 0; i < 32U; i++)
{
if (0U != (tokenDoneBits & (1UL << i)))
{
if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].stateUnion.stateBitField.A) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].control1Union.stateBitField.V))
{
continue;
}
p = USB_HostIp3516HsGetPipe(usbHostState, USB_ENDPOINT_INTERRUPT, i);
if (NULL != p)
{
p->isBusy = 0U;
}
}
}
usbHostState->usbRegBase->INT_PTD_DONE_MAP = tokenDoneBits;
return kStatus_USB_Success;
}
#endif
static usb_status_t USB_HostIp3516HsCheckAtlTransferSofar(usb_host_ip3516hs_state_struct_t *usbHostState)
{
uint32_t tokenDoneBits = usbHostState->usbRegBase->ATL_PTD_DONE_MAP;
usb_host_ip3516hs_pipe_struct_t *p;
if (0U == tokenDoneBits)
{
return kStatus_USB_Success;
}
for (uint8_t i = 0; i < 32U; i++)
{
if (0U != (tokenDoneBits & (1UL << i)))
{
p = USB_HostIp3516HsGetPipe(usbHostState, USB_ENDPOINT_CONTROL, i);
if (NULL != p)
{
p->isBusy = 0U;
}
p = USB_HostIp3516HsGetPipe(usbHostState, USB_ENDPOINT_BULK, i);
if ((NULL != p))
{
p->isBusy = 0U;
}
}
}
usbHostState->usbRegBase->ATL_PTD_DONE_MAP = tokenDoneBits;
return kStatus_USB_Success;
}
static void USB_HostIp3516HsCheckGetBufferFailedPipe(usb_host_ip3516hs_state_struct_t *usbHostState)
{
usb_host_ip3516hs_pipe_struct_t *pipe = usbHostState->pipeListInUsing;
void *temp;
while (NULL != pipe)
{
if (2U == pipe->isBusy)
{
if (NULL != pipe->trList)
{
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
(void)USB_HostIp3516HsWriteBulkPipe(usbHostState, pipe, pipe->trList);
break;
case USB_ENDPOINT_CONTROL:
(void)USB_HostIp3516HsWriteControlPipe(usbHostState, pipe, pipe->trList);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
(void)USB_HostIp3516HsWriteIsoPipe(usbHostState, pipe, pipe->trList);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
(void)USB_HostIp3516HsWriteInterruptPipe(usbHostState, pipe, pipe->trList);
break;
#endif
default:
/*no action*/
break;
}
}
}
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
}
static usb_status_t USB_HostIp3516HsTokenDone(usb_host_ip3516hs_state_struct_t *usbHostState)
{
usb_host_ip3516hs_pipe_struct_t *pipe;
usb_host_transfer_t *trCurrent;
usb_host_ip3516hs_pipe_struct_t *p;
uint32_t startUFrame;
uint32_t currentUFrame;
usb_host_ip3516hs_transfer_status_t transferStatus;
void *temp;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
indexLength_t indexLength;
#endif
usb_status_t trStatus;
uint8_t trDone;
/* Enter critical */
USB_HostIp3516HsLock();
USB_HostOhciDisableIsr(usbHostState);
pipe = usbHostState->pipeListInUsing;
while (NULL != pipe)
{
trStatus = kStatus_USB_Success;
trCurrent = pipe->trList;
if (NULL == trCurrent)
{
}
else
{
trDone = 0;
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_CONTROL:
if (0U != pipe->isBusy)
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
transferStatus = (usb_host_ip3516hs_transfer_status_t)trCurrent->setupStatus;
switch (transferStatus)
{
case kStatus_UsbHostIp3516Hs_Idle:
break;
case kStatus_UsbHostIp3516Hs_Setup:
break;
case kStatus_UsbHostIp3516Hs_Data2:
if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer) &&
(0U == (s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer %
pipe->pipeCommon.maxPacketSize)))
{
}
else
{
trCurrent->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_Data;
}
if (USB_IN == trCurrent->direction)
{
(void)memcpy((void *)(&trCurrent->transferBuffer[trCurrent->transferSofar]),
(void *)(&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0]),
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer);
}
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
break;
case kStatus_UsbHostIp3516Hs_Data:
if (USB_IN == trCurrent->direction)
{
(void)memcpy((void *)(&trCurrent->transferBuffer[trCurrent->transferSofar]),
(void *)(&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0]),
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer);
}
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
break;
case kStatus_UsbHostIp3516Hs_State:
break;
default:
/*no action*/
break;
}
if (!((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.A) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.control1Union.stateBitField.V)))
{
trDone = 1U;
}
if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.B) ||
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.X))
{
trStatus = kStatus_USB_TransferFailed;
}
else if (0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.H)
{
trStatus = kStatus_USB_TransferStall;
}
else
{
if (0U != trDone)
{
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
if (1U == usbHostState->complianceTestStart)
{
usbHostState->complianceTest++;
}
#endif
(void)USB_HostIp3516HsWriteControlPipe(usbHostState, pipe, pipe->trList);
}
}
if (0U != pipe->isBusy)
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.H = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.X = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.B = 0U;
break;
case USB_ENDPOINT_BULK:
if (0U != pipe->isBusy)
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
if (USB_IN == trCurrent->direction)
{
uint32_t length = s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
(void)memcpy((void *)(&trCurrent->transferBuffer[trCurrent->transferSofar]),
(void *)(&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0]), length);
}
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if (!((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.A) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.control1Union.stateBitField.V)))
{
trDone = 1U;
}
if (0U !=
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.H)
{
trStatus = kStatus_USB_TransferStall;
}
else if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.B) ||
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.stateUnion.stateBitField.X))
{
trStatus = kStatus_USB_TransferFailed;
}
else
{
if (0U != trDone)
{
if ((0U == (pipe->trList->transferLength % pipe->pipeCommon.maxPacketSize)) &&
(pipe->trList->transferSofar < pipe->trList->transferLength))
{
(void)USB_HostIp3516HsWriteBulkPipe(usbHostState, pipe, pipe->trList);
}
}
}
if (0U != pipe->isBusy)
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.H = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.X = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[pipe->tdIndex].stateUnion.stateBitField.B = 0U;
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
if (0U != pipe->isBusy)
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
if (!((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.A) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.control1Union.stateBitField.V)))
{
trDone = 1U;
}
if (USB_IN == trCurrent->direction)
{
(void)memcpy((void *)(&trCurrent->transferBuffer[trCurrent->transferSofar]),
(void *)(&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0]),
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer);
}
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if (1U == s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.H)
{
trStatus = kStatus_USB_TransferStall;
}
else if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.B) ||
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.X))
{
trStatus = kStatus_USB_TransferFailed;
}
else
{
/*no action*/
}
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.H = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.X = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.stateUnion.stateBitField.B = 0U;
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
#if 1
indexLength.indexLength = trCurrent->union2.frame;
trCurrent->union2.frame = 0u;
if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.A) &&
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.control1Union.stateBitField.V))
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
pipe->bufferIndex = indexLength.state.bufferIndex;
pipe->bufferLength = indexLength.state.bufferLength;
if (USB_IN == trCurrent->direction)
{
(void)memcpy((void *)(&trCurrent->transferBuffer[trCurrent->transferSofar]),
(void *)(&s_UsbHostIp3516HsBufferArray[pipe->bufferIndex][0]),
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer);
}
trCurrent->transferSofar += s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.NrBytesToTransfer;
if ((0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.B) ||
(0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.stateUnion.stateBitField.X))
{
trCurrent->union1.transferResult = (int32_t)kStatus_USB_TransferFailed;
}
else
{
trCurrent->union1.transferResult = (int32_t)kStatus_USB_Success;
}
if (NULL != pipe->trList)
{
pipe->currentTr = pipe->trList->next;
}
else
{
pipe->currentTr = NULL;
}
if (NULL != pipe->currentTr)
{
uint32_t trValue = (uint32_t)pipe->currentTr;
(void)USB_HostIp3516HsWriteIsoPipe(usbHostState, pipe, (usb_host_transfer_t *)trValue);
}
#else
if (pipe->trList == pipe->currentTr)
{
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
continue;
}
#endif
trDone = 1U;
trStatus = (usb_status_t)trCurrent->union1.transferResult;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[indexLength.state.tdIndex]
.dataUnion.dataBitField.NrBytesToTransfer = 0U;
break;
#endif
default:
/*no action*/
break;
}
if (0U != trDone)
{
pipe->trList = trCurrent->next;
#if 0
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
if ((USB_ENDPOINT_ISOCHRONOUS != pipe->pipeCommon.pipeType) && (pipe->bufferLength))
#else
if ((pipe->bufferLength)
#endif
#else
if ((0U != pipe->bufferLength))
#endif
{
(void)USB_HostIp3516HsFreeBuffer(usbHostState, pipe->bufferIndex, pipe->bufferLength);
pipe->bufferLength = 0U;
}
pipe->cutOffTime = USB_HOST_IP3516HS_TRANSFER_TIMEOUT_GAP;
if ((kStatus_USB_Success == (trStatus)) && (USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType) &&
(USB_REQUEST_STANDARD_CLEAR_FEATURE == trCurrent->setupPacket->bRequest) &&
(USB_REQUEST_TYPE_RECIPIENT_ENDPOINT == trCurrent->setupPacket->bmRequestType) &&
(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT ==
(USB_SHORT_FROM_LITTLE_ENDIAN(trCurrent->setupPacket->wValue) & 0x00FFU)))
{
p = usbHostState->pipeListInUsing;
while (p != NULL)
{
/* only compute bulk and interrupt pipe */
if ((p->pipeCommon.deviceHandle == pipe->pipeCommon.deviceHandle) &&
((p->pipeCommon.endpointAddress |
(p->pipeCommon.direction << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) ==
((uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(trCurrent->setupPacket->wIndex)))))
{
break;
}
temp = (void *)p->pipeCommon.next;
p = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
if ((NULL != p) && ((USB_ENDPOINT_BULK == p->pipeCommon.pipeType) ||
(USB_ENDPOINT_INTERRUPT == p->pipeCommon.pipeType)))
{
if (USB_ENDPOINT_BULK == p->pipeCommon.pipeType)
{
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP |= 1UL << p->tdIndex;
}
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
else if (USB_ENDPOINT_INTERRUPT == p->pipeCommon.pipeType)
{
usbHostState->usbRegBase->INT_PTD_SKIP_MAP |= 1UL << p->tdIndex;
}
#endif
else
{
}
startUFrame = (uint32_t)(
(usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
currentUFrame = startUFrame;
while (currentUFrame == startUFrame)
{
currentUFrame = (uint32_t)(
(usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
}
if (USB_ENDPOINT_BULK == p->pipeCommon.pipeType)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[p->tdIndex]
.stateUnion.stateBitField.DT = 0U;
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP &= ~(1UL << p->tdIndex);
}
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
else if (USB_ENDPOINT_INTERRUPT == p->pipeCommon.pipeType)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[p->tdIndex]
.stateUnion.stateBitField.DT = 0U;
usbHostState->usbRegBase->INT_PTD_SKIP_MAP &= ~(1UL << p->tdIndex);
}
#endif
else
{
}
}
}
/* callback function is different from the current condition */
trCurrent->callbackFn(trCurrent->callbackParam, trCurrent, trStatus); /* transfer callback */
USB_HostIp3516HsCheckGetBufferFailedPipe(usbHostState);
if (NULL != pipe->trList)
{
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
(void)USB_HostIp3516HsWriteBulkPipe(usbHostState, pipe, pipe->trList);
break;
case USB_ENDPOINT_CONTROL:
(void)USB_HostIp3516HsWriteControlPipe(usbHostState, pipe, pipe->trList);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
(void)USB_HostIp3516HsWriteIsoPipe(usbHostState, pipe, pipe->trList);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
(void)USB_HostIp3516HsWriteInterruptPipe(usbHostState, pipe, pipe->trList);
break;
#endif
default:
/*no action*/
break;
}
}
}
}
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
USB_HostOhciEnableIsr(usbHostState);
USB_HostIp3516HsUnlock();
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsSof(usb_host_ip3516hs_state_struct_t *usbHostState)
{
usb_host_ip3516hs_pipe_struct_t *pipe;
void *temp;
/* Enter critical */
USB_HostIp3516HsLock();
pipe = usbHostState->pipeListInUsing;
while (NULL != pipe)
{
if ((USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType) || (USB_ENDPOINT_BULK == pipe->pipeCommon.pipeType))
{
if (NULL != pipe->trList)
{
pipe->cutOffTime--;
if (0U == pipe->cutOffTime)
{
pipe->trList->union1.transferResult = (int)kStatus_USB_TransferFailed;
(void)USB_HostIp3516HsCancelPipe(usbHostState, pipe, pipe->trList);
}
}
}
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
/* Exit critical */
USB_HostIp3516HsUnlock();
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsControllerReset(usb_host_ip3516hs_state_struct_t *usbHostState)
{
usbHostState->usbRegBase->USBCMD = USB_HOST_IP3516HS_USBCMD_HCRESET_MASK;
while (0U != (usbHostState->usbRegBase->USBCMD & USB_HOST_IP3516HS_USBCMD_HCRESET_MASK))
{
__NOP();
}
return kStatus_USB_Success;
}
static usb_status_t USB_HostIp3516HsControllerInit(usb_host_ip3516hs_state_struct_t *usbHostState)
{
usb_host_ip3516hs_pipe_struct_t *pipe;
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_GTD) && (USB_HOST_CONFIG_IP3516HS_MAX_GTD > 0U))
usb_host_ip3516hs_atl_struct_t *gtd;
#endif
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_ITD) && (USB_HOST_CONFIG_IP3516HS_MAX_ITD > 0U))
usb_host_ip3516hs_isochronous_transfer_descritpor_struct_t *itd;
#endif
uint32_t i;
uint32_t interruptState;
void *temp;
OSA_SR_ALLOC();
/* Enter critical */
OSA_ENTER_CRITICAL();
for (i = 0U; i < (sizeof(usbHostState->bufferArrayBitMap) / (sizeof(uint32_t))); i++)
{
usbHostState->bufferArrayBitMap[i] = 0xFFFFFFFFU;
}
for (i = 0U; i < (sizeof(s_UsbHostIp3516HsBufferArray) / (sizeof(uint8_t) * 64U)); i++)
{
usbHostState->bufferArrayBitMap[i >> 5U] &= ~(1UL << (i % 32U));
}
for (i = 0U;
i < (sizeof(s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl) / sizeof(usb_host_ip3516hs_atl_struct_t));
i++)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[i].control1Union.controlState = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[i].control2Union.controlState = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[i].dataUnion.data = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[i].stateUnion.state = 0U;
}
usbHostState->usbRegBase->ATL_PTD_BASE_ADDRESS =
(((uint32_t)(&s_UsbHostIp3516HsPtd[usbHostState->controllerId].atl[0])) &
USB_HOST_IP3516HS_ATL_PTD_ATL_BASE_MASK);
usbHostState->usbRegBase->LAST_PTD_IN_USE = (i - 1U) & USB_HOST_IP3516HS_LAST_PTD_IN_USE_ATL_LAST_MASK;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_ATL_EN_MASK;
interruptState = USB_HOST_IP3516HS_USBINTR_ATL_IRQ_E_MASK;
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
for (i = 0U; i < USB_HOST_CONFIG_IP3516HS_MAX_ISO; i++)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[i].control1Union.controlState = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[i].control2Union.controlState = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[i].dataUnion.data = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[i].stateUnion.state = 0U;
}
usbHostState->usbRegBase->ISO_PTD_BASE_ADDRESS =
(((uint32_t)(&s_UsbHostIp3516HsPtd[usbHostState->controllerId].iso[0])) &
USB_HOST_IP3516HS_ISO_PTD_ISO_BASE_MASK);
usbHostState->usbRegBase->LAST_PTD_IN_USE |=
((USB_HOST_CONFIG_IP3516HS_MAX_ISO - 1UL) << USB_HOST_IP3516HS_LAST_PTD_IN_USE_ISO_LAST_SHIFT) &
USB_HOST_IP3516HS_LAST_PTD_IN_USE_ISO_LAST_MASK;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_ISO_EN_MASK;
interruptState |= USB_HOST_IP3516HS_USBINTR_ISO_IRQ_E_MASK;
#endif
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_INT) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
for (i = 0U; i < USB_HOST_CONFIG_IP3516HS_MAX_INT; i++)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].control1Union.controlState = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].control2Union.controlState = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].dataUnion.data = 0U;
s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[i].stateUnion.state = 0U;
}
usbHostState->usbRegBase->INT_PTD_BASE_ADDRESS =
(((uint32_t)(&s_UsbHostIp3516HsPtd[usbHostState->controllerId].interrupt[0])) &
USB_HOST_IP3516HS_INT_PTD_INT_BASE_MASK);
usbHostState->usbRegBase->LAST_PTD_IN_USE |=
(((uint32_t)USB_HOST_CONFIG_IP3516HS_MAX_INT - 1U) << USB_HOST_IP3516HS_LAST_PTD_IN_USE_INT_LAST_SHIFT) &
USB_HOST_IP3516HS_LAST_PTD_IN_USE_INT_LAST_MASK;
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_INT_EN_MASK;
interruptState |= USB_HOST_IP3516HS_USBINTR_INT_IRQ_E_MASK;
#endif
usbHostState->pipeListInUsing = NULL;
usbHostState->pipeList = &usbHostState->pipePool[0];
pipe = usbHostState->pipeList;
for (i = 1U; i < USB_HOST_CONFIG_IP3516HS_MAX_PIPE; i++)
{
temp = (void *)(&usbHostState->pipePool[i]);
pipe->pipeCommon.next = (usb_host_pipe_t *)temp;
temp = (void *)pipe->pipeCommon.next;
pipe = (usb_host_ip3516hs_pipe_struct_t *)temp;
}
pipe->pipeCommon.next = NULL;
/* Exit critical */
OSA_EXIT_CRITICAL();
if (0U != (usbHostState->usbRegBase->HCSPARAMS &
USB_HOST_IP3516HS_HCSPARAMS_PPC_MASK)) /* Ports have power port switches */
{
/* only has one port */
uint32_t tmp = usbHostState->usbRegBase->PORTSC1;
tmp &= (~USB_HOST_IP3516HS_PORTSC1_WIC);
usbHostState->usbRegBase->PORTSC1 = (tmp | USB_HOST_IP3516HS_PORTSC1_PP_MASK); /* turn on port power */
}
usbHostState->usbRegBase->DATA_PAYLOAD_BASE_ADDRESS =
(uint32_t)(&s_UsbHostIp3516HsBufferArray[0][0]) & USB_HOST_IP3516HS_DAT_BASE_MASK;
usbHostState->usbRegBase->USBSTS = 0xFFFFFFFFU;
usbHostState->usbRegBase->USBINTR =
interruptState | USB_HOST_IP3516HS_USBINTR_PCDE_MASK | USB_HOST_IP3516HS_USBINTR_SOF_E_MASK;
/* On RT600, there is no attach information when LS device is connected, the designer said it is due to the default
* turnaround time is too small, the 0x654 is their suggested value. */
#if (defined(FSL_FEATURE_USBHSH_HAS_TURNAROUND_TIMEOUT) && (FSL_FEATURE_USBHSH_HAS_TURNAROUND_TIMEOUT > 0U))
usbHostState->usbRegBase->PACKET_TURNAROUND_TIMEOUT &= ~USBHSH_PACKET_TURNAROUND_TIME_HOST_TIMEOUT_LS_MASK;
usbHostState->usbRegBase->PACKET_TURNAROUND_TIMEOUT |= 0x00000654;
#endif
usbHostState->usbRegBase->USBCMD |= USB_HOST_IP3516HS_USBCMD_RS_MASK;
return kStatus_USB_Success;
}
/*!
* @brief create the USB host ip3516hs instance.
*
* This function initializes the USB host ip3516hs controller driver.
*
* @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
* @param hostHandle The host level handle.
* @param controllerHandle Return the controller instance handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_AllocFail allocate memory fail.
* @retval kStatus_USB_Error host mutex create fail, IP3516HS mutex or IP3516HS event create fail.
* Or, IP3516HS IP initialize fail.
*/
usb_status_t USB_HostIp3516HsCreate(uint8_t controllerId,
usb_host_handle hostHandle,
usb_host_controller_handle *controllerHandle)
{
usb_host_ip3516hs_state_struct_t *usbHostState;
uint32_t usb_base_addrs[] = USBHSH_BASE_ADDRS;
IRQn_Type usb_irq[] = USBHSH_IRQS;
usb_status_t status = kStatus_USB_Success;
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
uint32_t hsdcd_base[] = USBHSDCD_BASE_ADDRS;
USBHSDCD_Type *base;
#endif
if (((controllerId - (uint8_t)kUSB_ControllerIp3516Hs0) >= (uint8_t)USB_HOST_CONFIG_IP3516HS)
#if (defined(USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 1U))
||
((controllerId - (uint8_t)kUSB_ControllerIp3516Hs0) >= (uint8_t)((sizeof(usb_base_addrs) / sizeof(uint32_t))))
#endif
)
{
return kStatus_USB_ControllerNotFound;
}
usbHostState = &s_UsbHostIp3516HsState[controllerId - (uint8_t)kUSB_ControllerIp3516Hs0];
/* Allocate the USB Host Pipe Descriptors */
usbHostState->hostHandle = hostHandle;
usbHostState->controllerId = controllerId - (uint8_t)kUSB_ControllerIp3516Hs0;
usbHostState->usbRegBase = (usb_host_ip3516hs_register_struct_t *)usb_base_addrs[usbHostState->controllerId];
usbHostState->isrNumber = (uint8_t)usb_irq[usbHostState->controllerId];
usbHostState->ip3516HsEvent = (osa_event_handle_t)&usbHostState->taskEventHandleBuffer[0];
if (KOSA_StatusSuccess != OSA_EventCreate(usbHostState->ip3516HsEvent, 1U))
{
#ifdef HOST_ECHO
usb_echo(" Event create failed in USB_HostIp3516HsCreate\n");
#endif
return kStatus_USB_AllocFail;
} /* Endif */
usbHostState->mutex = (osa_mutex_handle_t)(&usbHostState->mutexBuffer[0]);
if (KOSA_StatusSuccess != OSA_MutexCreate(usbHostState->mutex))
{
(void)USB_HostIp3516HsDestory(usbHostState);
#ifdef HOST_ECHO
usb_echo("USB_HostIp3516HsCreate: create host mutex fail\r\n");
#endif
return kStatus_USB_AllocFail;
}
usbHostState->portNumber =
(uint8_t)(usbHostState->usbRegBase->HCSPARAMS & USB_HOST_IP3516HS_HCSPARAMS_N_PORTS_MASK);
if (0U == usbHostState->portNumber)
{
#ifdef HOST_ECHO
usb_echo(" Port number is invalid in USB_HostIp3516HsCreate\n");
#endif
(void)USB_HostIp3516HsDestory(usbHostState);
return kStatus_USB_Error;
}
usbHostState->portState = (usb_host_ip3516hs_port_state_struct_t *)OSA_MemoryAllocate(
((uint32_t)sizeof(usb_host_ip3516hs_port_state_struct_t)) *
((uint32_t)usbHostState->portNumber)); /* malloc host ip3516hs port state */
if (NULL == usbHostState->portState)
{
#ifdef HOST_ECHO
usb_echo(" Mem alloc failed in USB_HostIp3516HsCreate\n");
#endif
(void)USB_HostIp3516HsDestory(usbHostState);
return kStatus_USB_Error;
}
(void)USB_HostIp3516HsControllerReset(usbHostState);
(void)USB_HostIp3516HsControllerInit(usbHostState);
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
base = (USBHSDCD_Type *)hsdcd_base[controllerId - kUSB_ControllerIp3516Hs0];
if (kStatus_hsdcd_Success != USB_HSDCD_Init(base, NULL, &usbHostState->dcdHandle))
{
(void)USB_HostIp3516HsDestory(usbHostState);
return kStatus_USB_Error;
}
usbHostState->chargerType = kUSB_DcdSDP;
#endif
*controllerHandle = (usb_host_handle)usbHostState;
return status;
}
/*!
* @brief destroy USB host ip3516hs instance.
*
* This function de-initialize the USB host ip3516hs controller driver.
*
* @param handle the controller handle.
*
* @retval kStatus_USB_Success The host is initialized successfully.
*/
usb_status_t USB_HostIp3516HsDestory(usb_host_controller_handle controllerHandle)
{
usb_host_ip3516hs_state_struct_t *usbHostState = (usb_host_ip3516hs_state_struct_t *)controllerHandle;
usbHostState->usbRegBase->USBINTR = 0U;
usbHostState->usbRegBase->USBSTS = 0xFFFFFFFFU;
usbHostState->usbRegBase->USBCMD &= ~USB_HOST_IP3516HS_USBCMD_RS_MASK;
if (NULL != usbHostState->portState)
{
(void)OSA_MemoryFree(usbHostState->portState);
usbHostState->portState = NULL;
}
if (NULL != usbHostState->mutex)
{
(void)OSA_MutexDestroy(usbHostState->mutex);
usbHostState->mutex = NULL;
}
if (NULL != usbHostState->ip3516HsEvent)
{
(void)OSA_EventDestroy(usbHostState->ip3516HsEvent);
usbHostState->ip3516HsEvent = NULL;
}
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
USB_HSDCD_Deinit(usbHostState->dcdHandle);
#endif
return kStatus_USB_Success;
}
usb_status_t USB_HostIp3516HsOpenPipe(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle *pipeHandle,
usb_host_pipe_init_t *pipeInit)
{
usb_host_ip3516hs_pipe_struct_t *pipe = NULL;
usb_host_ip3516hs_state_struct_t *usbHostState = (usb_host_ip3516hs_state_struct_t *)controllerHandle;
usb_status_t status;
status = USB_HostIp3516HsGetNewPipe(&usbHostState->pipeList, &pipe);
if ((kStatus_USB_Success != status) || (NULL == pipe))
{
#ifdef HOST_ECHO
usb_echo("ip3516hs open pipe failed\r\n");
#endif
return kStatus_USB_Busy;
}
/* initialize pipe informations */
pipe->pipeCommon.deviceHandle = pipeInit->devInstance;
pipe->pipeCommon.endpointAddress = pipeInit->endpointAddress;
pipe->pipeCommon.direction = pipeInit->direction;
pipe->pipeCommon.interval = pipeInit->interval;
pipe->pipeCommon.maxPacketSize = pipeInit->maxPacketSize;
pipe->pipeCommon.pipeType = pipeInit->pipeType;
pipe->pipeCommon.numberPerUframe = (pipeInit->numberPerUframe + 1U) & 0x03U;
pipe->pipeCommon.nakCount = pipeInit->nakCount;
pipe->pipeCommon.nextdata01 = 0U;
pipe->pipeCommon.currentCount = 0U;
pipe->pipeCommon.open = 1U;
pipe->tdIndex = 0xFFU;
pipe->cutOffTime = USB_HOST_IP3516HS_TRANSFER_TIMEOUT_GAP;
pipe->startUFrame = 0U;
pipe->csSlot = 0U;
pipe->isBusy = 0U;
pipe->bufferLength = 0U;
pipe->currentTr = NULL;
pipe->lastPrimedIndex = 0U;
if (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType)
{
#if 1U
if (0U == pipe->pipeCommon.interval)
{
pipe->pipeCommon.interval = 1U;
}
pipe->pipeCommon.interval =
(uint16_t)(1UL << (pipe->pipeCommon.interval - 1U)); /* iso interval is the power of 2 */
#else
pipe->pipeCommon.interval = 1U;
#endif
}
else if (USB_ENDPOINT_INTERRUPT == pipe->pipeCommon.pipeType)
{
if (USB_SPEED_HIGH != ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed)
{
uint32_t interval = 0U;
/* FS/LS interrupt interval should be the power of 2, it is used for ip3516hs bandwidth */
for (uint32_t p = 0U; p < 16U; p++)
{
if (0U != (pipe->pipeCommon.interval & ((uint16_t)(1UL << p))))
{
if (p > interval)
{
interval = p;
}
}
}
pipe->pipeCommon.interval = (uint16_t)(1UL << interval);
}
else
{
pipe->pipeCommon.interval = ((uint16_t)(
1UL << ((uint32_t)pipe->pipeCommon.interval - 1UL))); /* HS interrupt interval is the power of 2 */
}
}
else
{
pipe->pipeCommon.interval = 0U;
}
if (USB_SPEED_HIGH != ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed)
{
pipe->pipeCommon.interval = pipe->pipeCommon.interval << 3;
}
if (((uint16_t)USB_HOST_IP3516HS_MAX_FRAME) < pipe->pipeCommon.interval)
{
pipe->pipeCommon.interval = (uint16_t)USB_HOST_IP3516HS_MAX_FRAME;
}
/* open pipe */
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_CONTROL:
case USB_ENDPOINT_BULK:
status = USB_HostIp3516HsOpenControlBulkPipe(usbHostState, pipe);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
status = USB_HostIp3516HsOpenIsoPipe(usbHostState, pipe);
break;
#endif
#if (defined(USB_HOST_CONFIG_IP3516HS_MAX_INT) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
status = USB_HostIp3516HsOpenInterruptPipe(usbHostState, pipe);
break;
#endif
default:
status = kStatus_USB_Error;
break;
}
if (status != kStatus_USB_Success)
{
pipe->pipeCommon.open = 0U;
/* release the pipe */
(void)USB_HostIp3516HsInsertPipe(&usbHostState->pipeList, pipe);
return status;
}
(void)USB_HostIp3516HsInsertPipe(&usbHostState->pipeListInUsing, pipe);
*pipeHandle = pipe;
return status;
}
usb_status_t USB_HostIp3516HsClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
{
usb_host_ip3516hs_state_struct_t *usbHostState = (usb_host_ip3516hs_state_struct_t *)controllerHandle;
usb_host_ip3516hs_pipe_struct_t *pipe = (usb_host_ip3516hs_pipe_struct_t *)pipeHandle;
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
case USB_ENDPOINT_CONTROL:
(void)USB_HostIp3516HsCloseControlBulkPipe(usbHostState, pipe);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
(void)USB_HostIp3516HsCloseIsoPipe(usbHostState, pipe);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
(void)USB_HostIp3516HsCloseInterruptPipe(usbHostState, pipe);
break;
#endif
default:
/*no action*/
break;
}
(void)USB_HostIp3516HsRemovePipe(&usbHostState->pipeListInUsing, pipe);
pipe->pipeCommon.open = 0U;
(void)USB_HostIp3516HsInsertPipe(&usbHostState->pipeList, pipe);
return kStatus_USB_Success;
}
usb_status_t USB_HostIp3516HsWritePipe(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer)
{
usb_host_ip3516hs_state_struct_t *usbHostState = (usb_host_ip3516hs_state_struct_t *)controllerHandle;
usb_host_ip3516hs_pipe_struct_t *pipe = (usb_host_ip3516hs_pipe_struct_t *)pipeHandle;
usb_host_transfer_t *trPre;
usb_status_t status = kStatus_USB_Success;
uint8_t trListEmpty = 0U;
OSA_SR_ALLOC();
transfer->setupStatus = (uint8_t)kStatus_UsbHostIp3516Hs_Idle;
transfer->next = NULL;
transfer->transferSofar = 0U;
transfer->union1.transferResult = (int32_t)kStatus_USB_Success;
OSA_ENTER_CRITICAL();
if (NULL == pipe->trList)
{
pipe->trList = transfer;
pipe->currentTr = transfer;
trListEmpty = 1U;
}
else
{
trPre = pipe->trList;
while (NULL != trPre->next)
{
trPre = trPre->next;
}
trPre->next = transfer;
}
OSA_EXIT_CRITICAL();
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
if ((0U != trListEmpty) || (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType))
#else
if ((0U != trListEmpty))
#endif
{
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
status = USB_HostIp3516HsWriteBulkPipe(usbHostState, pipe, transfer);
break;
case USB_ENDPOINT_CONTROL:
status = USB_HostIp3516HsWriteControlPipe(usbHostState, pipe, transfer);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
status = USB_HostIp3516HsWriteIsoPipe(usbHostState, pipe, pipe->trList);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
status = USB_HostIp3516HsWriteInterruptPipe(usbHostState, pipe, transfer);
break;
#endif
default:
/*no action*/
break;
}
}
return status;
}
usb_status_t USB_HostIp3516HsReadPipe(usb_host_controller_handle controllerHandle,
usb_host_pipe_handle pipeHandle,
usb_host_transfer_t *transfer)
{
return USB_HostIp3516HsWritePipe(controllerHandle, pipeHandle, transfer);
}
usb_status_t USB_HostIp3516HsIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
{
usb_host_ip3516hs_state_struct_t *usbHostState = (usb_host_ip3516hs_state_struct_t *)controllerHandle;
usb_host_cancel_param_t *param;
usb_host_ip3516hs_pipe_struct_t *pipe;
uint32_t deviceAddress;
usb_host_controller_control_t ioctl;
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
uint8_t *lpmParam;
#endif
#endif
deviceAddress = 0U;
usb_status_t status = kStatus_USB_Success;
if (controllerHandle == NULL)
{
return kStatus_USB_InvalidHandle;
}
ioctl = (usb_host_controller_control_t)ioctlEvent;
switch (ioctl)
{
case kUSB_HostCancelTransfer:
/* cancel pipe or one transfer */
param = (usb_host_cancel_param_t *)ioctlParam;
status = USB_HostIp3516HsCancelPipe(usbHostState, (usb_host_ip3516hs_pipe_struct_t *)param->pipeHandle,
param->transfer);
break;
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
case kUSB_HostL1Config:
lpmParam = (uint8_t *)ioctlParam;
usbHostState->hirdValue = (*lpmParam) & 0xFU;
usbHostState->L1remoteWakeupEnable = (((*lpmParam) & 0x80U) >> 7);
break;
#endif
#endif
case kUSB_HostBusControl:
/* bus control */
status = USB_HostIp3516HsControlBus(usbHostState, *((uint8_t *)ioctlParam));
break;
case kUSB_HostGetFrameNumber:
/* get frame number */
*((uint32_t *)ioctlParam) =
(uint32_t)((usbHostState->usbRegBase->FLADJ_FRINDEX & USB_HOST_IP3516HS_FLADJ_FRINDEX_MASK) >>
USB_HOST_IP3516HS_FLADJ_FRINDEX_SHIFT);
break;
case kUSB_HostUpdateControlEndpointAddress:
pipe = (usb_host_ip3516hs_pipe_struct_t *)ioctlParam;
/* update address */
(void)USB_HostHelperGetPeripheralInformation(pipe->pipeCommon.deviceHandle,
(uint32_t)kUSB_HostGetDeviceAddress, &deviceAddress);
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
case USB_ENDPOINT_CONTROL:
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.control2Union.stateBitField.DeviceAddress = deviceAddress;
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
usbHostState->usbRegBase->INT_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.control2Union.stateBitField.DeviceAddress = deviceAddress;
usbHostState->usbRegBase->INT_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
usbHostState->usbRegBase->ISO_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[pipe->tdIndex]
.control2Union.stateBitField.DeviceAddress = deviceAddress;
usbHostState->usbRegBase->ISO_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#endif
default:
/*no action*/
break;
}
(void)USB_HostIp3516HsDelay(usbHostState, 16U);
break;
case kUSB_HostUpdateControlPacketSize:
pipe = (usb_host_ip3516hs_pipe_struct_t *)ioctlParam;
switch (pipe->pipeCommon.pipeType)
{
case USB_ENDPOINT_BULK:
case USB_ENDPOINT_CONTROL:
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.atl[pipe->tdIndex]
.control1Union.stateBitField.MaxPacketLength = pipe->pipeCommon.maxPacketSize;
usbHostState->usbRegBase->ATL_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
case USB_ENDPOINT_INTERRUPT:
usbHostState->usbRegBase->INT_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.interrupt[pipe->tdIndex]
.control1Union.stateBitField.MaxPacketLength = pipe->pipeCommon.maxPacketSize;
usbHostState->usbRegBase->INT_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#endif
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
case USB_ENDPOINT_ISOCHRONOUS:
usbHostState->usbRegBase->ISO_PTD_SKIP_MAP |= 1UL << pipe->tdIndex;
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[pipe->tdIndex]
.control1Union.stateBitField.MaxPacketLength = pipe->pipeCommon.maxPacketSize;
if (0U != s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[pipe->tdIndex]
.control2Union.stateBitField.S)
{
s_UsbHostIp3516HsPtd[usbHostState->controllerId]
.iso[pipe->tdIndex]
.control1Union.stateBitField.MaxPacketLength++;
}
usbHostState->usbRegBase->ISO_PTD_SKIP_MAP &= ~(1UL << pipe->tdIndex);
break;
#endif
default:
/*no action*/
break;
}
break;
case kUSB_HostPortAttachDisable:
break;
case kUSB_HostPortAttachEnable:
if ((*(uint8_t *)ioctlParam) < usbHostState->portNumber)
{
usbHostState->portState[*(uint8_t *)ioctlParam].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortDetached;
}
break;
#if (defined(USB_HOST_CONFIG_BATTERY_CHARGER) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U)) && \
(defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))
case kUSB_HostSetChargerType:
usbHostState->chargerType = *((uint8_t *)ioctlParam);
if ((usbHostState->portState[0].portStatus == kUSB_DeviceIp3516HsPortPhyDetached) ||
(usbHostState->portState[0].portStatus == kUSB_DeviceIp3516HsPortDetached))
{
USB_HSDCD_Control(usbHostState->dcdHandle, kUSB_HostHSDcdSetType, &(usbHostState->chargerType));
}
break;
#endif
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
case kUSB_HostTestModeInit: /* test mode control */
USB_HostIp3516HsTestModeInit((usb_host_device_instance_t *)ioctlParam);
break;
#endif
default:
status = kStatus_USB_NotSupported;
break;
}
return status;
}
void USB_HostIp3516HsTaskFunction(void *hostHandle)
{
usb_host_ip3516hs_state_struct_t *usbHostState;
uint32_t bitSet;
if (NULL == hostHandle)
{
return;
}
usbHostState = (usb_host_ip3516hs_state_struct_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
/* wait all event */
if (KOSA_StatusSuccess == OSA_EventWait(usbHostState->ip3516HsEvent, 0xFFU, 0, USB_OSA_WAIT_TIMEOUT, &bitSet))
{
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_PORT_CHANGE))
{
(void)USB_HostIp3516HsPortChange(usbHostState);
}
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_ISO_TOKEN_DONE))
{
(void)USB_HostIp3516HsTokenDone(usbHostState);
}
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_INT_TOKEN_DONE))
{
(void)USB_HostIp3516HsTokenDone(usbHostState);
}
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_ATL_TOKEN_DONE))
{
(void)USB_HostIp3516HsTokenDone(usbHostState);
}
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_SOF))
{
(void)USB_HostIp3516HsSof(usbHostState);
}
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_ATTACH))
{
for (uint8_t i = 0; i < usbHostState->portNumber; i++)
{
if ((uint8_t)kUSB_DeviceIp3516HsPortPhyAttached == usbHostState->portState[i].portStatus)
{
void *deviceHandle;
if (kStatus_USB_Success == USB_HostAttachDevice(usbHostState->hostHandle,
usbHostState->portState[i].portSpeed, 0U, i, 1U,
&deviceHandle))
{
usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceIp3516HsPortAttached;
}
}
}
}
if (0U != (bitSet & USB_HOST_IP3516HS_EVENT_DETACH))
{
for (uint8_t i = 0; i < usbHostState->portNumber; i++)
{
if ((uint8_t)kUSB_DeviceIp3516HsPortPhyDetached == usbHostState->portState[i].portStatus)
{
(void)USB_HostDetachDevice(usbHostState->hostHandle, 0U, i);
}
}
}
}
}
void USB_HostIp3516HsIsrFunction(void *hostHandle)
{
usb_host_ip3516hs_state_struct_t *usbHostState;
static uint32_t interruptStatus = 0U;
static uint32_t sofCount = 0U;
if (hostHandle == NULL)
{
return;
}
usbHostState = (usb_host_ip3516hs_state_struct_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
interruptStatus = usbHostState->usbRegBase->USBSTS;
interruptStatus &= usbHostState->usbRegBase->USBINTR;
if (0U != (interruptStatus & USB_HOST_IP3516HS_USBSTS_ISO_IRQ_MASK)) /* Write back done head */
{
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_ISO)) && (USB_HOST_CONFIG_IP3516HS_MAX_ISO > 0U))
(void)USB_HostIp3516HsCheckIsoTransferSofar(usbHostState);
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_ISO_TOKEN_DONE);
#endif
}
if (0U != (interruptStatus & USB_HOST_IP3516HS_USBSTS_INT_IRQ_MASK)) /* Write back done head */
{
#if ((defined(USB_HOST_CONFIG_IP3516HS_MAX_INT)) && (USB_HOST_CONFIG_IP3516HS_MAX_INT > 0U))
(void)USB_HostIp3516HsCheckIntTransferSofar(usbHostState);
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_INT_TOKEN_DONE);
#endif
}
if (0U != (interruptStatus & USB_HOST_IP3516HS_USBSTS_ATL_IRQ_MASK)) /* Write back done head */
{
(void)USB_HostIp3516HsCheckAtlTransferSofar(usbHostState);
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_ATL_TOKEN_DONE);
}
if (0U != (interruptStatus & USB_HOST_IP3516HS_USBSTS_SOF_IRQ_MASK)) /* SOF interrupt */
{
if (USB_SPEED_HIGH == usbHostState->portState->portSpeed)
{
sofCount++;
}
else
{
sofCount += 8U;
}
if (sofCount >= USB_HOST_IP3516HS_TRANSFER_SCAN_INTERVAL)
{
sofCount = 0U;
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_SOF);
}
}
if (0U != (interruptStatus & USB_HOST_IP3516HS_USBINTR_PCDE_MASK)) /* port change detect interrupt */
{
(void)OSA_EventSet(usbHostState->ip3516HsEvent, USB_HOST_IP3516HS_EVENT_PORT_CHANGE);
}
usbHostState->usbRegBase->USBSTS = interruptStatus; /* clear interrupt */
}
#endif