mirror of
https://github.com/azure-rtos/usbx.git
synced 2025-01-14 06:43:05 +08:00
Add stm32 device and host controllers
This commit is contained in:
parent
203d166f0b
commit
88240ba10e
188
common/usbx_stm32_device_controllers/ux_dcd_stm32.h
Normal file
188
common/usbx_stm32_device_controllers/ux_dcd_stm32.h
Normal file
@ -0,0 +1,188 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* ux_dcd_stm32.h PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the USB OTG device equivalences for the STM32 */
|
||||
/* controller. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* added bi-dir EP support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef UX_DCD_STM32_H
|
||||
#define UX_DCD_STM32_H
|
||||
|
||||
#include "ux_stm32_config.h"
|
||||
|
||||
/* Define STM32 generic equivalences. */
|
||||
|
||||
#define UX_DCD_STM32_SLAVE_CONTROLLER 0x80
|
||||
#ifndef UX_DCD_STM32_MAX_ED
|
||||
#define UX_DCD_STM32_MAX_ED 4
|
||||
#endif /* UX_DCD_STM32_MAX_ED */
|
||||
#define UX_DCD_STM32_IN_FIFO 3
|
||||
|
||||
|
||||
#define UX_DCD_STM32_FLUSH_RX_FIFO 0x00000010
|
||||
#define UX_DCD_STM32_FLUSH_TX_FIFO 0x00000020
|
||||
#define UX_DCD_STM32_FLUSH_FIFO_ALL 0x00000010
|
||||
#define UX_DCD_STM32_ENDPOINT_SPACE_SIZE 0x00000020
|
||||
#define UX_DCD_STM32_ENDPOINT_CHANNEL_SIZE 0x00000020
|
||||
|
||||
|
||||
/* Define USB STM32 physical endpoint status definition. */
|
||||
|
||||
#define UX_DCD_STM32_ED_STATUS_UNUSED 0u
|
||||
#define UX_DCD_STM32_ED_STATUS_USED 1u
|
||||
#define UX_DCD_STM32_ED_STATUS_TRANSFER 2u
|
||||
#define UX_DCD_STM32_ED_STATUS_STALLED 4u
|
||||
#define UX_DCD_STM32_ED_STATUS_DONE 8u
|
||||
#define UX_DCD_STM32_ED_STATUS_SETUP_IN (1u<<8)
|
||||
#define UX_DCD_STM32_ED_STATUS_SETUP_STATUS (2u<<8)
|
||||
#define UX_DCD_STM32_ED_STATUS_SETUP_OUT (3u<<8)
|
||||
#define UX_DCD_STM32_ED_STATUS_SETUP (3u<<8)
|
||||
#define UX_DCD_STM32_ED_STATUS_TASK_PENDING (1u<<10)
|
||||
|
||||
/* Define USB STM32 physical endpoint state machine definition. */
|
||||
|
||||
#define UX_DCD_STM32_ED_STATE_IDLE 0
|
||||
#define UX_DCD_STM32_ED_STATE_DATA_TX 1
|
||||
#define UX_DCD_STM32_ED_STATE_DATA_RX 2
|
||||
#define UX_DCD_STM32_ED_STATE_STATUS_TX 3
|
||||
#define UX_DCD_STM32_ED_STATE_STATUS_RX 4
|
||||
|
||||
/* Define USB STM32 device callback notification state definition. */
|
||||
|
||||
#define UX_DCD_STM32_SOF_RECEIVED 0xF0U
|
||||
#define UX_DCD_STM32_DEVICE_CONNECTED 0xF1U
|
||||
#define UX_DCD_STM32_DEVICE_DISCONNECTED 0xF2U
|
||||
#define UX_DCD_STM32_DEVICE_RESUMED 0xF3U
|
||||
#define UX_DCD_STM32_DEVICE_SUSPENDED 0xF4U
|
||||
|
||||
/* Define USB STM32 endpoint transfer status definition. */
|
||||
|
||||
#define UX_DCD_STM32_ED_TRANSFER_STATUS_IDLE 0
|
||||
#define UX_DCD_STM32_ED_TRANSFER_STATUS_SETUP 1
|
||||
#define UX_DCD_STM32_ED_TRANSFER_STATUS_IN_COMPLETION 2
|
||||
#define UX_DCD_STM32_ED_TRANSFER_STATUS_OUT_COMPLETION 3
|
||||
|
||||
/* Define USB STM32 physical endpoint structure. */
|
||||
|
||||
typedef struct UX_DCD_STM32_ED_STRUCT
|
||||
{
|
||||
struct UX_SLAVE_ENDPOINT_STRUCT
|
||||
*ux_dcd_stm32_ed_endpoint;
|
||||
ULONG ux_dcd_stm32_ed_status;
|
||||
UCHAR ux_dcd_stm32_ed_state;
|
||||
UCHAR ux_dcd_stm32_ed_index;
|
||||
UCHAR ux_dcd_stm32_ed_direction;
|
||||
UCHAR reserved;
|
||||
} UX_DCD_STM32_ED;
|
||||
|
||||
|
||||
/* Define USB STM32 DCD structure definition. */
|
||||
|
||||
typedef struct UX_DCD_STM32_STRUCT
|
||||
{
|
||||
|
||||
struct UX_SLAVE_DCD_STRUCT
|
||||
*ux_dcd_stm32_dcd_owner;
|
||||
struct UX_DCD_STM32_ED_STRUCT
|
||||
ux_dcd_stm32_ed[UX_DCD_STM32_MAX_ED];
|
||||
#if defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT)
|
||||
struct UX_DCD_STM32_ED_STRUCT
|
||||
ux_dcd_stm32_ed_in[UX_DCD_STM32_MAX_ED];
|
||||
#endif /* defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT) */
|
||||
PCD_HandleTypeDef *pcd_handle;
|
||||
} UX_DCD_STM32;
|
||||
|
||||
static inline struct UX_DCD_STM32_ED_STRUCT *_stm32_ed_get(UX_DCD_STM32 *dcd_stm32, ULONG ep_addr)
|
||||
{
|
||||
#if defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT)
|
||||
ULONG ep_dir = ep_addr & 0x80u;
|
||||
#endif /* defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT) */
|
||||
ULONG ep_num = ep_addr & 0x7Fu;
|
||||
|
||||
if (ep_num >= UX_DCD_STM32_MAX_ED ||
|
||||
ep_num >= dcd_stm32->pcd_handle->Init.dev_endpoints)
|
||||
return(UX_NULL);
|
||||
|
||||
#if defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT)
|
||||
if (ep_dir)
|
||||
return(&dcd_stm32->ux_dcd_stm32_ed_in[ep_num]);
|
||||
#endif /* defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT) */
|
||||
|
||||
return(&dcd_stm32->ux_dcd_stm32_ed[ep_num]);
|
||||
}
|
||||
|
||||
|
||||
/* Define USB STM32 DCD prototypes. */
|
||||
|
||||
UINT _ux_dcd_stm32_endpoint_create(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
|
||||
UINT _ux_dcd_stm32_endpoint_destroy(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
|
||||
UINT _ux_dcd_stm32_endpoint_reset(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
|
||||
UINT _ux_dcd_stm32_endpoint_stall(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint);
|
||||
UINT _ux_dcd_stm32_endpoint_status(UX_DCD_STM32 *dcd_stm32, ULONG endpoint_index);
|
||||
UINT _ux_dcd_stm32_frame_number_get(UX_DCD_STM32 *dcd_stm32, ULONG *frame_number);
|
||||
UINT _ux_dcd_stm32_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter);
|
||||
UINT _ux_dcd_stm32_initialize_complete(VOID);
|
||||
VOID _ux_dcd_stm32_interrupt_handler(VOID);
|
||||
UINT _ux_dcd_stm32_transfer_abort(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request);
|
||||
|
||||
#if !defined(UX_DEVICE_STANDALONE)
|
||||
UINT _ux_dcd_stm32_transfer_request(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request);
|
||||
#else
|
||||
UINT _ux_dcd_stm32_transfer_run(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request);
|
||||
VOID _ux_dcd_stm32_setup_isr_pending(UX_DCD_STM32 *dcd_stm32);
|
||||
#endif /* !defined(UX_DEVICE_STANDALONE) */
|
||||
|
||||
UINT _ux_dcd_stm32_initialize(ULONG dcd_io, ULONG parameter);
|
||||
UINT _ux_dcd_stm32_uninitialize(ULONG dcd_io, ULONG parameter);
|
||||
|
||||
|
||||
#define ux_dcd_stm32_initialize _ux_dcd_stm32_initialize
|
||||
#define ux_dcd_stm32_uninitialize _ux_dcd_stm32_uninitialize
|
||||
#define ux_dcd_stm32_interrupt_handler _ux_dcd_stm32_interrupt_handler
|
||||
|
||||
#endif /* UX_DCD_STM32_H */
|
||||
|
1195
common/usbx_stm32_device_controllers/ux_dcd_stm32_callback.c
Normal file
1195
common/usbx_stm32_device_controllers/ux_dcd_stm32_callback.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,126 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_endpoint_create PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will create a physical endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* endpoint Pointer to endpoint container */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_Open Open endpoint */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_endpoint_create(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
UX_DCD_STM32_ED *ed;
|
||||
ULONG stm32_endpoint_index;
|
||||
|
||||
|
||||
/* The endpoint index in the array of the STM32 must match the endpoint number. */
|
||||
stm32_endpoint_index = endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & ~UX_ENDPOINT_DIRECTION;
|
||||
|
||||
/* Get STM32 ED. */
|
||||
ed = _stm32_ed_get(dcd_stm32, endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress);
|
||||
|
||||
if (ed == UX_NULL)
|
||||
return(UX_NO_ED_AVAILABLE);
|
||||
|
||||
/* Check the endpoint status, if it is free, reserve it. If not reject this endpoint. */
|
||||
if ((ed -> ux_dcd_stm32_ed_status & UX_DCD_STM32_ED_STATUS_USED) == 0)
|
||||
{
|
||||
|
||||
/* We can use this endpoint. */
|
||||
ed -> ux_dcd_stm32_ed_status |= UX_DCD_STM32_ED_STATUS_USED;
|
||||
|
||||
/* Keep the physical endpoint address in the endpoint container. */
|
||||
endpoint -> ux_slave_endpoint_ed = (VOID *) ed;
|
||||
|
||||
/* Save the endpoint pointer. */
|
||||
ed -> ux_dcd_stm32_ed_endpoint = endpoint;
|
||||
|
||||
/* And its index. */
|
||||
ed -> ux_dcd_stm32_ed_index = stm32_endpoint_index;
|
||||
|
||||
/* And its direction. */
|
||||
ed -> ux_dcd_stm32_ed_direction = endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION;
|
||||
|
||||
/* Check if it is non-control endpoint. */
|
||||
if (stm32_endpoint_index != 0)
|
||||
{
|
||||
|
||||
/* Open the endpoint. */
|
||||
HAL_PCD_EP_Open(dcd_stm32 -> pcd_handle, endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress,
|
||||
endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize,
|
||||
endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE);
|
||||
}
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
/* Return an error. */
|
||||
return(UX_NO_ED_AVAILABLE);
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_endpoint_destroy PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will destroy a physical endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* endpoint Pointer to endpoint container */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_Close Deactivate endpoint */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_endpoint_destroy(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
UX_DCD_STM32_ED *ed;
|
||||
|
||||
|
||||
/* Keep the physical endpoint address in the endpoint container. */
|
||||
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
|
||||
|
||||
/* We can free this endpoint. */
|
||||
ed -> ux_dcd_stm32_ed_status = UX_DCD_STM32_ED_STATUS_UNUSED;
|
||||
|
||||
/* Deactivate the endpoint. */
|
||||
HAL_PCD_EP_Close(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress);
|
||||
|
||||
/* This function never fails. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,114 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_endpoint_reset PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will reset a physical endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* endpoint Pointer to endpoint container */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_ClrStall Clear STALL */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_endpoint_reset(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
UX_DCD_STM32_ED *ed;
|
||||
|
||||
|
||||
/* Get the physical endpoint address in the endpoint container. */
|
||||
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
|
||||
|
||||
UX_DISABLE
|
||||
|
||||
/* Set the status of the endpoint to not stalled. */
|
||||
ed -> ux_dcd_stm32_ed_status &= ~(UX_DCD_STM32_ED_STATUS_STALLED |
|
||||
UX_DCD_STM32_ED_STATUS_DONE |
|
||||
UX_DCD_STM32_ED_STATUS_SETUP);
|
||||
|
||||
/* Set the state of the endpoint to IDLE. */
|
||||
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_IDLE;
|
||||
|
||||
/* Clear STALL condition. */
|
||||
HAL_PCD_EP_ClrStall(dcd_stm32 -> pcd_handle, endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress);
|
||||
|
||||
/* Flush buffer. */
|
||||
HAL_PCD_EP_Flush(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress);
|
||||
|
||||
#ifndef UX_DEVICE_STANDALONE
|
||||
|
||||
/* Wakeup pending thread. */
|
||||
if (endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore.tx_semaphore_suspended_count)
|
||||
_ux_utility_semaphore_put(&endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore);
|
||||
#endif
|
||||
|
||||
UX_RESTORE
|
||||
|
||||
/* This function never fails. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_endpoint_stall PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will stall a physical endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* endpoint Pointer to endpoint container */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_SetStall Set STALL condition */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_endpoint_stall(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
UX_DCD_STM32_ED *ed;
|
||||
|
||||
|
||||
/* Get the physical endpoint address in the endpoint container. */
|
||||
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
|
||||
|
||||
/* Set the endpoint to stall. */
|
||||
ed -> ux_dcd_stm32_ed_status |= UX_DCD_STM32_ED_STATUS_STALLED;
|
||||
|
||||
/* Stall the endpoint. */
|
||||
HAL_PCD_EP_SetStall(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress | ed -> ux_dcd_stm32_ed_direction);
|
||||
|
||||
/* This function never fails. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_endpoint_status PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will retrieve the status of the endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* endpoint_index Endpoint index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added bi-dir EP support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_endpoint_status(UX_DCD_STM32 *dcd_stm32, ULONG endpoint_index)
|
||||
{
|
||||
|
||||
UX_DCD_STM32_ED *ed;
|
||||
|
||||
|
||||
/* Fetch the address of the physical endpoint. */
|
||||
ed = _stm32_ed_get(dcd_stm32, endpoint_index);
|
||||
|
||||
/* Check the endpoint status, if it is free, we have a illegal endpoint. */
|
||||
if ((ed -> ux_dcd_stm32_ed_status & UX_DCD_STM32_ED_STATUS_USED) == 0)
|
||||
return(UX_ERROR);
|
||||
|
||||
/* Check if the endpoint is stalled. */
|
||||
if ((ed -> ux_dcd_stm32_ed_status & UX_DCD_STM32_ED_STATUS_STALLED) == 0)
|
||||
return(UX_FALSE);
|
||||
else
|
||||
return(UX_TRUE);
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_frame_number_get PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will return the frame number currently used by the */
|
||||
/* controller. This function is mostly used for isochronous purposes. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* frame_number Destination for frame number */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_register_read Read register */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_frame_number_get(UX_DCD_STM32 *dcd_stm32, ULONG *frame_number)
|
||||
{
|
||||
|
||||
/* This function never fails. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
201
common/usbx_stm32_device_controllers/ux_dcd_stm32_function.c
Normal file
201
common/usbx_stm32_device_controllers/ux_dcd_stm32_function.c
Normal file
@ -0,0 +1,201 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
extern VOID _ux_dcd_stm32_setup_isr_pending(UX_DCD_STM32 *);
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_function PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function dispatches the DCD function internally to the STM32 */
|
||||
/* controller. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd Pointer to device controller */
|
||||
/* function Function requested */
|
||||
/* parameter Pointer to function parameters*/
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_endpoint_create Create endpoint */
|
||||
/* _ux_dcd_stm32_endpoint_destroy Destroy endpoint */
|
||||
/* _ux_dcd_stm32_endpoint_reset Reset endpoint */
|
||||
/* _ux_dcd_stm32_endpoint_stall Stall endpoint */
|
||||
/* _ux_dcd_stm32_endpoint_status Get endpoint status */
|
||||
/* _ux_dcd_stm32_frame_number_get Get frame number */
|
||||
/* _ux_dcd_stm32_transfer_request Request data transfer */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* USBX Device Stack */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_DCD_STM32 *dcd_stm32;
|
||||
|
||||
|
||||
/* Check the status of the controller. */
|
||||
if (dcd -> ux_slave_dcd_status == UX_UNUSED)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_CONTROLLER_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONTROLLER_UNKNOWN, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_CONTROLLER_UNKNOWN);
|
||||
}
|
||||
|
||||
/* Get the pointer to the STM32 DCD. */
|
||||
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
|
||||
|
||||
/* Look at the function and route it. */
|
||||
switch(function)
|
||||
{
|
||||
|
||||
case UX_DCD_GET_FRAME_NUMBER:
|
||||
|
||||
status = _ux_dcd_stm32_frame_number_get(dcd_stm32, (ULONG *) parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_TRANSFER_REQUEST:
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
status = _ux_dcd_stm32_transfer_run(dcd_stm32, (UX_SLAVE_TRANSFER *) parameter);
|
||||
#else
|
||||
status = _ux_dcd_stm32_transfer_request(dcd_stm32, (UX_SLAVE_TRANSFER *) parameter);
|
||||
#endif /* defined(UX_DEVICE_STANDALONE) */
|
||||
break;
|
||||
|
||||
case UX_DCD_TRANSFER_ABORT:
|
||||
status = _ux_dcd_stm32_transfer_abort(dcd_stm32, parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_CREATE_ENDPOINT:
|
||||
|
||||
status = _ux_dcd_stm32_endpoint_create(dcd_stm32, parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_DESTROY_ENDPOINT:
|
||||
|
||||
status = _ux_dcd_stm32_endpoint_destroy(dcd_stm32, parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_RESET_ENDPOINT:
|
||||
|
||||
status = _ux_dcd_stm32_endpoint_reset(dcd_stm32, parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_STALL_ENDPOINT:
|
||||
|
||||
status = _ux_dcd_stm32_endpoint_stall(dcd_stm32, parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_SET_DEVICE_ADDRESS:
|
||||
|
||||
status = HAL_PCD_SetAddress(dcd_stm32 -> pcd_handle, (uint8_t)(ULONG) parameter);
|
||||
break;
|
||||
|
||||
case UX_DCD_CHANGE_STATE:
|
||||
|
||||
if ((ULONG) parameter == UX_DEVICE_FORCE_DISCONNECT)
|
||||
{
|
||||
/* Disconnect the USB device */
|
||||
status = HAL_PCD_Stop(dcd_stm32 -> pcd_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = UX_SUCCESS;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UX_DCD_ENDPOINT_STATUS:
|
||||
|
||||
status = _ux_dcd_stm32_endpoint_status(dcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
case UX_DCD_ISR_PENDING:
|
||||
|
||||
_ux_dcd_stm32_setup_isr_pending(dcd_stm32);
|
||||
status = UX_SUCCESS;
|
||||
break;
|
||||
#endif /* defined(UX_DEVICE_STANDALONE) */
|
||||
|
||||
default:
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_FUNCTION_NOT_SUPPORTED);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
status = UX_FUNCTION_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
120
common/usbx_stm32_device_controllers/ux_dcd_stm32_initialize.c
Normal file
120
common/usbx_stm32_device_controllers/ux_dcd_stm32_initialize.c
Normal file
@ -0,0 +1,120 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_initialize PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function initializes the USB device controller of the STM32 */
|
||||
/* microcontroller from ST. */
|
||||
/* */
|
||||
/* Note: only software structures that are necessary for STM32 HAL to */
|
||||
/* work is initialized, STM32 HAL APIs should be used to initialize */
|
||||
/* controller hardware AFTER the function is invoked. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_io Address of DCD, not used */
|
||||
/* parameter Parameter, STM32 HAL PCD */
|
||||
/* pointer is expected */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_Init Initialize LL driver */
|
||||
/* _ux_utility_memory_allocate Allocate memory */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* USBX Device Stack */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_initialize(ULONG dcd_io, ULONG parameter)
|
||||
{
|
||||
|
||||
UX_SLAVE_DCD *dcd;
|
||||
UX_DCD_STM32 *dcd_stm32;
|
||||
|
||||
|
||||
UX_PARAMETER_NOT_USED(dcd_io);
|
||||
|
||||
/* Get the pointer to the DCD. */
|
||||
dcd = &_ux_system_slave -> ux_system_slave_dcd;
|
||||
|
||||
/* The controller initialized here is of STM32 type. */
|
||||
dcd -> ux_slave_dcd_controller_type = UX_DCD_STM32_SLAVE_CONTROLLER;
|
||||
|
||||
/* Allocate memory for this STM32 DCD instance. */
|
||||
dcd_stm32 = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_DCD_STM32));
|
||||
|
||||
/* Check if memory was properly allocated. */
|
||||
if(dcd_stm32 == UX_NULL)
|
||||
return(UX_MEMORY_INSUFFICIENT);
|
||||
|
||||
/* Set the pointer to the STM32 DCD. */
|
||||
dcd -> ux_slave_dcd_controller_hardware = (VOID *) dcd_stm32;
|
||||
|
||||
/* Set the generic DCD owner for the STM32 DCD. */
|
||||
dcd_stm32 -> ux_dcd_stm32_dcd_owner = dcd;
|
||||
|
||||
/* Initialize the function collector for this DCD. */
|
||||
dcd -> ux_slave_dcd_function = _ux_dcd_stm32_function;
|
||||
|
||||
dcd_stm32 -> pcd_handle = (PCD_HandleTypeDef *)parameter;
|
||||
|
||||
/* Set the state of the controller to OPERATIONAL now. */
|
||||
dcd -> ux_slave_dcd_status = UX_DCD_STATUS_OPERATIONAL;
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,213 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_initialize_complete PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function completes the initialization of the USB slave */
|
||||
/* controller for the STM32 chip. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* (ux_slave_dcd_function) Process the DCD function */
|
||||
/* _ux_utility_descriptor_parse Parse descriptor */
|
||||
/* _ux_utility_memory_allocate Allocate memory */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
|
||||
/* prefixed UX to MS_TO_TICK, */
|
||||
/* used ST HAL library to */
|
||||
/* drive the controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_initialize_complete(VOID)
|
||||
{
|
||||
|
||||
UX_SLAVE_DCD *dcd;
|
||||
UX_DCD_STM32 *dcd_stm32;
|
||||
UX_SLAVE_DEVICE *device;
|
||||
UCHAR *device_framework;
|
||||
UX_SLAVE_TRANSFER *transfer_request;
|
||||
|
||||
|
||||
/* Get the pointer to the DCD. */
|
||||
dcd = &_ux_system_slave -> ux_system_slave_dcd;
|
||||
|
||||
/* Get the pointer to the STM32 DCD. */
|
||||
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
|
||||
|
||||
/* Get the pointer to the device. */
|
||||
device = &_ux_system_slave -> ux_system_slave_device;
|
||||
|
||||
/* Are we in DFU mode ? If so, check if we are in a Reset mode. */
|
||||
if (_ux_system_slave -> ux_system_slave_device_dfu_state_machine == UX_SYSTEM_DFU_STATE_APP_DETACH)
|
||||
{
|
||||
|
||||
/* The device is now in DFU reset mode. Switch to the DFU device framework. */
|
||||
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_dfu_framework;
|
||||
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_dfu_framework_length;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Set State to App Idle. */
|
||||
_ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_APP_IDLE;
|
||||
|
||||
/* Check the speed and set the correct descriptor. */
|
||||
if (_ux_system_slave -> ux_system_slave_speed == UX_FULL_SPEED_DEVICE)
|
||||
{
|
||||
|
||||
/* The device is operating at full speed. */
|
||||
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
|
||||
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* The device is operating at high speed. */
|
||||
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_high_speed;
|
||||
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_high_speed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the device framework pointer. */
|
||||
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
|
||||
|
||||
/* And create the decompressed device descriptor structure. */
|
||||
_ux_utility_descriptor_parse(device_framework,
|
||||
_ux_system_device_descriptor_structure,
|
||||
UX_DEVICE_DESCRIPTOR_ENTRIES,
|
||||
(UCHAR *) &device -> ux_slave_device_descriptor);
|
||||
|
||||
/* Now we create a transfer request to accept the first SETUP packet
|
||||
and get the ball running. First get the address of the endpoint
|
||||
transfer request container. */
|
||||
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
|
||||
|
||||
/* Set the timeout to be for Control Endpoint. */
|
||||
transfer_request -> ux_slave_transfer_request_timeout = UX_MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT);
|
||||
|
||||
/* Adjust the current data pointer as well. */
|
||||
transfer_request -> ux_slave_transfer_request_current_data_pointer =
|
||||
transfer_request -> ux_slave_transfer_request_data_pointer;
|
||||
|
||||
/* Update the transfer request endpoint pointer with the default endpoint. */
|
||||
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
|
||||
|
||||
/* The control endpoint max packet size needs to be filled manually in its descriptor. */
|
||||
transfer_request -> ux_slave_transfer_request_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize =
|
||||
device -> ux_slave_device_descriptor.bMaxPacketSize0;
|
||||
|
||||
/* On the control endpoint, always expect the maximum. */
|
||||
transfer_request -> ux_slave_transfer_request_requested_length =
|
||||
device -> ux_slave_device_descriptor.bMaxPacketSize0;
|
||||
|
||||
/* Attach the control endpoint to the transfer request. */
|
||||
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
|
||||
|
||||
/* Create the default control endpoint attached to the device.
|
||||
Once this endpoint is enabled, the host can then send a setup packet
|
||||
The device controller will receive it and will call the setup function
|
||||
module. */
|
||||
dcd -> ux_slave_dcd_function(dcd, UX_DCD_CREATE_ENDPOINT,
|
||||
(VOID *) &device -> ux_slave_device_control_endpoint);
|
||||
|
||||
/* Open Control OUT endpoint. */
|
||||
HAL_PCD_EP_Flush(dcd_stm32 -> pcd_handle, 0x00U);
|
||||
HAL_PCD_EP_Open(dcd_stm32 -> pcd_handle, 0x00U, device -> ux_slave_device_descriptor.bMaxPacketSize0, UX_CONTROL_ENDPOINT);
|
||||
|
||||
/* Open Control IN endpoint. */
|
||||
HAL_PCD_EP_Flush(dcd_stm32 -> pcd_handle, 0x80U);
|
||||
HAL_PCD_EP_Open(dcd_stm32 -> pcd_handle, 0x80U, device -> ux_slave_device_descriptor.bMaxPacketSize0, UX_CONTROL_ENDPOINT);
|
||||
|
||||
/* Ensure the control endpoint is properly reset. */
|
||||
device -> ux_slave_device_control_endpoint.ux_slave_endpoint_state = UX_ENDPOINT_RESET;
|
||||
|
||||
/* Mark the phase as SETUP. */
|
||||
transfer_request -> ux_slave_transfer_request_type = UX_TRANSFER_PHASE_SETUP;
|
||||
|
||||
/* Mark this transfer request as pending. */
|
||||
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_PENDING;
|
||||
|
||||
/* Ask for 8 bytes of the SETUP packet. */
|
||||
transfer_request -> ux_slave_transfer_request_requested_length = UX_SETUP_SIZE;
|
||||
transfer_request -> ux_slave_transfer_request_in_transfer_length = UX_SETUP_SIZE;
|
||||
|
||||
/* Reset the number of bytes sent/received. */
|
||||
transfer_request -> ux_slave_transfer_request_actual_length = 0;
|
||||
|
||||
/* Check the status change callback. */
|
||||
if(_ux_system_slave -> ux_system_slave_change_function != UX_NULL)
|
||||
{
|
||||
|
||||
/* Inform the application if a callback function was programmed. */
|
||||
_ux_system_slave -> ux_system_slave_change_function(UX_DEVICE_ATTACHED);
|
||||
}
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CONNECT, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
|
||||
|
||||
/* If trace is enabled, register this object. */
|
||||
UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_DEVICE, device, 0, 0, 0)
|
||||
|
||||
/* We are now ready for the USB device to accept the first packet when connected. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_system.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_interrupt_handler PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is the interrupt handler for the STM32 controller. */
|
||||
/* The controller will trigger an interrupt when something happens on */
|
||||
/* an endpoint whose mask has been set in the interrupt enable */
|
||||
/* register, or when a bus reset is detected. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_IRQHandler HAL IRQ handler */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* USBX Device Stack */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _ux_dcd_stm32_interrupt_handler(VOID)
|
||||
{
|
||||
|
||||
|
||||
UX_SLAVE_DCD *dcd;
|
||||
UX_DCD_STM32 *dcd_stm32;
|
||||
|
||||
|
||||
/* Get the pointer to the DCD. */
|
||||
dcd = &_ux_system_slave -> ux_system_slave_dcd;
|
||||
|
||||
/* Get the pointer to the STM32 DCD. */
|
||||
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
|
||||
|
||||
/* Call the actual interrupt handler function. */
|
||||
HAL_PCD_IRQHandler(dcd_stm32 -> pcd_handle);
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_transfer_request PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will initiate a transfer to a specific endpoint. */
|
||||
/* If the endpoint is IN, the endpoint register will be set to accept */
|
||||
/* the request. */
|
||||
/* */
|
||||
/* If the endpoint is IN, the endpoint FIFO will be filled with the */
|
||||
/* buffer and the endpoint register set. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_Transmit Transmit data */
|
||||
/* HAL_PCD_EP_Receive Receive data */
|
||||
/* _ux_utility_semaphore_get Get semaphore */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_transfer_abort(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
#if !defined (USBD_HAL_TRANSFER_ABORT_NOT_SUPPORTED)
|
||||
|
||||
UX_SLAVE_ENDPOINT *endpoint;
|
||||
|
||||
|
||||
/* Get the pointer to the logical endpoint from the transfer request. */
|
||||
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
|
||||
|
||||
HAL_PCD_EP_Abort(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress);
|
||||
HAL_PCD_EP_Flush(dcd_stm32 -> pcd_handle, endpoint->ux_slave_endpoint_descriptor.bEndpointAddress);
|
||||
|
||||
/* No semaphore put here since it's already done in stack. */
|
||||
#endif /* USBD_HAL_TRANSFER_ABORT_NOT_SUPPORTED */
|
||||
|
||||
/* Return to caller with success. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
#if !defined(UX_DEVICE_STANDALONE)
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_transfer_request PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will initiate a transfer to a specific endpoint. */
|
||||
/* If the endpoint is IN, the endpoint register will be set to accept */
|
||||
/* the request. */
|
||||
/* */
|
||||
/* If the endpoint is IN, the endpoint FIFO will be filled with the */
|
||||
/* buffer and the endpoint register set. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_Transmit Transmit data */
|
||||
/* HAL_PCD_EP_Receive Receive data */
|
||||
/* _ux_utility_semaphore_get Get semaphore */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_transfer_request(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
UX_SLAVE_ENDPOINT *endpoint;
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Get the pointer to the logical endpoint from the transfer request. */
|
||||
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
|
||||
|
||||
/* Check for transfer direction. Is this a IN endpoint ? */
|
||||
if (transfer_request -> ux_slave_transfer_request_phase == UX_TRANSFER_PHASE_DATA_OUT)
|
||||
{
|
||||
|
||||
/* Transmit data. */
|
||||
HAL_PCD_EP_Transmit(dcd_stm32 -> pcd_handle,
|
||||
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
|
||||
transfer_request->ux_slave_transfer_request_data_pointer,
|
||||
transfer_request->ux_slave_transfer_request_requested_length);
|
||||
|
||||
/* If the endpoint is a Control endpoint, all this is happening under Interrupt and there is no
|
||||
thread to suspend. */
|
||||
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & (UINT)~UX_ENDPOINT_DIRECTION) != 0)
|
||||
{
|
||||
|
||||
/* We should wait for the semaphore to wake us up. */
|
||||
status = _ux_utility_semaphore_get(&transfer_request -> ux_slave_transfer_request_semaphore,
|
||||
(ULONG)transfer_request -> ux_slave_transfer_request_timeout);
|
||||
|
||||
/* Check the completion code. */
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
transfer_request -> ux_slave_transfer_request_actual_length = transfer_request->ux_slave_transfer_request_requested_length;
|
||||
|
||||
/* Check the transfer request completion code. We may have had a BUS reset or
|
||||
a device disconnection. */
|
||||
if (transfer_request -> ux_slave_transfer_request_completion_code != UX_SUCCESS)
|
||||
return(transfer_request -> ux_slave_transfer_request_completion_code);
|
||||
|
||||
/* Return to caller with success. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* We have a request for a SETUP or OUT Endpoint. */
|
||||
/* Receive data. */
|
||||
HAL_PCD_EP_Receive(dcd_stm32 -> pcd_handle,
|
||||
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
|
||||
transfer_request->ux_slave_transfer_request_data_pointer,
|
||||
transfer_request->ux_slave_transfer_request_requested_length);
|
||||
|
||||
/* If the endpoint is a Control endpoint, all this is happening under Interrupt and there is no
|
||||
thread to suspend. */
|
||||
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & (UINT)~UX_ENDPOINT_DIRECTION) != 0)
|
||||
{
|
||||
|
||||
/* We should wait for the semaphore to wake us up. */
|
||||
status = _ux_utility_semaphore_get(&transfer_request -> ux_slave_transfer_request_semaphore,
|
||||
(ULONG)transfer_request -> ux_slave_transfer_request_timeout);
|
||||
|
||||
/* Check the completion code. */
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* Check the transfer request completion code. We may have had a BUS reset or
|
||||
a device disconnection. */
|
||||
if (transfer_request -> ux_slave_transfer_request_completion_code != UX_SUCCESS)
|
||||
return(transfer_request -> ux_slave_transfer_request_completion_code);
|
||||
|
||||
/* Return to caller with success. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return to caller with success. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
#endif
|
166
common/usbx_stm32_device_controllers/ux_dcd_stm32_transfer_run.c
Normal file
166
common/usbx_stm32_device_controllers/ux_dcd_stm32_transfer_run.c
Normal file
@ -0,0 +1,166 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_transfer_request PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will initiate a transfer to a specific endpoint. */
|
||||
/* If the endpoint is IN, the endpoint register will be set to accept */
|
||||
/* the request. */
|
||||
/* */
|
||||
/* If the endpoint is IN, the endpoint FIFO will be filled with the */
|
||||
/* buffer and the endpoint register set. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd_stm32 Pointer to device controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_PCD_EP_Transmit Transmit data */
|
||||
/* HAL_PCD_EP_Receive Receive data */
|
||||
/* _ux_utility_semaphore_get Get semaphore */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), used ST */
|
||||
/* HAL library to drive the */
|
||||
/* controller, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_transfer_run(UX_DCD_STM32 *dcd_stm32, UX_SLAVE_TRANSFER *transfer_request)
|
||||
{
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UX_SLAVE_ENDPOINT *endpoint;
|
||||
UX_DCD_STM32_ED *ed;
|
||||
ULONG ed_status;
|
||||
|
||||
|
||||
/* Get the pointer to the logical endpoint from the transfer request. */
|
||||
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
|
||||
|
||||
/* Get the physical endpoint address in the endpoint container. */
|
||||
ed = (UX_DCD_STM32_ED *) endpoint -> ux_slave_endpoint_ed;
|
||||
|
||||
UX_DISABLE
|
||||
|
||||
/* Get current ED status. */
|
||||
ed_status = ed -> ux_dcd_stm32_ed_status;
|
||||
|
||||
/* Invalid state. */
|
||||
if (_ux_system_slave -> ux_system_slave_device.ux_slave_device_state == UX_DEVICE_RESET)
|
||||
{
|
||||
transfer_request -> ux_slave_transfer_request_completion_code = UX_TRANSFER_BUS_RESET;
|
||||
UX_RESTORE
|
||||
return(UX_STATE_EXIT);
|
||||
}
|
||||
|
||||
/* ED stalled. */
|
||||
if (ed_status & UX_DCD_STM32_ED_STATUS_STALLED)
|
||||
{
|
||||
transfer_request -> ux_slave_transfer_request_completion_code = UX_TRANSFER_STALLED;
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
}
|
||||
|
||||
/* ED transfer in progress. */
|
||||
if (ed_status & UX_DCD_STM32_ED_STATUS_TRANSFER)
|
||||
{
|
||||
if (ed_status & UX_DCD_STM32_ED_STATUS_DONE)
|
||||
{
|
||||
|
||||
/* Keep used, stall and task pending bits. */
|
||||
ed -> ux_dcd_stm32_ed_status &= (UX_DCD_STM32_ED_STATUS_USED |
|
||||
UX_DCD_STM32_ED_STATUS_STALLED |
|
||||
UX_DCD_STM32_ED_STATUS_TASK_PENDING);
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
}
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
}
|
||||
|
||||
|
||||
/* Start transfer. */
|
||||
ed -> ux_dcd_stm32_ed_status |= UX_DCD_STM32_ED_STATUS_TRANSFER;
|
||||
|
||||
/* Check for transfer direction. Is this a IN endpoint ? */
|
||||
if (transfer_request -> ux_slave_transfer_request_phase == UX_TRANSFER_PHASE_DATA_OUT)
|
||||
{
|
||||
|
||||
/* Transmit data. */
|
||||
HAL_PCD_EP_Transmit(dcd_stm32 -> pcd_handle,
|
||||
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
|
||||
transfer_request->ux_slave_transfer_request_data_pointer,
|
||||
transfer_request->ux_slave_transfer_request_requested_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* We have a request for a SETUP or OUT Endpoint. */
|
||||
/* Receive data. */
|
||||
HAL_PCD_EP_Receive(dcd_stm32 -> pcd_handle,
|
||||
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
|
||||
transfer_request->ux_slave_transfer_request_data_pointer,
|
||||
transfer_request->ux_slave_transfer_request_requested_length);
|
||||
}
|
||||
|
||||
/* Return to caller with WAIT. */
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
}
|
||||
#endif /* defined(UX_DEVICE_STANDALONE) */
|
103
common/usbx_stm32_device_controllers/ux_dcd_stm32_uninitialize.c
Normal file
103
common/usbx_stm32_device_controllers/ux_dcd_stm32_uninitialize.c
Normal file
@ -0,0 +1,103 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_DCD_STM32_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_dcd_stm32.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_dcd_stm32_uninitialize PORTABLE C */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function uninitializes the USB device controller of the STM32 */
|
||||
/* microcontroller from ST. */
|
||||
/* */
|
||||
/* Note: only software structures are uninitialized. STM32 HAL APIs */
|
||||
/* must be used to uninitialize controller hardware BEFORE the */
|
||||
/* function is invoked. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* dcd Address of DCD, not used */
|
||||
/* parameter Parameter, STM32 HAL PCD */
|
||||
/* pointer is expected */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* USBX Device Stack */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_dcd_stm32_uninitialize(ULONG dcd_io, ULONG parameter)
|
||||
{
|
||||
|
||||
UX_SLAVE_DCD *dcd;
|
||||
UX_DCD_STM32 *dcd_stm32;
|
||||
|
||||
|
||||
UX_PARAMETER_NOT_USED(dcd_io);
|
||||
|
||||
/* Get the pointer to the DCD. */
|
||||
dcd = &_ux_system_slave -> ux_system_slave_dcd;
|
||||
|
||||
/* Set the state of the controller to HALTED now. */
|
||||
dcd -> ux_slave_dcd_status = UX_DCD_STATUS_HALTED;
|
||||
|
||||
/* Get controller driver. */
|
||||
dcd_stm32 = (UX_DCD_STM32 *)dcd -> ux_slave_dcd_controller_hardware;
|
||||
|
||||
/* Check parameter. */
|
||||
if ((ULONG)dcd_stm32 -> pcd_handle == parameter)
|
||||
{
|
||||
_ux_utility_memory_free(dcd_stm32);
|
||||
dcd -> ux_slave_dcd_controller_hardware = UX_NULL;
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
/* Parameter not correct. */
|
||||
return(UX_ERROR);
|
||||
}
|
179
common/usbx_stm32_host_controllers/ux_hcd_stm32.h
Normal file
179
common/usbx_stm32_host_controllers/ux_hcd_stm32.h
Normal file
@ -0,0 +1,179 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* ux_hcd_stm32.h PORTABLE C */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains all the header and extern functions used by the */
|
||||
/* USBX host STM32 Controller. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added ISO transfer support, */
|
||||
/* refined packet size manage, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef UX_HCD_STM32_H
|
||||
#define UX_HCD_STM32_H
|
||||
|
||||
#include "ux_stm32_config.h"
|
||||
|
||||
/* Define STM32 HCD generic definitions. */
|
||||
|
||||
|
||||
#define UX_HCD_STM32_CONTROLLER 6U
|
||||
#ifndef UX_HCD_STM32_MAX_NB_CHANNELS
|
||||
#define UX_HCD_STM32_MAX_NB_CHANNELS 12U
|
||||
#endif /* UX_HCD_STM32_MAX_NB_CHANNELS */
|
||||
|
||||
#define UX_HCD_STM32_MAX_HUB_BINTERVAL 8U
|
||||
#define UX_HCD_STM32_NB_ROOT_PORTS 1U
|
||||
#define UX_HCD_STM32_NO_CHANNEL_ASSIGNED 0xffU
|
||||
#define UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_ATTACHED 0x01U
|
||||
#define UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_DETACHED 0x02U
|
||||
#define UX_HCD_STM32_CONTROLLER_FLAG_SOF 0x04U
|
||||
#define UX_HCD_STM32_CONTROLLER_FLAG_TRANSFER_DONE 0x08U
|
||||
#define UX_HCD_STM32_CONTROLLER_FLAG_TRANSFER_ERROR 0x10U
|
||||
#define UX_HCD_STM32_CONTROLLER_LOW_SPEED_DEVICE 0x20U
|
||||
#define UX_HCD_STM32_CONTROLLER_FULL_SPEED_DEVICE 0x40U
|
||||
#define UX_HCD_STM32_CONTROLLER_HIGH_SPEED_DEVICE 0x80U
|
||||
#define UX_HCD_STM32_MAX_PACKET_COUNT 256U
|
||||
|
||||
#define UX_HCD_STM32_ED_STATUS_FREE 0x00U
|
||||
#define UX_HCD_STM32_ED_STATUS_ALLOCATED 0x01U
|
||||
#define UX_HCD_STM32_ED_STATUS_ABORTED 0x02U
|
||||
#define UX_HCD_STM32_ED_STATUS_CONTROL_SETUP 0x03U
|
||||
#define UX_HCD_STM32_ED_STATUS_CONTROL_DATA_IN 0x04U
|
||||
#define UX_HCD_STM32_ED_STATUS_CONTROL_DATA_OUT 0x05U
|
||||
#define UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_IN 0x06U
|
||||
#define UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_OUT 0x07U
|
||||
#define UX_HCD_STM32_ED_STATUS_BULK_IN 0x08U
|
||||
#define UX_HCD_STM32_ED_STATUS_BULK_OUT 0x09U
|
||||
#define UX_HCD_STM32_ED_STATUS_PERIODIC_TRANSFER 0x0AU
|
||||
#define UX_HCD_STM32_ED_STATUS_PENDING_MASK 0x0FU
|
||||
#define UX_HCD_STM32_ED_STATUS_TRANSFER_DONE 0x10U
|
||||
|
||||
|
||||
/* Define STM32 static definition. */
|
||||
|
||||
#define UX_HCD_STM32_AVAILABLE_BANDWIDTH 6000U
|
||||
|
||||
|
||||
/* Define STM32 structure. */
|
||||
|
||||
typedef struct UX_HCD_STM32_STRUCT
|
||||
{
|
||||
|
||||
struct UX_HCD_STRUCT *ux_hcd_stm32_hcd_owner;
|
||||
struct UX_HCD_STM32_ED_STRUCT *ux_hcd_stm32_ed_list;
|
||||
struct UX_HCD_STM32_ED_STRUCT *ux_hcd_stm32_channels_ed[UX_HCD_STM32_MAX_NB_CHANNELS];
|
||||
ULONG ux_hcd_stm32_nb_channels;
|
||||
UINT ux_hcd_stm32_queue_empty;
|
||||
UINT ux_hcd_stm32_periodic_scheduler_active;
|
||||
ULONG ux_hcd_stm32_controller_flag;
|
||||
HCD_HandleTypeDef *hcd_handle;
|
||||
struct UX_HCD_STM32_ED_STRUCT *ux_hcd_stm32_periodic_ed_head;
|
||||
} UX_HCD_STM32;
|
||||
|
||||
|
||||
/* Define STM32 ED structure. */
|
||||
|
||||
typedef struct UX_HCD_STM32_ED_STRUCT
|
||||
{
|
||||
|
||||
struct UX_HCD_STM32_ED_STRUCT *ux_stm32_ed_next_ed;
|
||||
struct UX_ENDPOINT_STRUCT *ux_stm32_ed_endpoint;
|
||||
struct UX_TRANSFER_STRUCT *ux_stm32_ed_transfer_request;
|
||||
UCHAR *ux_stm32_ed_setup;
|
||||
UCHAR *ux_stm32_ed_data;
|
||||
USHORT ux_stm32_ed_saved_length;
|
||||
USHORT ux_stm32_ed_saved_actual_length;
|
||||
ULONG ux_stm32_ed_packet_length;
|
||||
ULONG ux_stm32_ed_interval_mask;
|
||||
ULONG ux_stm32_ed_interval_position;
|
||||
ULONG ux_stm32_ed_current_ss_frame;
|
||||
UCHAR ux_stm32_ed_status;
|
||||
UCHAR ux_stm32_ed_channel;
|
||||
UCHAR ux_stm32_ed_dir;
|
||||
UCHAR ux_stm32_ed_speed;
|
||||
UCHAR ux_stm32_ed_type;
|
||||
UCHAR ux_stm32_ed_sch_mode;
|
||||
UCHAR reserved[2];
|
||||
} UX_HCD_STM32_ED;
|
||||
|
||||
|
||||
#define USBH_PID_SETUP 0U
|
||||
#define USBH_PID_DATA 1U
|
||||
|
||||
|
||||
/* Define STM32 function prototypes. */
|
||||
|
||||
UINT _ux_hcd_stm32_controller_disable(UX_HCD_STM32 *hcd_stm32);
|
||||
UX_HCD_STM32_ED * _ux_hcd_stm32_ed_obtain(UX_HCD_STM32 *hcd_stm32);
|
||||
UINT _ux_hcd_stm32_endpoint_create(UX_HCD_STM32 *hcd_stm32, UX_ENDPOINT *endpoint);
|
||||
UINT _ux_hcd_stm32_endpoint_destroy(UX_HCD_STM32 *hcd_stm32, UX_ENDPOINT *endpoint);
|
||||
UINT _ux_hcd_stm32_endpoint_reset(UX_HCD_STM32 *hcd_stm32, UX_ENDPOINT *endpoint);
|
||||
UINT _ux_hcd_stm32_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
UINT _ux_hcd_stm32_frame_number_get(UX_HCD_STM32 *hcd_stm32, ULONG *frame_number);
|
||||
UINT _ux_hcd_stm32_initialize(UX_HCD *hcd);
|
||||
VOID _ux_hcd_stm32_interrupt_handler(VOID);
|
||||
UINT _ux_hcd_stm32_least_traffic_list_get(UX_HCD_STM32 *hcd_stm32);
|
||||
UINT _ux_hcd_stm32_periodic_schedule(UX_HCD_STM32 *hcd_stm32);
|
||||
UINT _ux_hcd_stm32_port_disable(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_port_enable(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_port_reset(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_port_resume(UX_HCD_STM32 *hcd_stm32, UINT port_index);
|
||||
ULONG _ux_hcd_stm32_port_status_get(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_port_suspend(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_power_down_port(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_power_on_port(UX_HCD_STM32 *hcd_stm32, ULONG port_index);
|
||||
UINT _ux_hcd_stm32_request_bulk_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request);
|
||||
UINT _ux_hcd_stm32_request_control_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request);
|
||||
UINT _ux_hcd_stm32_request_periodic_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request);
|
||||
UINT _ux_hcd_stm32_request_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request);
|
||||
UINT _ux_hcd_stm32_request_trans_prepare(UX_HCD_STM32 *hcd_stm32, UX_HCD_STM32_ED *ed, UX_TRANSFER *transfer);
|
||||
VOID _ux_hcd_stm32_request_trans_finish(UX_HCD_STM32 *hcd_stm32, UX_HCD_STM32_ED *ed);
|
||||
UINT _ux_hcd_stm32_transfer_abort(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request);
|
||||
|
||||
#define ux_hcd_stm32_initialize _ux_hcd_stm32_initialize
|
||||
#define ux_hcd_stm32_interrupt_handler _ux_hcd_stm32_interrupt_handler
|
||||
|
||||
|
||||
#endif
|
||||
|
499
common/usbx_stm32_host_controllers/ux_hcd_stm32_callback.c
Normal file
499
common/usbx_stm32_host_controllers/ux_hcd_stm32_callback.c
Normal file
@ -0,0 +1,499 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* HAL_HCD_Connect_Callback PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function handles callback from HAL driver. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hhcd Pointer to HCD handle */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_semaphore_put Put semaphore */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* stm32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* refined macros names, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
|
||||
UX_HCD *hcd;
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
|
||||
|
||||
/* Get the pointer to the HCD & HCD_STM32. */
|
||||
hcd = (UX_HCD*)hhcd -> pData;
|
||||
hcd_stm32 = (UX_HCD_STM32*)hcd -> ux_hcd_controller_hardware;
|
||||
|
||||
/* Something happened on the root hub port. Signal it to the root hub thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0]++;
|
||||
|
||||
/* The controller has issued a ATTACH Root HUB signal. */
|
||||
hcd_stm32 -> ux_hcd_stm32_controller_flag |= UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_ATTACHED;
|
||||
hcd_stm32 -> ux_hcd_stm32_controller_flag &= ~UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_DETACHED;
|
||||
|
||||
/* Wake up the root hub thread. */
|
||||
_ux_host_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* HAL_HCD_Disconnect_Callback PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function handles callback from HAL driver. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hhcd Pointer to HCD handle */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_semaphore_put Put semaphore */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* stm32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* refined macros names, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
|
||||
UX_HCD *hcd;
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
|
||||
|
||||
/* Get the pointer to the HCD & HCD_STM32. */
|
||||
hcd = (UX_HCD*)hhcd -> pData;
|
||||
hcd_stm32 = (UX_HCD_STM32*)hcd -> ux_hcd_controller_hardware;
|
||||
|
||||
/* Something happened on the root hub port. Signal it to the root hub thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0]++;
|
||||
|
||||
/* The controller has issued a DETACH Root HUB signal. */
|
||||
hcd_stm32 -> ux_hcd_stm32_controller_flag |= UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_DETACHED;
|
||||
hcd_stm32 -> ux_hcd_stm32_controller_flag &= ~UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_ATTACHED;
|
||||
|
||||
/* Wake up the root hub thread. */
|
||||
_ux_host_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* HAL_HCD_Disconnect_Callback PORTABLE C */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function handles callback from HAL driver. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hhcd Pointer to HCD handle */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_semaphore_put Put semaphore */
|
||||
/* HAL_HCD_HC_SubmitRequest Submit request */
|
||||
/* HAL_HCD_HC_Halt Halt channel */
|
||||
/* HAL_HCD_HC_GetXferCount Get transfer count */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* stm32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* refined macros names, */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added ISO transfer support, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
|
||||
{
|
||||
|
||||
UX_HCD *hcd;
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UX_TRANSFER *transfer_request;
|
||||
UX_TRANSFER *transfer_next;
|
||||
|
||||
|
||||
/* Check the URB state. */
|
||||
if (urb_state == URB_DONE || urb_state == URB_STALL || urb_state == URB_ERROR || urb_state == URB_NOTREADY)
|
||||
{
|
||||
|
||||
/* Get the pointer to the HCD & HCD_STM32. */
|
||||
hcd = (UX_HCD*)hhcd -> pData;
|
||||
hcd_stm32 = (UX_HCD_STM32*)hcd -> ux_hcd_controller_hardware;
|
||||
|
||||
/* Check if driver is still valid. */
|
||||
if (hcd_stm32 == UX_NULL)
|
||||
return;
|
||||
|
||||
/* Load the ED for the channel. */
|
||||
ed = hcd_stm32 -> ux_hcd_stm32_channels_ed[chnum];
|
||||
|
||||
/* Check if ED is still valid. */
|
||||
if (ed == UX_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get transfer request. */
|
||||
transfer_request = ed -> ux_stm32_ed_transfer_request;
|
||||
|
||||
/* Check if request is still valid. */
|
||||
if (transfer_request == UX_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if URB state is not URB_NOTREADY. */
|
||||
if (urb_state != URB_NOTREADY)
|
||||
{
|
||||
|
||||
/* Handle URB states. */
|
||||
switch (urb_state)
|
||||
{
|
||||
case URB_STALL:
|
||||
|
||||
/* Set the completion code to stalled. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_STALLED;
|
||||
break;
|
||||
|
||||
case URB_DONE:
|
||||
|
||||
/* Check the request direction. */
|
||||
if (ed -> ux_stm32_ed_dir == 1)
|
||||
{
|
||||
if ((ed -> ux_stm32_ed_type == EP_TYPE_CTRL) || (ed -> ux_stm32_ed_type == EP_TYPE_BULK))
|
||||
{
|
||||
/* Get transfer size for receiving direction. */
|
||||
transfer_request -> ux_transfer_request_actual_length += HAL_HCD_HC_GetXferCount(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel);
|
||||
|
||||
/* Check if there is more data to be received. */
|
||||
if ((transfer_request -> ux_transfer_request_requested_length > transfer_request -> ux_transfer_request_actual_length) &&
|
||||
(HAL_HCD_HC_GetXferCount(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel) == ed->ux_stm32_ed_endpoint->ux_endpoint_descriptor.wMaxPacketSize))
|
||||
{
|
||||
/* Adjust the transmit length. */
|
||||
ed -> ux_stm32_ed_packet_length = UX_MIN(ed->ux_stm32_ed_endpoint->ux_endpoint_descriptor.wMaxPacketSize,
|
||||
transfer_request -> ux_transfer_request_requested_length - transfer_request -> ux_transfer_request_actual_length);
|
||||
|
||||
/* Submit the transmit request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
1U,
|
||||
ed -> ux_stm32_ed_type,
|
||||
USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_request -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get transfer size for receiving direction. */
|
||||
transfer_request -> ux_transfer_request_actual_length = HAL_HCD_HC_GetXferCount(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the request is for OUT transfer. */
|
||||
if (ed -> ux_stm32_ed_dir == 0U)
|
||||
{
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
if ((hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].do_ssplit == 1U) && (ed -> ux_stm32_ed_type == EP_TYPE_ISOC) &&
|
||||
(ed -> ux_stm32_ed_packet_length > hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].max_packet))
|
||||
{
|
||||
/* Update actual transfer length with ISOC max packet size for split transaction */
|
||||
transfer_request -> ux_transfer_request_actual_length += hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].max_packet;
|
||||
}
|
||||
else
|
||||
#endif /*defined (USBH_HAL_HUB_SPLIT_SUPPORTED) */
|
||||
{
|
||||
/* Update actual transfer length. */
|
||||
transfer_request -> ux_transfer_request_actual_length += ed -> ux_stm32_ed_packet_length;
|
||||
}
|
||||
|
||||
/* Check if there is more data to send. */
|
||||
if (transfer_request -> ux_transfer_request_requested_length >
|
||||
transfer_request -> ux_transfer_request_actual_length)
|
||||
{
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
if ((hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].do_ssplit == 1U) && (ed -> ux_stm32_ed_type == EP_TYPE_ISOC) &&
|
||||
(ed -> ux_stm32_ed_packet_length > hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].max_packet))
|
||||
{
|
||||
/* Adjust the transmit length. */
|
||||
ed -> ux_stm32_ed_packet_length = transfer_request -> ux_transfer_request_packet_length - \
|
||||
hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].max_packet;
|
||||
|
||||
/* Submit the transmit request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
0, ed -> ux_stm32_ed_type, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_request -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0);
|
||||
return;
|
||||
}
|
||||
#endif /* defined (USBH_HAL_HUB_SPLIT_SUPPORTED) */
|
||||
|
||||
/* Periodic transfer that needs schedule is not started here. */
|
||||
if (ed -> ux_stm32_ed_sch_mode)
|
||||
return;
|
||||
|
||||
/* Adjust the transmit length. */
|
||||
ed -> ux_stm32_ed_packet_length =
|
||||
UX_MIN(transfer_request -> ux_transfer_request_packet_length,
|
||||
transfer_request -> ux_transfer_request_requested_length -
|
||||
transfer_request -> ux_transfer_request_actual_length);
|
||||
|
||||
/* Submit the transmit request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
0, ed -> ux_stm32_ed_type, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_request -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the completion code to SUCCESS. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Set the completion code to transfer error. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_ERROR;
|
||||
}
|
||||
|
||||
/* Finish current transfer. */
|
||||
_ux_hcd_stm32_request_trans_finish(hcd_stm32, ed);
|
||||
|
||||
/* Move to next transfer. */
|
||||
transfer_next = transfer_request -> ux_transfer_request_next_transfer_request;
|
||||
ed -> ux_stm32_ed_transfer_request = transfer_next;
|
||||
|
||||
/* If there is transfer to start, start it. */
|
||||
if (transfer_next)
|
||||
{
|
||||
|
||||
/* If transfer is not started by schedular, start here. */
|
||||
if (!ed -> ux_stm32_ed_sch_mode)
|
||||
{
|
||||
|
||||
/* For ISO OUT, packet size is from request variable,
|
||||
* otherwise, use request length. */
|
||||
if ((ed -> ux_stm32_ed_type == EP_TYPE_ISOC) && (ed -> ux_stm32_ed_dir == 0))
|
||||
ed -> ux_stm32_ed_packet_length = transfer_next -> ux_transfer_request_packet_length;
|
||||
else
|
||||
ed -> ux_stm32_ed_packet_length = transfer_next -> ux_transfer_request_requested_length;
|
||||
|
||||
/* Prepare transactions. */
|
||||
_ux_hcd_stm32_request_trans_prepare(hcd_stm32, ed, transfer_next);
|
||||
|
||||
/* Call HAL driver to submit the transfer request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
ed -> ux_stm32_ed_dir,
|
||||
ed -> ux_stm32_ed_type, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_next -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Transfer not continued, periodic needs re-schedule. */
|
||||
if ((ed -> ux_stm32_ed_type == EP_TYPE_INTR) ||
|
||||
(ed -> ux_stm32_ed_type == EP_TYPE_ISOC))
|
||||
ed -> ux_stm32_ed_sch_mode = 1;
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
transfer_request -> ux_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
|
||||
ed -> ux_stm32_ed_status |= UX_HCD_STM32_ED_STATUS_TRANSFER_DONE;
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* Invoke callback function. */
|
||||
if (transfer_request -> ux_transfer_request_completion_function)
|
||||
transfer_request -> ux_transfer_request_completion_function(transfer_request);
|
||||
|
||||
/* Wake up the transfer request thread. */
|
||||
_ux_host_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Handle URB_NOTREADY state here. */
|
||||
/* Check if we need to retry the transfer by checking the status. */
|
||||
if ((ed -> ux_stm32_ed_status == UX_HCD_STM32_ED_STATUS_CONTROL_SETUP) ||
|
||||
(ed -> ux_stm32_ed_status == UX_HCD_STM32_ED_STATUS_CONTROL_DATA_OUT) ||
|
||||
(ed -> ux_stm32_ed_status == UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_OUT) ||
|
||||
(ed -> ux_stm32_ed_status == UX_HCD_STM32_ED_STATUS_BULK_OUT))
|
||||
{
|
||||
|
||||
/* Submit the transmit request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel, 0,
|
||||
((ed -> ux_stm32_ed_endpoint -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT ? EP_TYPE_BULK : EP_TYPE_CTRL,
|
||||
ed -> ux_stm32_ed_status == UX_HCD_STM32_ED_STATUS_CONTROL_SETUP ? USBH_PID_SETUP : USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_request -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* HAL_HCD_SOF_Callback PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function handles callback from HAL driver. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hhcd Pointer to HCD handle */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_semaphore_put Put semaphore */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* stm32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* refined macros names, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
|
||||
UX_HCD *hcd;
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
|
||||
|
||||
/* Get the pointer to the HCD & HCD_STM32. */
|
||||
hcd = (UX_HCD*)hhcd -> pData;
|
||||
hcd_stm32 = (UX_HCD_STM32*)hcd -> ux_hcd_controller_hardware;
|
||||
|
||||
if ((hcd_stm32 -> ux_hcd_stm32_controller_flag & UX_HCD_STM32_CONTROLLER_FLAG_SOF) == 0)
|
||||
{
|
||||
hcd_stm32 -> ux_hcd_stm32_controller_flag |= UX_HCD_STM32_CONTROLLER_FLAG_SOF;
|
||||
hcd -> ux_hcd_thread_signal++;
|
||||
|
||||
/* Wake up the scheduler. */
|
||||
_ux_host_semaphore_put(&_ux_system_host -> ux_system_host_hcd_semaphore);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_controller_disable PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will disable the STM32 controller. The controller */
|
||||
/* will release all its resources (memory, IO ...). After this, the */
|
||||
/* controller will not send SOF any longer. */
|
||||
/* */
|
||||
/* All transactions should have been completed, all classes should */
|
||||
/* have been closed. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_controller_disable(UX_HCD_STM32 *hcd_stm32)
|
||||
{
|
||||
|
||||
UX_HCD *hcd;
|
||||
|
||||
/* Point to the generic portion of the host controller structure instance. */
|
||||
hcd = hcd_stm32 -> ux_hcd_stm32_hcd_owner;
|
||||
|
||||
/* Reflect the state of the controller in the main structure. */
|
||||
hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
105
common/usbx_stm32_host_controllers/ux_hcd_stm32_ed_obtain.c
Normal file
105
common/usbx_stm32_host_controllers/ux_hcd_stm32_ed_obtain.c
Normal file
@ -0,0 +1,105 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_ed_obtain PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function obtains a free ED from the ED list. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* UX_HCD_STM32_ED * Pointer to ED */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_memory_set Set memory block */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UX_HCD_STM32_ED *_ux_hcd_stm32_ed_obtain(UX_HCD_STM32 *hcd_stm32)
|
||||
{
|
||||
|
||||
UX_HCD_STM32_ED *ed;
|
||||
ULONG ed_index;
|
||||
|
||||
|
||||
/* Start the search from the beginning of the list. */
|
||||
ed = hcd_stm32 -> ux_hcd_stm32_ed_list;
|
||||
for (ed_index = 0; ed_index < _ux_system_host -> ux_system_host_max_ed; ed_index++)
|
||||
{
|
||||
|
||||
/* Check the ED status, a free ED is marked with the UNUSED flag. */
|
||||
if (ed -> ux_stm32_ed_status == UX_HCD_STM32_ED_STATUS_FREE)
|
||||
{
|
||||
|
||||
/* The ED may have been used, so we reset all fields. */
|
||||
_ux_utility_memory_set(ed, 0, sizeof(UX_HCD_STM32_ED));
|
||||
|
||||
/* This ED is now marked as ALLOCATED. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ALLOCATED;
|
||||
|
||||
/* Reset the channel. */
|
||||
ed -> ux_stm32_ed_channel = UX_HCD_STM32_NO_CHANNEL_ASSIGNED;
|
||||
|
||||
/* Return ED pointer. */
|
||||
return(ed);
|
||||
}
|
||||
|
||||
/* Point to the next ED. */
|
||||
ed++;
|
||||
}
|
||||
|
||||
/* There is no available ED in the ED list. */
|
||||
return(UX_NULL);
|
||||
}
|
||||
|
@ -0,0 +1,276 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_endpoint_create PORTABLE C */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will create an endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* endpoint Pointer to endpoint */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_ed_obtain Obtain STM32 ED */
|
||||
/* _ux_hcd_stm32_least_traffic_list_get Get least traffic list */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added ISO transfer support, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_endpoint_create(UX_HCD_STM32 *hcd_stm32, UX_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UX_DEVICE *device;
|
||||
ULONG channel_index;
|
||||
UINT device_speed;
|
||||
UINT endpoint_type;
|
||||
ULONG packet_size;
|
||||
ULONG endpoint_bInterval;
|
||||
|
||||
|
||||
/* Get the pointer to the device. */
|
||||
device = endpoint -> ux_endpoint_device;
|
||||
|
||||
/* Set device speed. */
|
||||
switch (device -> ux_device_speed)
|
||||
{
|
||||
case UX_HIGH_SPEED_DEVICE:
|
||||
device_speed = HCD_DEVICE_SPEED_HIGH;
|
||||
break;
|
||||
case UX_FULL_SPEED_DEVICE:
|
||||
device_speed = HCD_DEVICE_SPEED_FULL;
|
||||
break;
|
||||
case UX_LOW_SPEED_DEVICE:
|
||||
device_speed = HCD_DEVICE_SPEED_LOW;
|
||||
break;
|
||||
default:
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
/* Set endpoint type. */
|
||||
switch ((endpoint -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE)
|
||||
{
|
||||
case UX_CONTROL_ENDPOINT:
|
||||
endpoint_type = EP_TYPE_CTRL;
|
||||
break;
|
||||
case UX_BULK_ENDPOINT:
|
||||
endpoint_type = EP_TYPE_BULK;
|
||||
break;
|
||||
case UX_INTERRUPT_ENDPOINT:
|
||||
endpoint_type = EP_TYPE_INTR;
|
||||
break;
|
||||
case UX_ISOCHRONOUS_ENDPOINT:
|
||||
endpoint_type = EP_TYPE_ISOC;
|
||||
break;
|
||||
default:
|
||||
return(UX_FUNCTION_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/* Obtain a ED for this new endpoint. This ED will live as long as the endpoint is active
|
||||
and will be the container for the tds. */
|
||||
ed = _ux_hcd_stm32_ed_obtain(hcd_stm32);
|
||||
if (ed == UX_NULL)
|
||||
return(UX_NO_ED_AVAILABLE);
|
||||
|
||||
/* And get a channel. */
|
||||
for (channel_index = 0; channel_index < hcd_stm32 -> ux_hcd_stm32_nb_channels; channel_index++)
|
||||
{
|
||||
|
||||
/* Check if that Channel is free. */
|
||||
if (hcd_stm32 -> ux_hcd_stm32_channels_ed[channel_index] == UX_NULL)
|
||||
{
|
||||
|
||||
/* We have a channel. Save it. */
|
||||
hcd_stm32 -> ux_hcd_stm32_channels_ed[channel_index] = ed;
|
||||
|
||||
/* And in the endpoint too. */
|
||||
ed -> ux_stm32_ed_channel = channel_index;
|
||||
|
||||
/* Done here. */
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for channel assignment. */
|
||||
if (ed -> ux_stm32_ed_channel == UX_HCD_STM32_NO_CHANNEL_ASSIGNED)
|
||||
{
|
||||
|
||||
/* Free the ED. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_FREE;
|
||||
|
||||
/* Could not allocate a channel. */
|
||||
return(UX_NO_ED_AVAILABLE);
|
||||
}
|
||||
|
||||
/* Check for interrupt and isochronous endpoints. */
|
||||
if ((endpoint_type == EP_TYPE_INTR) || (endpoint_type == EP_TYPE_ISOC))
|
||||
{
|
||||
if (device_speed == HCD_DEVICE_SPEED_HIGH)
|
||||
{
|
||||
if ((device->ux_device_current_configuration->ux_configuration_first_interface->ux_interface_descriptor.bInterfaceClass == 0x9U) &&
|
||||
(endpoint -> ux_endpoint_descriptor.bInterval > 9U))
|
||||
{
|
||||
/* Some hubs has an issue with larger binterval scheduling */
|
||||
endpoint_bInterval = UX_HCD_STM32_MAX_HUB_BINTERVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
endpoint_bInterval = endpoint -> ux_endpoint_descriptor.bInterval;
|
||||
}
|
||||
|
||||
/* Set the interval mask for high speed or isochronous endpoints. */
|
||||
ed -> ux_stm32_ed_interval_mask = (1 << (endpoint_bInterval - 1U)) - 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Set the interval mask for other endpoints. */
|
||||
ed -> ux_stm32_ed_interval_mask = endpoint -> ux_endpoint_descriptor.bInterval;
|
||||
|
||||
#if UX_MAX_DEVICES > 1
|
||||
if (device->ux_device_parent != NULL)
|
||||
{
|
||||
if (device->ux_device_parent->ux_device_speed == UX_HIGH_SPEED_DEVICE)
|
||||
{
|
||||
ed -> ux_stm32_ed_interval_mask <<= 3U;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ed -> ux_stm32_ed_interval_mask |= ed -> ux_stm32_ed_interval_mask >> 1;
|
||||
ed -> ux_stm32_ed_interval_mask |= ed -> ux_stm32_ed_interval_mask >> 2;
|
||||
ed -> ux_stm32_ed_interval_mask |= ed -> ux_stm32_ed_interval_mask >> 4;
|
||||
ed -> ux_stm32_ed_interval_mask >>= 1;
|
||||
}
|
||||
|
||||
/* Select a transfer time slot with least traffic. */
|
||||
if (ed -> ux_stm32_ed_interval_mask == 0)
|
||||
ed -> ux_stm32_ed_interval_position = 0;
|
||||
else
|
||||
ed -> ux_stm32_ed_interval_position = _ux_hcd_stm32_least_traffic_list_get(hcd_stm32);
|
||||
|
||||
/* No transfer on going. */
|
||||
ed -> ux_stm32_ed_transfer_request = UX_NULL;
|
||||
|
||||
/* Attach the ed to periodic ed list. */
|
||||
ed -> ux_stm32_ed_next_ed = hcd_stm32 -> ux_hcd_stm32_periodic_ed_head;
|
||||
hcd_stm32 -> ux_hcd_stm32_periodic_ed_head = ed;
|
||||
|
||||
/* Activate periodic scheduler. */
|
||||
hcd_stm32 -> ux_hcd_stm32_periodic_scheduler_active ++;
|
||||
}
|
||||
|
||||
/* Attach the ED to the endpoint container. */
|
||||
endpoint -> ux_endpoint_ed = (VOID *) ed;
|
||||
|
||||
/* Now do the opposite, attach the ED container to the physical ED. */
|
||||
ed -> ux_stm32_ed_endpoint = endpoint;
|
||||
ed -> ux_stm32_ed_speed = (UCHAR)device_speed;
|
||||
ed -> ux_stm32_ed_dir = (endpoint -> ux_endpoint_descriptor.bEndpointAddress & 0x80) ? 1 : 0;
|
||||
ed -> ux_stm32_ed_type = endpoint_type;
|
||||
packet_size = endpoint -> ux_endpoint_descriptor.wMaxPacketSize & UX_MAX_PACKET_SIZE_MASK;
|
||||
if (endpoint -> ux_endpoint_descriptor.wMaxPacketSize & UX_MAX_NUMBER_OF_TRANSACTIONS_MASK)
|
||||
{
|
||||
|
||||
/* Free the ED. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_FREE;
|
||||
|
||||
/* High bandwidth are not supported for now. */
|
||||
return(UX_FUNCTION_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/* By default scheduler is not needed. */
|
||||
ed -> ux_stm32_ed_sch_mode = 0;
|
||||
|
||||
/* By default data pointer is not used. */
|
||||
ed -> ux_stm32_ed_data = UX_NULL;
|
||||
|
||||
/* Call HAL to initialize the host channel. */
|
||||
HAL_HCD_HC_Init(hcd_stm32->hcd_handle,
|
||||
channel_index,
|
||||
endpoint -> ux_endpoint_descriptor.bEndpointAddress,
|
||||
device -> ux_device_address,
|
||||
device_speed,
|
||||
endpoint_type,
|
||||
endpoint -> ux_endpoint_descriptor.wMaxPacketSize);
|
||||
|
||||
/* Reset toggles. */
|
||||
hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].toggle_in = 0;
|
||||
hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].toggle_out = 0;
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
/* Check if device connected to hub */
|
||||
if (endpoint->ux_endpoint_device->ux_device_parent != NULL)
|
||||
{
|
||||
HAL_HCD_HC_SetHubInfo(hcd_stm32->hcd_handle, ed->ux_stm32_ed_channel,
|
||||
endpoint->ux_endpoint_device->ux_device_parent->ux_device_address,
|
||||
endpoint->ux_endpoint_device->ux_device_port_location);
|
||||
}
|
||||
#endif /* USBH_HAL_HUB_SPLIT_SUPPORTED */
|
||||
|
||||
/* We need to take into account the nature of the HCD to define the max size
|
||||
of any transfer in the transfer request. */
|
||||
endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = UX_HCD_STM32_MAX_PACKET_COUNT * packet_size;
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_endpoint_destroy PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will destroy an endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* endpoint Pointer to endpoint */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_virtual_address Get virtual address */
|
||||
/* _ux_utility_delay_ms Delay ms */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_endpoint_destroy(UX_HCD_STM32 *hcd_stm32, UX_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UX_HCD_STM32_ED *next_ed;
|
||||
UINT endpoint_type;
|
||||
|
||||
/* From the endpoint container fetch the STM32 ED descriptor. */
|
||||
ed = (UX_HCD_STM32_ED *) endpoint -> ux_endpoint_ed;
|
||||
|
||||
/* Check if this physical endpoint has been initialized properly! */
|
||||
if (ed == UX_NULL)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_ENDPOINT_HANDLE_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, endpoint, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_ENDPOINT_HANDLE_UNKNOWN);
|
||||
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* There is no background thread, just remove the ED from processing list. */
|
||||
UX_DISABLE
|
||||
#else
|
||||
|
||||
/* Wait for the controller to finish the current frame processing. */
|
||||
_ux_utility_delay_ms(1);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* We need to free the channel. */
|
||||
hcd_stm32 -> ux_hcd_stm32_channels_ed[ed -> ux_stm32_ed_channel] = UX_NULL;
|
||||
|
||||
/* Get endpoint type. */
|
||||
endpoint_type = (endpoint -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE;
|
||||
|
||||
/* Check for periodic endpoints. */
|
||||
if ((endpoint_type == UX_INTERRUPT_ENDPOINT) || (endpoint_type == UX_ISOCHRONOUS_ENDPOINT))
|
||||
{
|
||||
|
||||
/* Remove the ED from periodic ED list. */
|
||||
if (hcd_stm32 -> ux_hcd_stm32_periodic_ed_head == ed)
|
||||
{
|
||||
|
||||
/* The head one in the list, just set the pointer to it's next. */
|
||||
hcd_stm32 -> ux_hcd_stm32_periodic_ed_head = ed -> ux_stm32_ed_next_ed;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Get the first ED in the list. */
|
||||
next_ed = hcd_stm32 -> ux_hcd_stm32_periodic_ed_head;
|
||||
|
||||
/* Search for the ED in the list. */
|
||||
while( (next_ed != UX_NULL) && (next_ed -> ux_stm32_ed_next_ed != ed) )
|
||||
{
|
||||
|
||||
/* Move to next ED. */
|
||||
next_ed = next_ed -> ux_stm32_ed_next_ed;
|
||||
}
|
||||
|
||||
/* Check if we found the ED. */
|
||||
if (next_ed)
|
||||
{
|
||||
|
||||
/* Remove the ED from list. */
|
||||
next_ed -> ux_stm32_ed_next_ed = next_ed -> ux_stm32_ed_next_ed -> ux_stm32_ed_next_ed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decrease the periodic active count. */
|
||||
hcd_stm32 -> ux_hcd_stm32_periodic_scheduler_active --;
|
||||
}
|
||||
|
||||
/* Now we can safely make the ED free. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_FREE;
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
HAL_HCD_HC_ClearHubInfo(hcd_stm32->hcd_handle, ed -> ux_stm32_ed_channel);
|
||||
#endif /* USBH_HAL_HUB_SPLIT_SUPPORTED */
|
||||
|
||||
/* Finish current transfer. */
|
||||
_ux_hcd_stm32_request_trans_finish(hcd_stm32, ed);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* If setup memory is not freed correct, free it. */
|
||||
if (ed -> ux_stm32_ed_setup)
|
||||
_ux_utility_memory_free(ed -> ux_stm32_ed_setup);
|
||||
|
||||
UX_RESTORE
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_endpoint_reset PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will reset an endpoint. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* endpoint Pointer to endpoint */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_endpoint_reset(UX_HCD_STM32 *hcd_stm32, UX_ENDPOINT *endpoint)
|
||||
{
|
||||
|
||||
UX_HCD_STM32_ED *ed;
|
||||
|
||||
|
||||
/* From the endpoint container fetch the STM32 ED descriptor. */
|
||||
ed = (UX_HCD_STM32_ED *) endpoint -> ux_endpoint_ed;
|
||||
|
||||
/* Finish current transfer. */
|
||||
_ux_hcd_stm32_request_trans_finish(hcd_stm32, ed);
|
||||
|
||||
/* Reset the data0/data1 toggle bit. */
|
||||
hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].toggle_in = 0;
|
||||
hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].toggle_out = 0;
|
||||
|
||||
/* This operation never fails. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
248
common/usbx_stm32_host_controllers/ux_hcd_stm32_entry.c
Normal file
248
common/usbx_stm32_host_controllers/ux_hcd_stm32_entry.c
Normal file
@ -0,0 +1,248 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_entry PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function dispatch the HCD function internally to the STM32 */
|
||||
/* controller driver. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* HCD Pointer to HCD */
|
||||
/* function Function for driver to perform*/
|
||||
/* parameter Pointer to parameter(s) */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_asynchronous_endpoint_create Create async endpoint */
|
||||
/* _ux_hcd_stm32_asynchronous_endpoint_destroy Destroy async endpoint */
|
||||
/* _ux_hcd_stm32_controller_disable Disable controller */
|
||||
/* _ux_hcd_stm32_endpoint_reset Reset endpoint */
|
||||
/* _ux_hcd_stm32_frame_number_get Get frame number */
|
||||
/* _ux_hcd_stm32_interrupt_endpoint_create Create endpoint */
|
||||
/* _ux_hcd_stm32_periodic_endpoint_destroy Destroy endpoint */
|
||||
/* _ux_hcd_stm32_periodic_schedule Schedule periodic */
|
||||
/* _ux_hcd_stm32_port_enable Enable port */
|
||||
/* _ux_hcd_stm32_port_disable Disable port */
|
||||
/* _ux_hcd_stm32_port_reset Reset port */
|
||||
/* _ux_hcd_stm32_port_resume Resume port */
|
||||
/* _ux_hcd_stm32_port_status_get Get port status */
|
||||
/* _ux_hcd_stm32_port_suspend Suspend port */
|
||||
/* _ux_hcd_stm32_power_down_port Power down port */
|
||||
/* _ux_hcd_stm32_power_on_port Power on port */
|
||||
/* _ux_hcd_stm32_request_transfer Request transfer */
|
||||
/* _ux_hcd_stm32_transfer_abort Abort transfer */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Host Stack */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* refined macros names, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_entry(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Check the status of the controller. */
|
||||
if (hcd -> ux_hcd_status == UX_UNUSED)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_CONTROLLER_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONTROLLER_UNKNOWN, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_CONTROLLER_UNKNOWN);
|
||||
}
|
||||
|
||||
/* Get the pointer to the STM32 HCD. */
|
||||
hcd_stm32 = (UX_HCD_STM32 *) hcd -> ux_hcd_controller_hardware;
|
||||
|
||||
/* look at the function and route it. */
|
||||
switch(function)
|
||||
{
|
||||
|
||||
case UX_HCD_DISABLE_CONTROLLER:
|
||||
|
||||
status = _ux_hcd_stm32_controller_disable(hcd_stm32);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
status = _ux_hcd_stm32_port_status_get(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_ENABLE_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_port_enable(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_DISABLE_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_port_disable(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_POWER_ON_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_power_on_port(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_POWER_DOWN_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_power_down_port(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_SUSPEND_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_port_suspend(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_RESUME_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_port_resume(hcd_stm32, (UINT) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_RESET_PORT:
|
||||
|
||||
status = _ux_hcd_stm32_port_reset(hcd_stm32, (ULONG) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_GET_FRAME_NUMBER:
|
||||
|
||||
status = _ux_hcd_stm32_frame_number_get(hcd_stm32, (ULONG *) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_TRANSFER_REQUEST:
|
||||
|
||||
status = _ux_hcd_stm32_request_transfer(hcd_stm32, (UX_TRANSFER *) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_TRANSFER_ABORT:
|
||||
|
||||
status = _ux_hcd_stm32_transfer_abort(hcd_stm32, (UX_TRANSFER *) parameter);
|
||||
break;
|
||||
|
||||
|
||||
case UX_HCD_CREATE_ENDPOINT:
|
||||
|
||||
status = _ux_hcd_stm32_endpoint_create(hcd_stm32, (UX_ENDPOINT*) parameter);
|
||||
break;
|
||||
|
||||
case UX_HCD_DESTROY_ENDPOINT:
|
||||
|
||||
status = _ux_hcd_stm32_endpoint_destroy(hcd_stm32, (UX_ENDPOINT*) parameter);
|
||||
break;
|
||||
|
||||
case UX_HCD_RESET_ENDPOINT:
|
||||
|
||||
status = _ux_hcd_stm32_endpoint_reset(hcd_stm32, (UX_ENDPOINT*) parameter);
|
||||
break;
|
||||
|
||||
case UX_HCD_PROCESS_DONE_QUEUE:
|
||||
|
||||
/* Process periodic queue. */
|
||||
_ux_hcd_stm32_periodic_schedule(hcd_stm32);
|
||||
|
||||
/* Reset the SOF flag. */
|
||||
UX_DISABLE
|
||||
hcd_stm32 -> ux_hcd_stm32_controller_flag &= ~UX_HCD_STM32_CONTROLLER_FLAG_SOF;
|
||||
UX_RESTORE
|
||||
|
||||
status = UX_SUCCESS;
|
||||
break;
|
||||
|
||||
case UX_HCD_UNINITIALIZE:
|
||||
|
||||
/* free HCD resources */
|
||||
if (hcd_stm32 != UX_NULL)
|
||||
{
|
||||
_ux_utility_memory_free(hcd_stm32 -> ux_hcd_stm32_ed_list);
|
||||
_ux_utility_memory_free(hcd_stm32);
|
||||
}
|
||||
|
||||
status = UX_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_FUNCTION_NOT_SUPPORTED);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
/* Unknown request, return an error. */
|
||||
status = UX_FUNCTION_NOT_SUPPORTED;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
@ -0,0 +1,80 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_frame_number_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will return the frame number currently used by the */
|
||||
/* controller. This function is mostly used for isochronous purposes. */
|
||||
/* */
|
||||
/* Note since ThreadX delay is used, the function must not be used in */
|
||||
/* interrupts. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* frame_number Frame number to set */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_frame_number_get(UX_HCD_STM32 *hcd_stm32, ULONG *frame_number)
|
||||
{
|
||||
|
||||
/* Call HAL to get the frame number. */
|
||||
*frame_number = (ULONG)HAL_HCD_GetCurrentFrame(hcd_stm32 -> hcd_handle);
|
||||
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
150
common/usbx_stm32_host_controllers/ux_hcd_stm32_initialize.c
Normal file
150
common/usbx_stm32_host_controllers/ux_hcd_stm32_initialize.c
Normal file
@ -0,0 +1,150 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_initialize PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function initializes the STM32 HS USB host controller. This */
|
||||
/* is not for the OTG mode. It forces the chip in Host mode only. */
|
||||
/* For OTG support, the filex in the usbx_otg subdirectory must be */
|
||||
/* used. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* HCD Pointer to HCD */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_memory_allocate Allocate memory block */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Host Stack */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_initialize(UX_HCD *hcd)
|
||||
{
|
||||
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
|
||||
|
||||
/* The controller initialized here is of STM32 type. */
|
||||
hcd -> ux_hcd_controller_type = UX_HCD_STM32_CONTROLLER;
|
||||
|
||||
/* Initialize the max bandwidth for periodic endpoints. On STM32, the spec says
|
||||
no more than 90% to be allocated for periodic. */
|
||||
#if UX_MAX_DEVICES > 1
|
||||
hcd -> ux_hcd_available_bandwidth = UX_HCD_STM32_AVAILABLE_BANDWIDTH;
|
||||
#endif
|
||||
|
||||
/* Allocate memory for this STM32 HCD instance. */
|
||||
hcd_stm32 = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HCD_STM32));
|
||||
if (hcd_stm32 == UX_NULL)
|
||||
return(UX_MEMORY_INSUFFICIENT);
|
||||
|
||||
/* Set the pointer to the STM32 HCD. */
|
||||
hcd -> ux_hcd_controller_hardware = (VOID *) hcd_stm32;
|
||||
|
||||
/* Set the generic HCD owner for the STM32 HCD. */
|
||||
hcd_stm32 -> ux_hcd_stm32_hcd_owner = hcd;
|
||||
|
||||
/* Initialize the function collector for this HCD. */
|
||||
hcd -> ux_hcd_entry_function = _ux_hcd_stm32_entry;
|
||||
|
||||
/* Set the state of the controller to HALTED first. */
|
||||
hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
|
||||
|
||||
/* Initialize the number of channels. */
|
||||
hcd_stm32 -> ux_hcd_stm32_nb_channels = UX_HCD_STM32_MAX_NB_CHANNELS;
|
||||
|
||||
/* Check if the parameter is null. */
|
||||
if (hcd -> ux_hcd_irq == 0)
|
||||
{
|
||||
_ux_utility_memory_free(hcd_stm32);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
/* Get HCD handle from parameter. */
|
||||
hcd_stm32 -> hcd_handle = (HCD_HandleTypeDef*)hcd -> ux_hcd_irq;
|
||||
hcd_stm32 -> hcd_handle -> pData = hcd;
|
||||
|
||||
/* Allocate the list of eds. */
|
||||
hcd_stm32 -> ux_hcd_stm32_ed_list = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HCD_STM32_ED) *_ux_system_host -> ux_system_host_max_ed);
|
||||
if (hcd_stm32 -> ux_hcd_stm32_ed_list == UX_NULL)
|
||||
{
|
||||
_ux_utility_memory_free(hcd_stm32);
|
||||
return(UX_MEMORY_INSUFFICIENT);
|
||||
}
|
||||
|
||||
/* Since we know this is a high-speed controller, we can hardwire the version. */
|
||||
#if UX_MAX_DEVICES > 1
|
||||
hcd -> ux_hcd_version = 0x200;
|
||||
#endif
|
||||
|
||||
/* The number of ports on the controller is fixed to 1. The number of ports needs to be reflected both
|
||||
for the generic HCD container and the local stm32 container. */
|
||||
hcd -> ux_hcd_nb_root_hubs = UX_HCD_STM32_NB_ROOT_PORTS;
|
||||
|
||||
/* The root port must now be powered to pick up device insertion. */
|
||||
_ux_hcd_stm32_power_on_port(hcd_stm32, 0);
|
||||
|
||||
/* The asynchronous queues are empty for now. */
|
||||
hcd_stm32 -> ux_hcd_stm32_queue_empty = UX_TRUE;
|
||||
|
||||
/* The periodic scheduler is not active. */
|
||||
hcd_stm32 -> ux_hcd_stm32_periodic_scheduler_active = 0;
|
||||
|
||||
/* Set the host controller into the operational state. */
|
||||
hcd -> ux_hcd_status = UX_HCD_STATUS_OPERATIONAL;
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_interrupt_handler PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is the interrupt handler for the USB interrupts. */
|
||||
/* This function calls HAL driver for interrupt handling. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_HCD_IRQHandler Interrupt handler */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ThreadX Interrupt Handler */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _ux_hcd_stm32_interrupt_handler(VOID)
|
||||
{
|
||||
|
||||
UINT hcd_index;
|
||||
UX_HCD *hcd;
|
||||
UX_HCD_STM32 *hcd_stm32;
|
||||
|
||||
|
||||
/* We need to parse the controller driver table to find all controllers that
|
||||
are registered as STM32. */
|
||||
for (hcd_index = 0; hcd_index < _ux_system_host -> ux_system_host_registered_hcd; hcd_index++)
|
||||
{
|
||||
|
||||
/* Check type of controller. */
|
||||
if (_ux_system_host -> ux_system_host_hcd_array[hcd_index].ux_hcd_controller_type == UX_HCD_STM32_CONTROLLER)
|
||||
{
|
||||
|
||||
/* Get the pointers to the generic HCD and STM32 specific areas. */
|
||||
hcd = &_ux_system_host -> ux_system_host_hcd_array[hcd_index];
|
||||
hcd_stm32 = (UX_HCD_STM32 *) hcd -> ux_hcd_controller_hardware;
|
||||
|
||||
/* Call HAL interrupt handler. */
|
||||
HAL_HCD_IRQHandler(hcd_stm32 -> hcd_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,128 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_least_traffic_list_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function return a pointer to the first ED in the periodic */
|
||||
/* tree that has the least traffic registered. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* UX_HCD_STM32_ED * Pointer to STM32 ED */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_least_traffic_list_get(UX_HCD_STM32 *hcd_stm32)
|
||||
{
|
||||
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UINT list_index;
|
||||
ULONG min_bandwidth_used;
|
||||
ULONG bandwidth_used;
|
||||
UINT min_bandwidth_slot;
|
||||
|
||||
|
||||
/* Set the min bandwidth used to a arbitrary maximum value. */
|
||||
min_bandwidth_used = 0xffffffff;
|
||||
|
||||
/* The first ED is the list candidate for now. */
|
||||
min_bandwidth_slot = 0;
|
||||
|
||||
/* All list will be scanned. */
|
||||
for (list_index = 0; list_index < 32; list_index++)
|
||||
{
|
||||
|
||||
/* Reset the bandwidth for this list. */
|
||||
bandwidth_used = 0;
|
||||
|
||||
/* Get the ED of the beginning of the list we parse now. */
|
||||
ed = hcd_stm32 -> ux_hcd_stm32_periodic_ed_head;
|
||||
|
||||
/* Parse the eds in the list. */
|
||||
while (ed != UX_NULL)
|
||||
{
|
||||
|
||||
if ((list_index & ed -> ux_stm32_ed_interval_mask) == ed -> ux_stm32_ed_interval_position)
|
||||
{
|
||||
|
||||
/* Add to the bandwidth used the max packet size pointed by this ED. */
|
||||
bandwidth_used += (ULONG) ed -> ux_stm32_ed_endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
|
||||
}
|
||||
|
||||
/* Move to next ED. */
|
||||
ed = ed -> ux_stm32_ed_next_ed;
|
||||
}
|
||||
|
||||
/* We have processed a list, check the bandwidth used by this list.
|
||||
If this bandwidth is the minimum, we memorize the ED. */
|
||||
if (bandwidth_used < min_bandwidth_used)
|
||||
{
|
||||
|
||||
/* We have found a better list with a lower used bandwidth, memorize the bandwidth
|
||||
for this list. */
|
||||
min_bandwidth_used = bandwidth_used;
|
||||
|
||||
/* Memorize the begin ED for this list. */
|
||||
min_bandwidth_slot = list_index;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the ED list with the lowest bandwidth. */
|
||||
return(min_bandwidth_slot);
|
||||
}
|
||||
|
@ -0,0 +1,267 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_periodic_schedule PORTABLE C */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function schedules new transfers from the periodic interrupt */
|
||||
/* list. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TRUE or FALSE */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_HCD_GetCurrentFrame Get frame number */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added ISO transfer support, */
|
||||
/* resulting in version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_periodic_schedule(UX_HCD_STM32 *hcd_stm32)
|
||||
{
|
||||
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UX_TRANSFER *transfer_request;
|
||||
ULONG frame_index;
|
||||
UX_DEVICE *parent_device;
|
||||
UX_ENDPOINT *endpoint;
|
||||
UX_ENDPOINT *parent_endpoint;
|
||||
ULONG ep_schedule = 1U;
|
||||
USHORT port_status_change_bits;
|
||||
|
||||
/* Get the current frame number. */
|
||||
frame_index = HAL_HCD_GetCurrentFrame(hcd_stm32 -> hcd_handle);
|
||||
|
||||
/* Get the first ED in the periodic list. */
|
||||
ed = hcd_stm32 -> ux_hcd_stm32_periodic_ed_head;
|
||||
|
||||
/* Search for an entry in the periodic tree. */
|
||||
while (ed != UX_NULL)
|
||||
{
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
if (hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].do_ssplit == 1U)
|
||||
{
|
||||
/* Get the transfer request. */
|
||||
transfer_request = ed -> ux_stm32_ed_transfer_request;
|
||||
|
||||
if (transfer_request != NULL)
|
||||
{
|
||||
if ((frame_index & ed -> ux_stm32_ed_interval_mask) == ed -> ux_stm32_ed_interval_position)
|
||||
{
|
||||
hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].ep_ss_schedule = 1U;
|
||||
}
|
||||
|
||||
/* Schedule Start & Complete split where the entire split transaction is completely bounded by a
|
||||
frame FS/LS devices */
|
||||
if (((((frame_index & 0x7U) < 0x3U) || ((frame_index & 0x7U) == 0x7U)) &&
|
||||
(hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].ep_ss_schedule == 1U)) ||
|
||||
((hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].do_csplit == 1U) &&
|
||||
(frame_index > (ed -> ux_stm32_ed_current_ss_frame + 1U))))
|
||||
{
|
||||
if (hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].ep_ss_schedule == 1U)
|
||||
{
|
||||
hcd_stm32 -> hcd_handle -> hc[ed -> ux_stm32_ed_channel].ep_ss_schedule = 0U;
|
||||
ed -> ux_stm32_ed_current_ss_frame = frame_index;
|
||||
}
|
||||
|
||||
/* Check if there is transfer needs schedule. */
|
||||
if (ed -> ux_stm32_ed_sch_mode)
|
||||
{
|
||||
/* If it's scheduled each SOF/uSOF, the request should be submitted
|
||||
* immediately after packet is done. This is performed in callback. */
|
||||
if (ed -> ux_stm32_ed_interval_mask == 0U)
|
||||
ed -> ux_stm32_ed_sch_mode = 0U;
|
||||
|
||||
/* For ISO OUT, packet size is from request variable,
|
||||
* otherwise, use request length. */
|
||||
if ((ed -> ux_stm32_ed_type == EP_TYPE_ISOC) && (ed -> ux_stm32_ed_dir == 0U))
|
||||
ed -> ux_stm32_ed_packet_length = transfer_request -> ux_transfer_request_packet_length;
|
||||
else
|
||||
ed -> ux_stm32_ed_packet_length = transfer_request -> ux_transfer_request_requested_length;
|
||||
|
||||
/* Prepare transactions. */
|
||||
_ux_hcd_stm32_request_trans_prepare(hcd_stm32, ed, transfer_request);
|
||||
|
||||
/* Get the pointer to the Endpoint. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
/* Check if device connected to hub */
|
||||
if (endpoint->ux_endpoint_device->ux_device_parent != NULL)
|
||||
{
|
||||
parent_device = endpoint->ux_endpoint_device->ux_device_parent;
|
||||
if (parent_device->ux_device_current_configuration->ux_configuration_first_interface->ux_interface_descriptor.bInterfaceClass == 0x9U)
|
||||
{
|
||||
parent_endpoint = parent_device->ux_device_current_configuration->ux_configuration_first_interface->ux_interface_first_endpoint;
|
||||
|
||||
if (parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_actual_length != 0U)
|
||||
{
|
||||
/* The interrupt pipe buffer contains the status change for each of the ports
|
||||
the length of the buffer can be 1 or 2 depending on the number of ports.
|
||||
Usually, since HUBs can be bus powered the maximum number of ports is 4.
|
||||
We must be taking precautions on how we read the buffer content for
|
||||
big endian machines. */
|
||||
if (parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_actual_length == 1U)
|
||||
port_status_change_bits = *(USHORT *) parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_data_pointer;
|
||||
else
|
||||
port_status_change_bits = (USHORT)_ux_utility_short_get(parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_data_pointer);
|
||||
|
||||
if ((port_status_change_bits & (0x1U << endpoint->ux_endpoint_device->ux_device_port_location)) != 0U)
|
||||
{
|
||||
ep_schedule = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((endpoint->ux_endpoint_device->ux_device_state == UX_DEVICE_CONFIGURED) && (ep_schedule != 0U))
|
||||
{
|
||||
/* Call HAL driver to submit the transfer request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
ed -> ux_stm32_ed_dir,
|
||||
ed -> ux_stm32_ed_type, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_request -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0U);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* defined (USBH_HAL_HUB_SPLIT_SUPPORTED) */
|
||||
{
|
||||
/* Check if the periodic transfer should be scheduled in this frame. */
|
||||
/* Interval Mask is 0: it's scheduled every SOF/uSOF. */
|
||||
/* Interval Mask is not 0: check position to see if it's scheduled. */
|
||||
if ((frame_index & ed -> ux_stm32_ed_interval_mask) == ed -> ux_stm32_ed_interval_position)
|
||||
{
|
||||
|
||||
/* Get the transfer request. */
|
||||
transfer_request = ed -> ux_stm32_ed_transfer_request;
|
||||
|
||||
/* Check if there is transfer needs schedule. */
|
||||
if (transfer_request && ed -> ux_stm32_ed_sch_mode)
|
||||
{
|
||||
|
||||
/* If it's scheduled each SOF/uSOF, the request should be submitted
|
||||
* immediately after packet is done. This is performed in callback. */
|
||||
if (ed -> ux_stm32_ed_interval_mask == 0U)
|
||||
ed -> ux_stm32_ed_sch_mode = 0U;
|
||||
|
||||
/* For ISO OUT, packet size is from request variable,
|
||||
* otherwise, use request length. */
|
||||
if ((ed -> ux_stm32_ed_type == EP_TYPE_ISOC) && (ed -> ux_stm32_ed_dir == 0U))
|
||||
ed -> ux_stm32_ed_packet_length = transfer_request -> ux_transfer_request_packet_length;
|
||||
else
|
||||
ed -> ux_stm32_ed_packet_length = transfer_request -> ux_transfer_request_requested_length;
|
||||
|
||||
/* Prepare transactions. */
|
||||
_ux_hcd_stm32_request_trans_prepare(hcd_stm32, ed, transfer_request);
|
||||
|
||||
/* Get the pointer to the Endpoint. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
/* Check if device connected to hub */
|
||||
if (endpoint->ux_endpoint_device->ux_device_parent != NULL)
|
||||
{
|
||||
parent_device = endpoint->ux_endpoint_device->ux_device_parent;
|
||||
if (parent_device->ux_device_current_configuration->ux_configuration_first_interface->ux_interface_descriptor.bInterfaceClass == 0x9U)
|
||||
{
|
||||
parent_endpoint = parent_device->ux_device_current_configuration->ux_configuration_first_interface->ux_interface_first_endpoint;
|
||||
|
||||
if (parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_actual_length != 0U)
|
||||
{
|
||||
/* The interrupt pipe buffer contains the status change for each of the ports
|
||||
the length of the buffer can be 1 or 2 depending on the number of ports.
|
||||
Usually, since HUBs can be bus powered the maximum number of ports is 4.
|
||||
We must be taking precautions on how we read the buffer content for
|
||||
big endian machines. */
|
||||
if (parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_actual_length == 1U)
|
||||
port_status_change_bits = *(USHORT *) parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_data_pointer;
|
||||
else
|
||||
port_status_change_bits = (USHORT)_ux_utility_short_get(parent_endpoint->ux_endpoint_transfer_request.ux_transfer_request_data_pointer);
|
||||
|
||||
if ((port_status_change_bits & (0x1U << endpoint->ux_endpoint_device->ux_device_port_location)) != 0U)
|
||||
{
|
||||
ep_schedule = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((endpoint->ux_endpoint_device->ux_device_state == UX_DEVICE_CONFIGURED) && (ep_schedule != 0U))
|
||||
{
|
||||
/* Call HAL driver to submit the transfer request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
ed -> ux_stm32_ed_dir,
|
||||
ed -> ux_stm32_ed_type, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data + transfer_request -> ux_transfer_request_actual_length,
|
||||
ed -> ux_stm32_ed_packet_length, 0U);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Point to the next ED in the list. */
|
||||
ed = ed -> ux_stm32_ed_next_ed;
|
||||
}
|
||||
|
||||
/* Return to caller. */
|
||||
return(UX_FALSE);
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_port_disable PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will disable a specific port attached to the root */
|
||||
/* HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_port_disable(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_port_enable PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will enable a specific port attached to the root */
|
||||
/* HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_port_enable(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
129
common/usbx_stm32_host_controllers/ux_hcd_stm32_port_reset.c
Normal file
129
common/usbx_stm32_host_controllers/ux_hcd_stm32_port_reset.c
Normal file
@ -0,0 +1,129 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_port_reset PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will reset a specific port attached to the root */
|
||||
/* HUB. */
|
||||
/* */
|
||||
/* Note since ThreadX delay is used, the function must not be used in */
|
||||
/* interrupts. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_hcor_register_read Read STM32 register */
|
||||
/* _ux_hcd_stm32_hcor_register_write Write STM32 register */
|
||||
/* _ux_utility_delay_ms Delay */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_port_reset(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
/* Check to see if this port is valid on this controller. On STM32, there is only one. */
|
||||
if (port_index != 0)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_PORT_INDEX_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_PORT_INDEX_UNKNOWN, port_index, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
return(UX_STATE_ERROR);
|
||||
#else
|
||||
return(UX_PORT_INDEX_UNKNOWN);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
}
|
||||
|
||||
/* Ensure that the downstream port has a device attached. It is unnatural
|
||||
to perform a port reset if there is no device. */
|
||||
if ((hcd_stm32 -> ux_hcd_stm32_controller_flag & UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_ATTACHED) == 0)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_NO_DEVICE_CONNECTED);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_NO_DEVICE_CONNECTED, port_index, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
return(UX_STATE_ERROR);
|
||||
#else
|
||||
return(UX_NO_DEVICE_CONNECTED);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
/* There is no way for non-blocking reset in HCD, just do blocking operation here. */
|
||||
HAL_HCD_ResetPort(hcd_stm32 -> hcd_handle);
|
||||
return(UX_STATE_NEXT);
|
||||
#else
|
||||
HAL_HCD_ResetPort(hcd_stm32 -> hcd_handle);
|
||||
|
||||
/* This function should never fail. */
|
||||
return(UX_SUCCESS);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_port_resume PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will resume a specific port attached to the root */
|
||||
/* HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_port_resume(UX_HCD_STM32 *hcd_stm32, UINT port_index)
|
||||
{
|
||||
|
||||
/* Return error status. */
|
||||
return(UX_FUNCTION_NOT_SUPPORTED);
|
||||
}
|
||||
|
@ -0,0 +1,149 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_port_status_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will return the status for each port attached to the */
|
||||
/* root HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* STM32 Port Status */
|
||||
/* */
|
||||
/* Where port status has the following format: */
|
||||
/* */
|
||||
/* bit 0 device connection status */
|
||||
/* if 0 : no device connected */
|
||||
/* if 1 : device connected to the port */
|
||||
/* bit 1 port enable status */
|
||||
/* if 0 : port disabled */
|
||||
/* if 1 : port enabled */
|
||||
/* bit 2 port suspend status */
|
||||
/* if 0 : port is not suspended */
|
||||
/* if 1 : port is suspended */
|
||||
/* bit 3 port overcurrent status */
|
||||
/* if 0 : port has no overcurrent condition */
|
||||
/* if 1 : port has overcurrent condition */
|
||||
/* bit 4 port reset status */
|
||||
/* if 0 : port is not in reset */
|
||||
/* if 1 : port is in reset */
|
||||
/* bit 5 port power status */
|
||||
/* if 0 : port power is off */
|
||||
/* if 1 : port power is on */
|
||||
/* bit 6-7 device attached speed */
|
||||
/* if 00 : low speed device attached */
|
||||
/* if 01 : full speed device attached */
|
||||
/* if 10 : high speed device attached */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* HAL_HCD_GetCurrentSpeed Get device speed */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
ULONG _ux_hcd_stm32_port_status_get(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
ULONG port_status;
|
||||
|
||||
|
||||
/* Check to see if this port is valid on this controller. */
|
||||
if (UX_HCD_STM32_NB_ROOT_PORTS < port_index)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_PORT_INDEX_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_PORT_INDEX_UNKNOWN, port_index, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_PORT_INDEX_UNKNOWN);
|
||||
}
|
||||
|
||||
/* The port is valid, build the status mask for this port. This function
|
||||
returns a controller agnostic bit field. */
|
||||
port_status = 0;
|
||||
|
||||
/* Device Connection Status. */
|
||||
if (hcd_stm32 -> ux_hcd_stm32_controller_flag & UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_ATTACHED)
|
||||
port_status |= UX_PS_CCS;
|
||||
|
||||
switch (HAL_HCD_GetCurrentSpeed(hcd_stm32 -> hcd_handle))
|
||||
{
|
||||
case 0:
|
||||
/* High Speed. */
|
||||
port_status |= UX_PS_DS_HS;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Full Speed. */
|
||||
port_status |= UX_PS_DS_FS;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Low Speed. */
|
||||
port_status |= UX_PS_DS_LS;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Full Speed. */
|
||||
port_status |= UX_PS_DS_FS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return port status. */
|
||||
return(port_status);
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_port_suspend PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will suspend a specific port attached to the root */
|
||||
/* HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_port_suspend(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
/* Return error status. */
|
||||
return(UX_FUNCTION_NOT_SUPPORTED);
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_power_down_port PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will power down a specific port attached to the */
|
||||
/* root HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_power_down_port(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
/* Return error status. */
|
||||
return(UX_FUNCTION_NOT_SUPPORTED);
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_power_on_port PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will power a specific port attached to the root HUB. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* port_index Port index */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_power_on_port(UX_HCD_STM32 *hcd_stm32, ULONG port_index)
|
||||
{
|
||||
|
||||
/* Check to see if this port is valid on this controller. On STM32, there is only one. */
|
||||
if (port_index != 0)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_PORT_INDEX_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_PORT_INDEX_UNKNOWN, port_index, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_PORT_INDEX_UNKNOWN);
|
||||
}
|
||||
|
||||
/* This function never fails. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
@ -0,0 +1,204 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_bulk_transfer PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function performs a bulk transfer request. A bulk transfer */
|
||||
/* can be larger than the size of the stm32 buffer so it may be */
|
||||
/* required to chain multiple tds to accommodate this transfer */
|
||||
/* request. A bulk transfer is non blocking, so we return before the */
|
||||
/* transfer request is completed. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_regular_td_obtain Obtain regular TD */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_request_bulk_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
UX_ENDPOINT *endpoint;
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UINT direction;
|
||||
UINT length;
|
||||
|
||||
/* Get the pointer to the Endpoint. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
/* Now get the physical ED attached to this endpoint. */
|
||||
ed = endpoint -> ux_endpoint_ed;
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
UX_DISABLE
|
||||
|
||||
/* Check if transfer is still in progress. */
|
||||
if ((ed -> ux_stm32_ed_status & UX_HCD_STM32_ED_STATUS_PENDING_MASK) >
|
||||
UX_HCD_STM32_ED_STATUS_ABORTED)
|
||||
{
|
||||
|
||||
/* Check done bit. */
|
||||
if ((ed -> ux_stm32_ed_status & UX_HCD_STM32_ED_STATUS_TRANSFER_DONE) == 0)
|
||||
{
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
}
|
||||
|
||||
/* Check status to see if it's first initialize. */
|
||||
if (transfer_request -> ux_transfer_request_status !=
|
||||
UX_TRANSFER_STATUS_NOT_PENDING)
|
||||
{
|
||||
|
||||
/* Done, modify status and notify state change. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ALLOCATED;
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
}
|
||||
|
||||
/* Maybe transfer completed but state not reported yet. */
|
||||
}
|
||||
transfer_request -> ux_transfer_request_status = UX_TRANSFER_STATUS_PENDING;
|
||||
|
||||
UX_RESTORE
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* Save the pending transfer in the ED. */
|
||||
ed -> ux_stm32_ed_transfer_request = transfer_request;
|
||||
|
||||
/* Direction, 0 : Output / 1 : Input */
|
||||
direction = ed -> ux_stm32_ed_dir;
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
if (hcd_stm32->hcd_handle->hc[ed -> ux_stm32_ed_channel].do_ssplit == 1U)
|
||||
{
|
||||
if ((direction == 0) && (transfer_request -> ux_transfer_request_requested_length > endpoint -> ux_endpoint_descriptor.wMaxPacketSize))
|
||||
{
|
||||
/* Set transfer length to MPS. */
|
||||
length = endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep the original transfer length. */
|
||||
length = transfer_request -> ux_transfer_request_requested_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* USBH_HAL_HUB_SPLIT_SUPPORTED */
|
||||
{
|
||||
|
||||
/* If DMA enabled, use max possible transfer length. */
|
||||
if (hcd_stm32 -> hcd_handle -> Init.dma_enable)
|
||||
{
|
||||
if (transfer_request -> ux_transfer_request_requested_length > endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length)
|
||||
length = endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length;
|
||||
else
|
||||
length = transfer_request -> ux_transfer_request_requested_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the direction is OUT, request size is larger than MPS, and DMA is not used, we need to set transfer length to MPS. */
|
||||
if ((direction == 0) && (transfer_request -> ux_transfer_request_requested_length > endpoint -> ux_endpoint_descriptor.wMaxPacketSize))
|
||||
{
|
||||
|
||||
/* Set transfer length to MPS. */
|
||||
length = endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Keep the original transfer length. */
|
||||
length = transfer_request -> ux_transfer_request_requested_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the transfer status in the ED. */
|
||||
ed -> ux_stm32_ed_status = direction == 0 ? UX_HCD_STM32_ED_STATUS_BULK_OUT : UX_HCD_STM32_ED_STATUS_BULK_IN;
|
||||
|
||||
/* Save the transfer length. */
|
||||
ed -> ux_stm32_ed_packet_length = length;
|
||||
|
||||
/* Prepare transactions. */
|
||||
_ux_hcd_stm32_request_trans_prepare(hcd_stm32, ed, transfer_request);
|
||||
|
||||
/* Submit the transfer request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
direction,
|
||||
EP_TYPE_BULK, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data,
|
||||
length, 0);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* Background transfer started but not done yet. */
|
||||
return(UX_STATE_WAIT);
|
||||
#else
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,543 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
static inline VOID _ux_hcd_stm32_request_control_setup(UX_HCD_STM32 *hcd_stm32,
|
||||
UX_HCD_STM32_ED *ed, UX_ENDPOINT *endpoint, UX_TRANSFER *transfer_request);
|
||||
|
||||
static inline VOID _ux_hcd_stm32_request_control_data(UX_HCD_STM32 *hcd_stm32,
|
||||
UX_HCD_STM32_ED *ed, UX_ENDPOINT *endpoint, UX_TRANSFER *transfer_request);
|
||||
|
||||
static inline VOID _ux_hcd_stm32_request_control_status(UX_HCD_STM32 *hcd_stm32,
|
||||
UX_HCD_STM32_ED *ed, UX_ENDPOINT *endpoint, UX_TRANSFER *transfer_request);
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_control_transfer PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function performs a control transfer from a transfer request. */
|
||||
/* The USB control transfer is in 3 phases (setup, data, status). */
|
||||
/* This function will chain all phases of the control sequence before */
|
||||
/* setting the stm32 endpoint as a candidate for transfer. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_regular_td_obtain Obtain regular TD */
|
||||
/* _ux_host_stack_transfer_request_abort Abort transfer request */
|
||||
/* _ux_utility_memory_allocate Allocate memory block */
|
||||
/* _ux_utility_memory_free Release memory block */
|
||||
/* _ux_utility_semaphore_get Get semaphore */
|
||||
/* _ux_utility_short_put Write 16-bit value */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* prefixed UX to MS_TO_TICK, */
|
||||
/* refined macros names, */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_request_control_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
#else
|
||||
UINT status;
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
UX_ENDPOINT *endpoint;
|
||||
UX_HCD_STM32_ED *ed;
|
||||
|
||||
/* Get the pointer to the Endpoint. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
/* Now get the physical ED attached to this endpoint. */
|
||||
ed = endpoint -> ux_endpoint_ed;
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
UX_DISABLE
|
||||
switch(ed -> ux_stm32_ed_status)
|
||||
{
|
||||
case UX_HCD_STM32_ED_STATUS_ALLOCATED:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_ABORTED:
|
||||
|
||||
/* Setup for SETUP packet. */
|
||||
_ux_hcd_stm32_request_control_setup(hcd_stm32, ed, endpoint, transfer_request);
|
||||
UX_RESTORE
|
||||
if (ed -> ux_stm32_ed_setup == UX_NULL)
|
||||
{
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_MEMORY_INSUFFICIENT;
|
||||
return(UX_STATE_ERROR);
|
||||
}
|
||||
return(UX_STATE_WAIT);
|
||||
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_SETUP | UX_HCD_STM32_ED_STATUS_TRANSFER_DONE:
|
||||
|
||||
/* Free allocated memory. */
|
||||
_ux_utility_memory_free(ed -> ux_stm32_ed_setup);
|
||||
ed -> ux_stm32_ed_setup = UX_NULL;
|
||||
|
||||
/* Restore request information. */
|
||||
transfer_request -> ux_transfer_request_requested_length =
|
||||
ed -> ux_stm32_ed_saved_length;
|
||||
transfer_request -> ux_transfer_request_actual_length = 0;
|
||||
|
||||
/* Check completion code. */
|
||||
if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
|
||||
{
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ALLOCATED;
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
}
|
||||
|
||||
if (ed -> ux_stm32_ed_saved_length)
|
||||
{
|
||||
|
||||
/* To data stage. */
|
||||
_ux_hcd_stm32_request_control_data(hcd_stm32, ed, endpoint, transfer_request);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* To status stage. */
|
||||
_ux_hcd_stm32_request_control_status(hcd_stm32, ed, endpoint, transfer_request);
|
||||
}
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_DATA_IN | UX_HCD_STM32_ED_STATUS_TRANSFER_DONE:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_DATA_OUT | UX_HCD_STM32_ED_STATUS_TRANSFER_DONE:
|
||||
|
||||
/* Check completion code. */
|
||||
if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
|
||||
{
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ALLOCATED;
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
}
|
||||
|
||||
/* Get request actual length for IN transfer. */
|
||||
if (ed -> ux_stm32_ed_dir)
|
||||
{
|
||||
|
||||
/* Get the actual transfer length. */
|
||||
transfer_request -> ux_transfer_request_actual_length =
|
||||
HAL_HCD_HC_GetXferCount(hcd_stm32 -> hcd_handle,
|
||||
ed -> ux_stm32_ed_channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* For OUT, all data is sent. */
|
||||
transfer_request -> ux_transfer_request_actual_length =
|
||||
transfer_request -> ux_transfer_request_requested_length;
|
||||
}
|
||||
|
||||
/* To status stage. */
|
||||
_ux_hcd_stm32_request_control_status(hcd_stm32, ed, endpoint, transfer_request);
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_IN | UX_HCD_STM32_ED_STATUS_TRANSFER_DONE:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_OUT | UX_HCD_STM32_ED_STATUS_TRANSFER_DONE:
|
||||
|
||||
/* All done, reset status. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ALLOCATED;
|
||||
|
||||
/* Restore saved things. */
|
||||
transfer_request -> ux_transfer_request_requested_length = ed -> ux_stm32_ed_saved_length;
|
||||
transfer_request -> ux_transfer_request_actual_length = ed -> ux_stm32_ed_saved_actual_length;
|
||||
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_SETUP:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_DATA_IN:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_DATA_OUT:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_IN:
|
||||
/* Fall through. */
|
||||
case UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_OUT:
|
||||
|
||||
/* Keep waiting. */
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
|
||||
default:
|
||||
UX_RESTORE
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_INVALID_STATE);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INVALID_STATE, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_STATE_EXIT);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Setup for SETUP packet. */
|
||||
_ux_hcd_stm32_request_control_setup(hcd_stm32, ed, endpoint, transfer_request);
|
||||
if (ed -> ux_stm32_ed_setup == UX_NULL)
|
||||
return(UX_MEMORY_INSUFFICIENT);
|
||||
|
||||
/* Wait for the completion of the transfer request. */
|
||||
status = _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT));
|
||||
|
||||
/* Free the resources. */
|
||||
_ux_utility_memory_free(ed -> ux_stm32_ed_setup);
|
||||
|
||||
/* If the semaphore did not succeed we probably have a time out. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* All transfers pending need to abort. There may have been a partial transfer. */
|
||||
_ux_host_stack_transfer_request_abort(transfer_request);
|
||||
|
||||
/* There was an error, return to the caller. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_TIMEOUT;
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_TIMEOUT, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_TRANSFER_TIMEOUT);
|
||||
}
|
||||
|
||||
/* Check the transfer request completion code. */
|
||||
if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return completion to caller. */
|
||||
return(transfer_request -> ux_transfer_request_completion_code);
|
||||
}
|
||||
|
||||
/* Check if there is data phase. */
|
||||
if (ed -> ux_stm32_ed_saved_length)
|
||||
{
|
||||
|
||||
/* Prepare data stage. */
|
||||
_ux_hcd_stm32_request_control_data(hcd_stm32, ed, endpoint, transfer_request);
|
||||
|
||||
/* Wait for the completion of the transfer request. */
|
||||
status = _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT));
|
||||
|
||||
/* If the semaphore did not succeed we probably have a time out. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* All transfers pending need to abort. There may have been a partial transfer. */
|
||||
_ux_host_stack_transfer_request_abort(transfer_request);
|
||||
|
||||
/* There was an error, return to the caller. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_TIMEOUT;
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_TIMEOUT, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_TRANSFER_TIMEOUT);
|
||||
|
||||
}
|
||||
|
||||
/* Check the transfer request completion code. */
|
||||
if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Return completion to caller. */
|
||||
return(transfer_request -> ux_transfer_request_completion_code);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare status stage. */
|
||||
_ux_hcd_stm32_request_control_status(hcd_stm32, ed, endpoint, transfer_request);
|
||||
|
||||
/* Wait for the completion of the transfer request. */
|
||||
status = _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, UX_MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT));
|
||||
|
||||
/* Restore the original transfer parameter. */
|
||||
transfer_request -> ux_transfer_request_requested_length = ed -> ux_stm32_ed_saved_length;
|
||||
transfer_request -> ux_transfer_request_actual_length = ed -> ux_stm32_ed_saved_actual_length;
|
||||
|
||||
/* If the semaphore did not succeed we probably have a time out. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* All transfers pending need to abort. There may have been a partial transfer. */
|
||||
_ux_host_stack_transfer_request_abort(transfer_request);
|
||||
|
||||
/* There was an error, return to the caller. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_TIMEOUT;
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_TIMEOUT, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
}
|
||||
|
||||
/* Return completion to caller. */
|
||||
return(transfer_request -> ux_transfer_request_completion_code);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
}
|
||||
|
||||
static inline VOID _ux_hcd_stm32_request_control_setup(UX_HCD_STM32 *hcd_stm32,
|
||||
UX_HCD_STM32_ED *ed, UX_ENDPOINT *endpoint, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
UCHAR *setup_request;
|
||||
|
||||
/* Save the pending transfer in the ED. */
|
||||
ed -> ux_stm32_ed_transfer_request = transfer_request;
|
||||
|
||||
/* Build the SETUP packet (phase 1 of the control transfer). */
|
||||
ed -> ux_stm32_ed_setup = UX_NULL;
|
||||
setup_request = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_SETUP_SIZE);
|
||||
|
||||
if (setup_request == UX_NULL)
|
||||
return;
|
||||
|
||||
ed -> ux_stm32_ed_setup = setup_request;
|
||||
|
||||
/* Build the SETUP request. */
|
||||
*(setup_request + UX_SETUP_REQUEST_TYPE) = transfer_request -> ux_transfer_request_type;
|
||||
*(setup_request + UX_SETUP_REQUEST) = transfer_request -> ux_transfer_request_function;
|
||||
_ux_utility_short_put(setup_request + UX_SETUP_VALUE, transfer_request -> ux_transfer_request_value);
|
||||
_ux_utility_short_put(setup_request + UX_SETUP_INDEX, transfer_request -> ux_transfer_request_index);
|
||||
_ux_utility_short_put(setup_request + UX_SETUP_LENGTH, (USHORT) transfer_request -> ux_transfer_request_requested_length);
|
||||
|
||||
/* Save the original transfer parameter. */
|
||||
ed -> ux_stm32_ed_saved_length = transfer_request -> ux_transfer_request_requested_length;
|
||||
ed -> ux_stm32_ed_data = setup_request;
|
||||
|
||||
/* Reset requested length for SETUP packet. */
|
||||
transfer_request -> ux_transfer_request_requested_length = 0;
|
||||
|
||||
/* Set the packet length for SETUP packet. */
|
||||
ed -> ux_stm32_ed_packet_length = 8;
|
||||
|
||||
/* Set the current status. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_CONTROL_SETUP;
|
||||
|
||||
/* Set device speed. */
|
||||
switch (endpoint -> ux_endpoint_device -> ux_device_speed)
|
||||
{
|
||||
case UX_HIGH_SPEED_DEVICE:
|
||||
ed -> ux_stm32_ed_speed = HCD_DEVICE_SPEED_HIGH;
|
||||
break;
|
||||
case UX_LOW_SPEED_DEVICE:
|
||||
ed -> ux_stm32_ed_speed = HCD_DEVICE_SPEED_LOW;
|
||||
break;
|
||||
default:
|
||||
ed -> ux_stm32_ed_speed = HCD_DEVICE_SPEED_FULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Initialize the host channel for SETUP phase. */
|
||||
ed -> ux_stm32_ed_dir = 0;
|
||||
HAL_HCD_HC_Init(hcd_stm32 -> hcd_handle,
|
||||
ed -> ux_stm32_ed_channel,
|
||||
0,
|
||||
endpoint -> ux_endpoint_device -> ux_device_address,
|
||||
ed -> ux_stm32_ed_speed,
|
||||
EP_TYPE_CTRL,
|
||||
endpoint -> ux_endpoint_descriptor.wMaxPacketSize);
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
/* Check if device connected to hub */
|
||||
if (endpoint->ux_endpoint_device->ux_device_parent != NULL)
|
||||
{
|
||||
HAL_HCD_HC_SetHubInfo(hcd_stm32->hcd_handle, ed->ux_stm32_ed_channel,
|
||||
endpoint->ux_endpoint_device->ux_device_parent->ux_device_address,
|
||||
endpoint->ux_endpoint_device->ux_device_port_location);
|
||||
}
|
||||
#endif /* USBH_HAL_HUB_SPLIT_SUPPORTED */
|
||||
|
||||
/* Send the SETUP packet. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
0, EP_TYPE_CTRL, USBH_PID_SETUP, setup_request, 8, 0);
|
||||
}
|
||||
|
||||
static inline VOID _ux_hcd_stm32_request_control_data(UX_HCD_STM32 *hcd_stm32,
|
||||
UX_HCD_STM32_ED *ed, UX_ENDPOINT *endpoint, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
/* Check the direction of the transaction. */
|
||||
if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) ==
|
||||
UX_REQUEST_IN)
|
||||
{
|
||||
|
||||
/* Re-initialize the host channel to IN direction. */
|
||||
ed -> ux_stm32_ed_dir = 1;
|
||||
HAL_HCD_HC_Init(hcd_stm32 -> hcd_handle,
|
||||
ed -> ux_stm32_ed_channel,
|
||||
0x80,
|
||||
endpoint -> ux_endpoint_device -> ux_device_address,
|
||||
ed -> ux_stm32_ed_speed,
|
||||
EP_TYPE_CTRL,
|
||||
endpoint -> ux_endpoint_descriptor.wMaxPacketSize);
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
/* Check if device connected to hub */
|
||||
if (endpoint->ux_endpoint_device->ux_device_parent != NULL)
|
||||
{
|
||||
HAL_HCD_HC_SetHubInfo(hcd_stm32->hcd_handle, ed->ux_stm32_ed_channel,
|
||||
endpoint->ux_endpoint_device->ux_device_parent->ux_device_address,
|
||||
endpoint->ux_endpoint_device->ux_device_port_location);
|
||||
}
|
||||
#endif /* USBH_HAL_HUB_SPLIT_SUPPORTED */
|
||||
|
||||
/* Set the current status to data IN. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_CONTROL_DATA_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Set the current status to data OUT. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_CONTROL_DATA_OUT;
|
||||
}
|
||||
|
||||
/* Save the pending transfer in the ED. */
|
||||
ed -> ux_stm32_ed_transfer_request = transfer_request;
|
||||
|
||||
/* Set the transfer to pending. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_STATUS_PENDING;
|
||||
|
||||
/* Restore requested length. */
|
||||
transfer_request -> ux_transfer_request_requested_length = ed -> ux_stm32_ed_saved_length;
|
||||
|
||||
/* If the direction is OUT, request size is larger than MPS, and DMA is not used, we need to set transfer length to MPS. */
|
||||
if ((ed -> ux_stm32_ed_dir == 0) &&
|
||||
(transfer_request -> ux_transfer_request_requested_length > endpoint -> ux_endpoint_descriptor.wMaxPacketSize) &&
|
||||
(hcd_stm32 -> hcd_handle -> Init.dma_enable == 0))
|
||||
{
|
||||
|
||||
/* Set transfer length to MPS. */
|
||||
ed -> ux_stm32_ed_packet_length = endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Keep the original transfer length. */
|
||||
ed -> ux_stm32_ed_packet_length = transfer_request -> ux_transfer_request_requested_length;
|
||||
}
|
||||
|
||||
/* Reset actual length. */
|
||||
transfer_request -> ux_transfer_request_actual_length = 0;
|
||||
|
||||
/* Prepare transactions. */
|
||||
_ux_hcd_stm32_request_trans_prepare(hcd_stm32, ed, transfer_request);
|
||||
|
||||
/* Submit the transfer request. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
ed -> ux_stm32_ed_dir,
|
||||
EP_TYPE_CTRL, USBH_PID_DATA,
|
||||
ed -> ux_stm32_ed_data,
|
||||
ed -> ux_stm32_ed_packet_length, 0);
|
||||
}
|
||||
|
||||
static inline VOID _ux_hcd_stm32_request_control_status(UX_HCD_STM32 *hcd_stm32,
|
||||
UX_HCD_STM32_ED *ed, UX_ENDPOINT *endpoint, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
/* Setup status phase direction. */
|
||||
ed -> ux_stm32_ed_dir = !ed -> ux_stm32_ed_dir;
|
||||
HAL_HCD_HC_Init(hcd_stm32 -> hcd_handle,
|
||||
ed -> ux_stm32_ed_channel,
|
||||
ed -> ux_stm32_ed_dir ? 0x80 : 0,
|
||||
endpoint -> ux_endpoint_device -> ux_device_address,
|
||||
ed -> ux_stm32_ed_speed,
|
||||
EP_TYPE_CTRL,
|
||||
endpoint -> ux_endpoint_descriptor.wMaxPacketSize);
|
||||
|
||||
#if defined (USBH_HAL_HUB_SPLIT_SUPPORTED)
|
||||
/* Check if device connected to hub */
|
||||
if (endpoint->ux_endpoint_device->ux_device_parent != NULL)
|
||||
{
|
||||
HAL_HCD_HC_SetHubInfo(hcd_stm32->hcd_handle, ed->ux_stm32_ed_channel,
|
||||
endpoint->ux_endpoint_device->ux_device_parent->ux_device_address,
|
||||
endpoint->ux_endpoint_device->ux_device_port_location);
|
||||
}
|
||||
#endif /* USBH_HAL_HUB_SPLIT_SUPPORTED */
|
||||
|
||||
/* Save the pending transfer in the ED. */
|
||||
ed -> ux_stm32_ed_transfer_request = transfer_request;
|
||||
|
||||
/* Set the transfer to pending. */
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_STATUS_PENDING;
|
||||
|
||||
/* Save the original transfer parameter. */
|
||||
ed -> ux_stm32_ed_saved_length = (USHORT)
|
||||
transfer_request -> ux_transfer_request_requested_length;
|
||||
transfer_request -> ux_transfer_request_requested_length = 0;
|
||||
|
||||
ed -> ux_stm32_ed_saved_actual_length = (USHORT)
|
||||
transfer_request -> ux_transfer_request_actual_length;
|
||||
transfer_request -> ux_transfer_request_actual_length = 0;
|
||||
|
||||
/* Reset the packet length. */
|
||||
ed -> ux_stm32_ed_packet_length = 0;
|
||||
|
||||
/* Set the current status to data OUT. */
|
||||
ed -> ux_stm32_ed_status = ed -> ux_stm32_ed_dir ?
|
||||
UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_IN :
|
||||
UX_HCD_STM32_ED_STATUS_CONTROL_STATUS_OUT;
|
||||
|
||||
/* Submit the request for status phase. */
|
||||
HAL_HCD_HC_SubmitRequest(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel,
|
||||
ed -> ux_stm32_ed_dir,
|
||||
EP_TYPE_CTRL, USBH_PID_DATA, 0, 0, 0);
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_periodic_transfer PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function performs an periodic transfer request. An periodic */
|
||||
/* transfer can only be as large as the MaxpacketField in the */
|
||||
/* endpoint descriptor. This was verified at the USB layer and does */
|
||||
/* not need to be reverified here. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* UX_DISABLE Disable interrupt */
|
||||
/* UX_RESTORE Restore interrupt */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* refined macros names, */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_request_periodic_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
UX_ENDPOINT *endpoint;
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UX_TRANSFER *transfer;
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Get the pointer to the Endpoint. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
/* Now get the physical ED attached to this endpoint. */
|
||||
ed = endpoint -> ux_endpoint_ed;
|
||||
|
||||
/* Disable interrupt. */
|
||||
UX_DISABLE
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* Check if transfer is still in progress. */
|
||||
if ((ed -> ux_stm32_ed_status & UX_HCD_STM32_ED_STATUS_PENDING_MASK) >
|
||||
UX_HCD_STM32_ED_STATUS_ABORTED)
|
||||
{
|
||||
|
||||
/* Check done bit. */
|
||||
if ((ed -> ux_stm32_ed_status & UX_HCD_STM32_ED_STATUS_TRANSFER_DONE) == 0)
|
||||
{
|
||||
UX_RESTORE
|
||||
return(UX_STATE_WAIT);
|
||||
}
|
||||
|
||||
/* Check status to see if it's first initialize. */
|
||||
if (transfer_request -> ux_transfer_request_status !=
|
||||
UX_TRANSFER_STATUS_NOT_PENDING)
|
||||
{
|
||||
|
||||
/* Done, modify status and notify state change. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ALLOCATED;
|
||||
UX_RESTORE
|
||||
return(UX_STATE_NEXT);
|
||||
}
|
||||
|
||||
/* Maybe transfer completed but state not reported yet. */
|
||||
}
|
||||
transfer_request -> ux_transfer_request_status = UX_TRANSFER_STATUS_PENDING;
|
||||
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* Save the transfer status in the ED. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_PERIODIC_TRANSFER;
|
||||
|
||||
/* Isochronous transfer supports transfer list. */
|
||||
if (ed -> ux_stm32_ed_transfer_request == UX_NULL)
|
||||
{
|
||||
|
||||
/* Scheduler is needed to start, and kept if interval is more than 1 SOF/uSOF. */
|
||||
ed -> ux_stm32_ed_sch_mode = 1;
|
||||
|
||||
/* Save the pending transfer in the ED. */
|
||||
ed -> ux_stm32_ed_transfer_request = transfer_request;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Link the pending transfer to list tail. */
|
||||
transfer = ed -> ux_stm32_ed_transfer_request;
|
||||
while(transfer -> ux_transfer_request_next_transfer_request != UX_NULL)
|
||||
transfer = transfer -> ux_transfer_request_next_transfer_request;
|
||||
transfer -> ux_transfer_request_next_transfer_request = transfer_request;
|
||||
}
|
||||
|
||||
/* Restore interrupt. */
|
||||
UX_RESTORE
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* Background transfer started but not done yet. */
|
||||
return(UX_STATE_WAIT);
|
||||
#else
|
||||
|
||||
/* There is no need to wake up the stm32 controller on this transfer
|
||||
since periodic transactions will be picked up when the interrupt
|
||||
tree is scanned. */
|
||||
return(UX_SUCCESS);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,99 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_trans_finish PORTABLE C */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* Finish current on going data transactions. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* ed Pointer to STM32 ED */
|
||||
/* transfer Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_memory_free Free memory */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _ux_hcd_stm32_request_trans_finish(UX_HCD_STM32 *hcd_stm32, UX_HCD_STM32_ED *ed)
|
||||
{
|
||||
UX_TRANSFER *transfer = ed -> ux_stm32_ed_transfer_request;
|
||||
|
||||
/* If there is no transfer, it's OK. */
|
||||
if (transfer == UX_NULL)
|
||||
return;
|
||||
|
||||
/* If there is no data, it's OK. */
|
||||
if (ed -> ux_stm32_ed_data == UX_NULL)
|
||||
return;
|
||||
|
||||
/* If the data is aligned, it's OK. */
|
||||
if (ed -> ux_stm32_ed_data == transfer -> ux_transfer_request_data_pointer)
|
||||
return;
|
||||
|
||||
/* If the data is IN, copy it. */
|
||||
if (ed -> ux_stm32_ed_dir)
|
||||
{
|
||||
_ux_utility_memory_copy(transfer -> ux_transfer_request_data_pointer,
|
||||
ed -> ux_stm32_ed_data,
|
||||
transfer -> ux_transfer_request_actual_length);
|
||||
}
|
||||
|
||||
/* Free the aligned memory. */
|
||||
_ux_utility_memory_free(ed -> ux_stm32_ed_data);
|
||||
ed -> ux_stm32_ed_data = UX_NULL;
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_trans_prepare PORTABLE C */
|
||||
/* 6.1.12 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* Prepare for data transactions. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* ed Pointer to STM32 ED */
|
||||
/* transfer Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_memory_allocate Allocate memory */
|
||||
/* _ux_utility_memory_copy Copy memory */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_request_trans_prepare(UX_HCD_STM32 *hcd_stm32, UX_HCD_STM32_ED *ed, UX_TRANSFER *transfer)
|
||||
{
|
||||
|
||||
/* Save transfer data pointer. */
|
||||
ed -> ux_stm32_ed_data = transfer -> ux_transfer_request_data_pointer;
|
||||
|
||||
/* If DMA not enabled, nothing to do. */
|
||||
if (!hcd_stm32 -> hcd_handle -> Init.dma_enable)
|
||||
return(UX_SUCCESS);
|
||||
|
||||
/* If there is no data, nothing to do. */
|
||||
if (transfer -> ux_transfer_request_requested_length == 0)
|
||||
return(UX_SUCCESS);
|
||||
|
||||
/* If transfer buffer aligned, nothing to do. */
|
||||
if (((ALIGN_TYPE)ed -> ux_stm32_ed_data & 0x3UL) == 0)
|
||||
return(UX_SUCCESS);
|
||||
|
||||
/* Allocate aligned data buffer for transfer. */
|
||||
ed -> ux_stm32_ed_data = _ux_utility_memory_allocate(UX_NO_ALIGN,
|
||||
UX_CACHE_SAFE_MEMORY,
|
||||
transfer -> ux_transfer_request_requested_length);
|
||||
if (ed -> ux_stm32_ed_data == UX_NULL)
|
||||
return(UX_MEMORY_INSUFFICIENT);
|
||||
|
||||
/* For data IN it's done. */
|
||||
if (ed -> ux_stm32_ed_dir)
|
||||
return(UX_SUCCESS);
|
||||
|
||||
/* For data OUT, copy buffer. */
|
||||
_ux_utility_memory_copy(ed -> ux_stm32_ed_data,
|
||||
transfer -> ux_transfer_request_data_pointer,
|
||||
transfer -> ux_transfer_request_requested_length); /* Use case of memcpy is verified. */
|
||||
|
||||
/* Done. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_transfer PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is the handler for all the transactions on the USB. */
|
||||
/* The transfer request passed as parameter contains the endpoint and */
|
||||
/* the device descriptors in addition to the type of transaction de */
|
||||
/* be executed. This function routes the transfer request to */
|
||||
/* according to the type of transfer to be executed. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to STM32 controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_request_bulk_transfer Request bulk transfer */
|
||||
/* _ux_hcd_stm32_request_control_transfer Request control */
|
||||
/* transfer */
|
||||
/* _ux_hcd_stm32_request_periodic_transfer Request periodic */
|
||||
/* transfer */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* STM32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* internal clean up, */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_request_transfer(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
UX_ENDPOINT *endpoint;
|
||||
UINT status;
|
||||
|
||||
/* Device Connection Status. */
|
||||
if (hcd_stm32 -> ux_hcd_stm32_controller_flag & UX_HCD_STM32_CONTROLLER_FLAG_DEVICE_ATTACHED)
|
||||
{
|
||||
|
||||
/* Get the pointer to the Endpoint. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
#if !defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* We reset the actual length field of the transfer request as a safety measure. */
|
||||
transfer_request -> ux_transfer_request_actual_length = 0;
|
||||
#endif /* !defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* Isolate the endpoint type and route the transfer request. */
|
||||
switch ((endpoint -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE)
|
||||
{
|
||||
|
||||
case UX_CONTROL_ENDPOINT:
|
||||
|
||||
status = _ux_hcd_stm32_request_control_transfer(hcd_stm32, transfer_request);
|
||||
break;
|
||||
|
||||
case UX_BULK_ENDPOINT:
|
||||
|
||||
status = _ux_hcd_stm32_request_bulk_transfer(hcd_stm32, transfer_request);
|
||||
break;
|
||||
|
||||
case UX_INTERRUPT_ENDPOINT:
|
||||
case UX_ISOCHRONOUS_ENDPOINT:
|
||||
|
||||
status = _ux_hcd_stm32_request_periodic_transfer(hcd_stm32, transfer_request);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
status = UX_ERROR;
|
||||
#else
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_ERROR;
|
||||
return(UX_STATE_EXIT);
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Error, no device attached. */
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
status = UX_NO_DEVICE_CONNECTED;
|
||||
#else
|
||||
transfer_request -> ux_transfer_request_completion_code = UX_NO_DEVICE_CONNECTED;
|
||||
status = UX_STATE_EXIT;
|
||||
#endif /* defined(UX_HOST_STANDALONE) */
|
||||
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
147
common/usbx_stm32_host_controllers/ux_hcd_stm32_transfer_abort.c
Normal file
147
common/usbx_stm32_host_controllers/ux_hcd_stm32_transfer_abort.c
Normal file
@ -0,0 +1,147 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Microsoft Corporation
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** USBX Component */
|
||||
/** */
|
||||
/** STM32 Controller Driver */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define UX_SOURCE_CODE
|
||||
#define UX_HCD_STM32_SOURCE_CODE
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_hcd_stm32.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _ux_hcd_stm32_transfer_abort PORTABLE C */
|
||||
/* 6.1.10 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Chaoqiong Xiao, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function will abort transactions attached to a transfer */
|
||||
/* request. */
|
||||
/* */
|
||||
/* Note since ThreadX delay is used, the function must not be used in */
|
||||
/* interrupts. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* hcd_stm32 Pointer to stm32 controller */
|
||||
/* transfer_request Pointer to transfer request */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _ux_utility_delay_ms Delay */
|
||||
/* HAL_HCD_HC_Halt Halt host channel */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* stm32 Controller Driver */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
|
||||
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone support, */
|
||||
/* resulting in version 6.1.10 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _ux_hcd_stm32_transfer_abort(UX_HCD_STM32 *hcd_stm32, UX_TRANSFER *transfer_request)
|
||||
{
|
||||
|
||||
UX_ENDPOINT *endpoint;
|
||||
UX_HCD_STM32_ED *ed;
|
||||
UX_TRANSFER *transfer;
|
||||
UX_INTERRUPT_SAVE_AREA
|
||||
|
||||
/* Get the pointer to the endpoint associated with the transfer request. */
|
||||
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
|
||||
|
||||
/* From the endpoint container, get the address of the physical endpoint. */
|
||||
ed = (UX_HCD_STM32_ED *) endpoint -> ux_endpoint_ed;
|
||||
|
||||
/* Check if this physical endpoint has been initialized properly! */
|
||||
if (ed == UX_NULL)
|
||||
{
|
||||
|
||||
/* Error trap. */
|
||||
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_ENDPOINT_HANDLE_UNKNOWN);
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, endpoint, 0, 0, UX_TRACE_ERRORS, 0, 0)
|
||||
|
||||
return(UX_ENDPOINT_HANDLE_UNKNOWN);
|
||||
}
|
||||
|
||||
UX_DISABLE
|
||||
|
||||
/* Halt the host channel. */
|
||||
HAL_HCD_HC_Halt(hcd_stm32 -> hcd_handle, ed -> ux_stm32_ed_channel);
|
||||
|
||||
/* Save the transfer status in the ED. */
|
||||
ed -> ux_stm32_ed_status = UX_HCD_STM32_ED_STATUS_ABORTED;
|
||||
|
||||
/* Finish current transfer. */
|
||||
_ux_hcd_stm32_request_trans_finish(hcd_stm32, ed);
|
||||
|
||||
/* Update the transfer status in linked transfer requests. */
|
||||
transfer = ed -> ux_stm32_ed_transfer_request;
|
||||
while(transfer)
|
||||
{
|
||||
|
||||
/* Set transfer status to aborted. */
|
||||
transfer -> ux_transfer_request_status = UX_TRANSFER_STATUS_ABORT;
|
||||
|
||||
/* Get next transfer linked. */
|
||||
transfer = transfer -> ux_transfer_request_next_transfer_request;
|
||||
}
|
||||
|
||||
/* No transfer on going. */
|
||||
ed -> ux_stm32_ed_transfer_request = UX_NULL;
|
||||
|
||||
UX_RESTORE
|
||||
|
||||
#if !defined(UX_HOST_STANDALONE)
|
||||
|
||||
/* Wait for the controller to finish the current frame processing. */
|
||||
_ux_utility_delay_ms(1);
|
||||
#else
|
||||
|
||||
/* If setup memory is not freed correct, free it. */
|
||||
if (ed -> ux_stm32_ed_setup)
|
||||
_ux_utility_memory_free(ed -> ux_stm32_ed_setup);
|
||||
#endif /* !defined(UX_HOST_STANDALONE) */
|
||||
|
||||
/* Return successful completion. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user