Merge pull request #4295 from LeeChunHei/test_branch
添加imxrt的pulse encoder和usb host驅動
This commit is contained in:
commit
d9c3459e11
|
@ -0,0 +1,813 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2020 NXP
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_OS_ABSTRACTION_H_
|
||||
#define _FSL_OS_ABSTRACTION_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_os_abstraction_config.h"
|
||||
#include "generic_list.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup osa_adapter
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Type for the Task Priority*/
|
||||
typedef uint16_t osa_task_priority_t;
|
||||
/*! @brief Type for a task handler */
|
||||
typedef void *osa_task_handle_t;
|
||||
/*! @brief Type for the parameter to be passed to the task at its creation */
|
||||
typedef void *osa_task_param_t;
|
||||
/*! @brief Type for task pointer. Task prototype declaration */
|
||||
typedef void (*osa_task_ptr_t)(osa_task_param_t task_param);
|
||||
/*! @brief Type for the semaphore handler */
|
||||
typedef void *osa_semaphore_handle_t;
|
||||
/*! @brief Type for the mutex handler */
|
||||
typedef void *osa_mutex_handle_t;
|
||||
/*! @brief Type for the event handler */
|
||||
typedef void *osa_event_handle_t;
|
||||
/*! @brief Type for an event flags group, bit 32 is reserved. */
|
||||
typedef uint32_t osa_event_flags_t;
|
||||
/*! @brief Message definition. */
|
||||
typedef void *osa_msg_handle_t;
|
||||
/*! @brief Type for the message queue handler */
|
||||
typedef void *osa_msgq_handle_t;
|
||||
/*! @brief Type for the Timer handler */
|
||||
typedef void *osa_timer_handle_t;
|
||||
/*! @brief Type for the Timer callback function pointer. */
|
||||
typedef void (*osa_timer_fct_ptr_t)(void const *argument);
|
||||
/*! @brief Thread Definition structure contains startup information of a thread.*/
|
||||
typedef struct osa_task_def_tag
|
||||
{
|
||||
osa_task_ptr_t pthread; /*!< start address of thread function*/
|
||||
uint32_t tpriority; /*!< initial thread priority*/
|
||||
uint32_t instances; /*!< maximum number of instances of that thread function*/
|
||||
uint32_t stacksize; /*!< stack size requirements in bytes; 0 is default stack size*/
|
||||
uint32_t *tstack; /*!< stack pointer*/
|
||||
void *tlink; /*!< link pointer*/
|
||||
uint8_t *tname; /*!< name pointer*/
|
||||
uint8_t useFloat; /*!< is use float*/
|
||||
} osa_task_def_t;
|
||||
/*! @brief Thread Link Definition structure .*/
|
||||
typedef struct osa_thread_link_tag
|
||||
{
|
||||
uint8_t link[12]; /*!< link*/
|
||||
osa_task_handle_t osThreadId; /*!< thread id*/
|
||||
osa_task_def_t *osThreadDefHandle; /*!< pointer of thread define handle*/
|
||||
uint32_t *osThreadStackHandle; /*!< pointer of thread stack handle*/
|
||||
} osa_thread_link_t, *osa_thread_link_handle_t;
|
||||
|
||||
/*! @brief Definition structure contains timer parameters.*/
|
||||
typedef struct osa_time_def_tag
|
||||
{
|
||||
osa_timer_fct_ptr_t pfCallback; /* < start address of a timer function */
|
||||
void *argument; /* < argument of a timer function */
|
||||
} osa_time_def_t;
|
||||
|
||||
/*! @brief Type for the timer definition*/
|
||||
typedef enum _osa_timer
|
||||
{
|
||||
KOSA_TimerOnce = 0, /*!< one-shot timer*/
|
||||
KOSA_TimerPeriodic = 1 /*!< repeating timer*/
|
||||
} osa_timer_t;
|
||||
|
||||
/*! @brief Defines the return status of OSA's functions */
|
||||
typedef enum _osa_status
|
||||
{
|
||||
KOSA_StatusSuccess = kStatus_Success, /*!< Success */
|
||||
KOSA_StatusError = MAKE_STATUS(kStatusGroup_OSA, 1), /*!< Failed */
|
||||
KOSA_StatusTimeout = MAKE_STATUS(kStatusGroup_OSA, 2), /*!< Timeout occurs while waiting */
|
||||
KOSA_StatusIdle = MAKE_STATUS(kStatusGroup_OSA, 3), /*!< Used for bare metal only, the wait object is not ready
|
||||
and timeout still not occur */
|
||||
} osa_status_t;
|
||||
|
||||
#ifdef USE_RTOS
|
||||
#undef USE_RTOS
|
||||
#endif
|
||||
|
||||
#define USE_RTOS (1)
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
#define OSA_TASK_HANDLE_SIZE (12U)
|
||||
#else
|
||||
#define OSA_TASK_HANDLE_SIZE (16U)
|
||||
#endif
|
||||
#define OSA_EVENT_HANDLE_SIZE (8U)
|
||||
#define OSA_SEM_HANDLE_SIZE (4U)
|
||||
#define OSA_MUTEX_HANDLE_SIZE (4U)
|
||||
#define OSA_MSGQ_HANDLE_SIZE (4U)
|
||||
#define OSA_MSG_HANDLE_SIZE (0U)
|
||||
|
||||
/*! @brief Priority setting for OSA. */
|
||||
#ifndef OSA_PRIORITY_IDLE
|
||||
#define OSA_PRIORITY_IDLE (6)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_PRIORITY_LOW
|
||||
#define OSA_PRIORITY_LOW (5)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_PRIORITY_BELOW_NORMAL
|
||||
#define OSA_PRIORITY_BELOW_NORMAL (4)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_PRIORITY_NORMAL
|
||||
#define OSA_PRIORITY_NORMAL (3)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_PRIORITY_ABOVE_NORMAL
|
||||
#define OSA_PRIORITY_ABOVE_NORMAL (2)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_PRIORITY_HIGH
|
||||
#define OSA_PRIORITY_HIGH (1)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_PRIORITY_REAL_TIME
|
||||
#define OSA_PRIORITY_REAL_TIME (0)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_TASK_PRIORITY_MAX
|
||||
#define OSA_TASK_PRIORITY_MAX (0)
|
||||
#endif
|
||||
|
||||
#ifndef OSA_TASK_PRIORITY_MIN
|
||||
#define OSA_TASK_PRIORITY_MIN (15)
|
||||
#endif
|
||||
|
||||
#define SIZE_IN_UINT32_UNITS(size) (((size) + sizeof(uint32_t) - 1) / sizeof(uint32_t))
|
||||
|
||||
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
|
||||
#define osaWaitForever_c ((uint32_t)(-1))
|
||||
#define osaEventFlagsAll_c ((osa_event_flags_t)(0x00FFFFFF))
|
||||
#define osThreadStackArray(name) osThread_##name##_stack
|
||||
#define osThreadStackDef(name, stacksize, instances) \
|
||||
uint32_t osThreadStackArray(name)[SIZE_IN_UINT32_UNITS(stacksize) * (instances)];
|
||||
|
||||
/* ==== Thread Management ==== */
|
||||
|
||||
/* Create a Thread Definition with function, priority, and stack requirements.
|
||||
* \param name name of the thread function.
|
||||
* \param priority initial priority of the thread function.
|
||||
* \param instances number of possible thread instances.
|
||||
* \param stackSz stack size (in bytes) requirements for the thread function.
|
||||
* \param useFloat
|
||||
*/
|
||||
#if defined(FSL_RTOS_MQX)
|
||||
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
|
||||
osa_thread_link_t osThreadLink_##name[instances] = {0}; \
|
||||
osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
|
||||
(name), (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \
|
||||
(uint8_t *)#name, (useFloat)}
|
||||
#elif defined(FSL_RTOS_UCOSII)
|
||||
#if gTaskMultipleInstancesManagement_c
|
||||
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
|
||||
osa_thread_link_t osThreadLink_##name[instances] = {0}; \
|
||||
osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
|
||||
(name), (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \
|
||||
(uint8_t *)#name, (useFloat)}
|
||||
#else
|
||||
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
|
||||
osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \
|
||||
(name), (priority), (instances), (stackSz), osThreadStackArray(name), NULL, (uint8_t *)#name, (useFloat)}
|
||||
#endif
|
||||
#else
|
||||
#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \
|
||||
osa_task_def_t os_thread_def_##name = {(name), (priority), (instances), (stackSz), \
|
||||
NULL, NULL, (uint8_t *)#name, (useFloat)}
|
||||
#endif
|
||||
/* Access a Thread defintion.
|
||||
* \param name name of the thread definition object.
|
||||
*/
|
||||
#define OSA_TASK(name) &os_thread_def_##name
|
||||
|
||||
#define OSA_TASK_PROTO(name) externosa_task_def_t os_thread_def_##name
|
||||
/* ==== Timer Management ====
|
||||
* Define a Timer object.
|
||||
* \param name name of the timer object.
|
||||
* \param function name of the timer call back function.
|
||||
*/
|
||||
|
||||
#define OSA_TIMER_DEF(name, function) osa_time_def_t os_timer_def_##name = {(function), NULL}
|
||||
|
||||
/* Access a Timer definition.
|
||||
* \param name name of the timer object.
|
||||
*/
|
||||
#define OSA_TIMER(name) &os_timer_def_##name
|
||||
|
||||
/* ==== Buffer Definition ==== */
|
||||
|
||||
/*!
|
||||
* @brief Defines the semaphore handle
|
||||
*
|
||||
* This macro is used to define a 4 byte aligned semaphore handle.
|
||||
* Then use "(osa_semaphore_handle_t)name" to get the semaphore handle.
|
||||
*
|
||||
* The macro should be global and could be optional. You could also define semaphore handle by yourself.
|
||||
*
|
||||
* This is an example,
|
||||
* @code
|
||||
* OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
|
||||
* @endcode
|
||||
*
|
||||
* @param name The name string of the semaphore handle.
|
||||
*/
|
||||
#define OSA_SEMAPHORE_HANDLE_DEFINE(name) \
|
||||
uint32_t name[(OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
|
||||
|
||||
/*!
|
||||
* @brief Defines the mutex handle
|
||||
*
|
||||
* This macro is used to define a 4 byte aligned mutex handle.
|
||||
* Then use "(osa_mutex_handle_t)name" to get the mutex handle.
|
||||
*
|
||||
* The macro should be global and could be optional. You could also define mutex handle by yourself.
|
||||
*
|
||||
* This is an example,
|
||||
* @code
|
||||
* OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
|
||||
* @endcode
|
||||
*
|
||||
* @param name The name string of the mutex handle.
|
||||
*/
|
||||
#define OSA_MUTEX_HANDLE_DEFINE(name) uint32_t name[(OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
|
||||
|
||||
/*!
|
||||
* @brief Defines the event handle
|
||||
*
|
||||
* This macro is used to define a 4 byte aligned event handle.
|
||||
* Then use "(osa_event_handle_t)name" to get the event handle.
|
||||
*
|
||||
* The macro should be global and could be optional. You could also define event handle by yourself.
|
||||
*
|
||||
* This is an example,
|
||||
* @code
|
||||
* OSA_EVENT_HANDLE_DEFINE(eventHandle);
|
||||
* @endcode
|
||||
*
|
||||
* @param name The name string of the event handle.
|
||||
*/
|
||||
#define OSA_EVENT_HANDLE_DEFINE(name) uint32_t name[(OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
|
||||
|
||||
/*!
|
||||
* @brief Defines the message queue handle
|
||||
*
|
||||
* This macro is used to define a 4 byte aligned message queue handle.
|
||||
* Then use "(osa_msgq_handle_t)name" to get the message queue handle.
|
||||
*
|
||||
* The macro should be global and could be optional. You could also define message queue handle by yourself.
|
||||
*
|
||||
* This is an example,
|
||||
* @code
|
||||
* OSA_MSGQ_HANDLE_DEFINE(msgqHandle, 3, sizeof(msgStruct));
|
||||
* @endcode
|
||||
*
|
||||
* @param name The name string of the message queue handle.
|
||||
* @param numberOfMsgs Number of messages.
|
||||
* @param msgSize Message size.
|
||||
*
|
||||
*/
|
||||
|
||||
/*< Macro For FREE_RTOS*/
|
||||
#define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \
|
||||
uint32_t name[(OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
|
||||
|
||||
/*!
|
||||
* @brief Defines the TASK handle
|
||||
*
|
||||
* This macro is used to define a 4 byte aligned TASK handle.
|
||||
* Then use "(osa_task_handle_t)name" to get the TASK handle.
|
||||
*
|
||||
* The macro should be global and could be optional. You could also define TASK handle by yourself.
|
||||
*
|
||||
* This is an example,
|
||||
* @code
|
||||
* OSA_TASK_HANDLE_DEFINE(taskHandle);
|
||||
* @endcode
|
||||
*
|
||||
* @param name The name string of the TASK handle.
|
||||
*/
|
||||
#define OSA_TASK_HANDLE_DEFINE(name) uint32_t name[(OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
|
||||
|
||||
#include "fsl_os_abstraction_rtthread.h"
|
||||
|
||||
extern const uint8_t gUseRtos_c;
|
||||
|
||||
/*
|
||||
* alloc the temporary memory to store the status
|
||||
*/
|
||||
#define OSA_SR_ALLOC() uint32_t osaCurrentSr;
|
||||
/*
|
||||
* Enter critical mode
|
||||
*/
|
||||
#define OSA_ENTER_CRITICAL() OSA_EnterCritical(&osaCurrentSr)
|
||||
/*
|
||||
* Exit critical mode and retore the previous mode
|
||||
*/
|
||||
#define OSA_EXIT_CRITICAL() OSA_ExitCritical(osaCurrentSr)
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Reserves the requested amount of memory in bytes.
|
||||
*
|
||||
* The function is used to reserve the requested amount of memory in bytes and initializes it to 0.
|
||||
*
|
||||
* @param length Amount of bytes to reserve.
|
||||
*
|
||||
* @return Pointer to the reserved memory. NULL if memory can't be allocated.
|
||||
*/
|
||||
void *OSA_MemoryAllocate(uint32_t length);
|
||||
|
||||
/*!
|
||||
* @brief Frees the memory previously reserved.
|
||||
*
|
||||
* The function is used to free the memory block previously reserved.
|
||||
*
|
||||
* @param p Pointer to the start of the memory block previously reserved.
|
||||
*
|
||||
*/
|
||||
void OSA_MemoryFree(void *p);
|
||||
|
||||
/*!
|
||||
* @brief Enter critical with nesting mode.
|
||||
*
|
||||
* @param sr Store current status and return to caller.
|
||||
*/
|
||||
void OSA_EnterCritical(uint32_t *sr);
|
||||
|
||||
/*!
|
||||
* @brief Exit critical with nesting mode.
|
||||
*
|
||||
* @param sr Previous status to restore.
|
||||
*/
|
||||
void OSA_ExitCritical(uint32_t sr);
|
||||
|
||||
/*!
|
||||
* @name Task management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Creates a task.
|
||||
*
|
||||
* This function is used to create task based on the resources defined
|
||||
* by the macro OSA_TASK_DEFINE.
|
||||
*
|
||||
* Example below shows how to use this API to create the task handle.
|
||||
* @code
|
||||
* OSA_TASK_HANDLE_DEFINE(taskHandle);
|
||||
* OSA_TASK_DEFINE( Job1, OSA_PRIORITY_HIGH, 1, 800, 0);
|
||||
* OSA_TaskCreate((osa_task_handle_t)taskHandle, OSA_TASK(Job1), (osa_task_param_t)NULL);
|
||||
* @endcode
|
||||
*
|
||||
* @param taskHandle Pointer to a memory space of size OSA_TASK_HANDLE_SIZE allocated by the caller, task handle.
|
||||
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
||||
* You can define the handle in the following two ways:
|
||||
* #OSA_TASK_HANDLE_DEFINE(taskHandle);
|
||||
* or
|
||||
* uint32_t taskHandle[((OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
||||
* @param thread_def pointer to theosa_task_def_t structure which defines the task.
|
||||
* @param task_param Pointer to be passed to the task when it is created.
|
||||
* @retval KOSA_StatusSuccess The task is successfully created.
|
||||
* @retval KOSA_StatusError The task can not be created.
|
||||
*/
|
||||
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, osa_task_def_t *thread_def, osa_task_param_t task_param);
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
||||
|
||||
/*!
|
||||
* @brief Gets the handler of active task.
|
||||
*
|
||||
* @return Handler to current active task.
|
||||
*/
|
||||
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_task_handle_t OSA_TaskGetCurrentHandle(void);
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
||||
|
||||
/*!
|
||||
* @brief Puts the active task to the end of scheduler's queue.
|
||||
*
|
||||
* When a task calls this function, it gives up the CPU and puts itself to the
|
||||
* end of a task ready list.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The function is called successfully.
|
||||
* @retval KOSA_StatusError Error occurs with this function.
|
||||
*/
|
||||
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskYield(void);
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
||||
|
||||
/*!
|
||||
* @brief Gets the priority of a task.
|
||||
*
|
||||
* @param taskHandle The handler of the task whose priority is received.
|
||||
*
|
||||
* @return Task's priority.
|
||||
*/
|
||||
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle);
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
||||
|
||||
/*!
|
||||
* @brief Sets the priority of a task.
|
||||
*
|
||||
* @param taskHandle The handler of the task whose priority is set.
|
||||
* @param taskPriority The priority to set.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess Task's priority is set successfully.
|
||||
* @retval KOSA_StatusError Task's priority can not be set.
|
||||
*/
|
||||
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority);
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
||||
|
||||
/*!
|
||||
* @brief Destroys a previously created task.
|
||||
*
|
||||
* @param taskHandle The handler of the task to destroy.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The task was successfully destroyed.
|
||||
* @retval KOSA_StatusError Task destruction failed or invalid parameter.
|
||||
*/
|
||||
#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle);
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
||||
|
||||
/*!
|
||||
* @brief Creates a semaphore with a given value.
|
||||
*
|
||||
* This function creates a semaphore and sets the value to the parameter
|
||||
* initValue.
|
||||
*
|
||||
* Example below shows how to use this API to create the semaphore handle.
|
||||
* @code
|
||||
* OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
|
||||
* OSA_SemaphoreCreate((osa_semaphore_handle_t)semaphoreHandle, 0xff);
|
||||
* @endcode
|
||||
*
|
||||
* @param semaphoreHandle Pointer to a memory space of size OSA_SEM_HANDLE_SIZE allocated by the caller.
|
||||
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
||||
* You can define the handle in the following two ways:
|
||||
* #OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle);
|
||||
* or
|
||||
* uint32_t semaphoreHandle[((OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
||||
* @param initValue Initial value the semaphore will be set to.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess the new semaphore if the semaphore is created successfully.
|
||||
* @retval KOSA_StatusError if the semaphore can not be created.
|
||||
*/
|
||||
osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue);
|
||||
|
||||
/*!
|
||||
* @brief Destroys a previously created semaphore.
|
||||
*
|
||||
* @param semaphoreHandle The semaphore handle.
|
||||
* The macro SEMAPHORE_HANDLE_BUFFER_GET is used to get the semaphore buffer pointer,
|
||||
* and should not be used before the macro SEMAPHORE_HANDLE_BUFFER_DEFINE is used.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The semaphore is successfully destroyed.
|
||||
* @retval KOSA_StatusError The semaphore can not be destroyed.
|
||||
*/
|
||||
osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle);
|
||||
|
||||
/*!
|
||||
* @brief Pending a semaphore with timeout.
|
||||
*
|
||||
* This function checks the semaphore's counting value. If it is positive,
|
||||
* decreases it and returns KOSA_StatusSuccess. Otherwise, a timeout is used
|
||||
* to wait.
|
||||
*
|
||||
* @param semaphoreHandle The semaphore handle.
|
||||
* @param millisec The maximum number of milliseconds to wait if semaphore is not
|
||||
* positive. Pass osaWaitForever_c to wait indefinitely, pass 0
|
||||
* will return KOSA_StatusTimeout immediately.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The semaphore is received.
|
||||
* @retval KOSA_StatusTimeout The semaphore is not received within the specified 'timeout'.
|
||||
* @retval KOSA_StatusError An incorrect parameter was passed.
|
||||
*/
|
||||
osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec);
|
||||
|
||||
/*!
|
||||
* @brief Signals for someone waiting on the semaphore to wake up.
|
||||
*
|
||||
* Wakes up one task that is waiting on the semaphore. If no task is waiting, increases
|
||||
* the semaphore's counting value.
|
||||
*
|
||||
* @param semaphoreHandle The semaphore handle to signal.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The semaphore is successfully signaled.
|
||||
* @retval KOSA_StatusError The object can not be signaled or invalid parameter.
|
||||
*
|
||||
*/
|
||||
osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle);
|
||||
|
||||
/*!
|
||||
* @brief Create an unlocked mutex.
|
||||
*
|
||||
* This function creates a non-recursive mutex and sets it to unlocked status.
|
||||
*
|
||||
* Example below shows how to use this API to create the mutex handle.
|
||||
* @code
|
||||
* OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
|
||||
* OSA_MutexCreate((osa_mutex_handle_t)mutexHandle);
|
||||
* @endcode
|
||||
*
|
||||
* @param mutexHandle Pointer to a memory space of size OSA_MUTEX_HANDLE_SIZE allocated by the caller.
|
||||
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
||||
* You can define the handle in the following two ways:
|
||||
* #OSA_MUTEX_HANDLE_DEFINE(mutexHandle);
|
||||
* or
|
||||
* uint32_t mutexHandle[((OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
||||
* @retval KOSA_StatusSuccess the new mutex if the mutex is created successfully.
|
||||
* @retval KOSA_StatusError if the mutex can not be created.
|
||||
*/
|
||||
osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle);
|
||||
|
||||
/*!
|
||||
* @brief Waits for a mutex and locks it.
|
||||
*
|
||||
* This function checks the mutex's status. If it is unlocked, locks it and returns the
|
||||
* KOSA_StatusSuccess. Otherwise, waits for a timeout in milliseconds to lock.
|
||||
*
|
||||
* @param mutexHandle The mutex handle.
|
||||
* @param millisec The maximum number of milliseconds to wait for the mutex.
|
||||
* If the mutex is locked, Pass the value osaWaitForever_c will
|
||||
* wait indefinitely, pass 0 will return KOSA_StatusTimeout
|
||||
* immediately.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The mutex is locked successfully.
|
||||
* @retval KOSA_StatusTimeout Timeout occurred.
|
||||
* @retval KOSA_StatusError Incorrect parameter was passed.
|
||||
*
|
||||
* @note This is non-recursive mutex, a task can not try to lock the mutex it has locked.
|
||||
*/
|
||||
osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec);
|
||||
|
||||
/*!
|
||||
* @brief Unlocks a previously locked mutex.
|
||||
*
|
||||
* @param mutexHandle The mutex handle.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The mutex is successfully unlocked.
|
||||
* @retval KOSA_StatusError The mutex can not be unlocked or invalid parameter.
|
||||
*/
|
||||
osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle);
|
||||
|
||||
/*!
|
||||
* @brief Destroys a previously created mutex.
|
||||
*
|
||||
* @param mutexHandle The mutex handle.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The mutex is successfully destroyed.
|
||||
* @retval KOSA_StatusError The mutex can not be destroyed.
|
||||
*
|
||||
*/
|
||||
osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle);
|
||||
|
||||
/*!
|
||||
* @brief Initializes an event object with all flags cleared.
|
||||
*
|
||||
* This function creates an event object and set its clear mode. If autoClear
|
||||
* is 1, when a task gets the event flags, these flags will be
|
||||
* cleared automatically. Otherwise these flags must
|
||||
* be cleared manually.
|
||||
*
|
||||
* Example below shows how to use this API to create the event handle.
|
||||
* @code
|
||||
* OSA_EVENT_HANDLE_DEFINE(eventHandle);
|
||||
* OSA_EventCreate((osa_event_handle_t)eventHandle, 0);
|
||||
* @endcode
|
||||
*
|
||||
* @param eventHandle Pointer to a memory space of size OSA_EVENT_HANDLE_SIZE allocated by the caller.
|
||||
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
||||
* You can define the handle in the following two ways:
|
||||
* #OSA_EVENT_HANDLE_DEFINE(eventHandle);
|
||||
* or
|
||||
* uint32_t eventHandle[((OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
||||
* @param autoClear 1 The event is auto-clear.
|
||||
* 0 The event manual-clear
|
||||
* @retval KOSA_StatusSuccess the new event if the event is created successfully.
|
||||
* @retval KOSA_StatusError if the event can not be created.
|
||||
*/
|
||||
osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear);
|
||||
|
||||
/*!
|
||||
* @brief Sets one or more event flags.
|
||||
*
|
||||
* Sets specified flags of an event object.
|
||||
*
|
||||
* @param eventHandle The event handle.
|
||||
* @param flagsToSet Flags to be set.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The flags were successfully set.
|
||||
* @retval KOSA_StatusError An incorrect parameter was passed.
|
||||
*/
|
||||
osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet);
|
||||
|
||||
/*!
|
||||
* @brief Clears one or more flags.
|
||||
*
|
||||
* Clears specified flags of an event object.
|
||||
*
|
||||
* @param eventHandle The event handle.
|
||||
* @param flagsToClear Flags to be clear.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The flags were successfully cleared.
|
||||
* @retval KOSA_StatusError An incorrect parameter was passed.
|
||||
*/
|
||||
osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear);
|
||||
|
||||
/*!
|
||||
* @brief Get event's flags.
|
||||
*
|
||||
* Get specified flags of an event object.
|
||||
*
|
||||
* @param eventHandle The event handle.
|
||||
* The macro EVENT_HANDLE_BUFFER_GET is used to get the event buffer pointer,
|
||||
* and should not be used before the macro EVENT_HANDLE_BUFFER_DEFINE is used.
|
||||
* @param flagsMask The flags user want to get are specified by this parameter.
|
||||
* @param pFlagsOfEvent The event flags are obtained by this parameter.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The event flags were successfully got.
|
||||
* @retval KOSA_StatusError An incorrect parameter was passed.
|
||||
*/
|
||||
osa_status_t OSA_EventGet(osa_event_handle_t eventHandle,
|
||||
osa_event_flags_t flagsMask,
|
||||
osa_event_flags_t *pFlagsOfEvent);
|
||||
|
||||
/*!
|
||||
* @brief Waits for specified event flags to be set.
|
||||
*
|
||||
* This function waits for a combination of flags to be set in an event object.
|
||||
* Applications can wait for any/all bits to be set. Also this function could
|
||||
* obtain the flags who wakeup the waiting task.
|
||||
*
|
||||
* @param eventHandle The event handle.
|
||||
* @param flagsToWait Flags that to wait.
|
||||
* @param waitAll Wait all flags or any flag to be set.
|
||||
* @param millisec The maximum number of milliseconds to wait for the event.
|
||||
* If the wait condition is not met, pass osaWaitForever_c will
|
||||
* wait indefinitely, pass 0 will return KOSA_StatusTimeout
|
||||
* immediately.
|
||||
* @param pSetFlags Flags that wakeup the waiting task are obtained by this parameter.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The wait condition met and function returns successfully.
|
||||
* @retval KOSA_StatusTimeout Has not met wait condition within timeout.
|
||||
* @retval KOSA_StatusError An incorrect parameter was passed.
|
||||
|
||||
*
|
||||
* @note Please pay attention to the flags bit width, FreeRTOS uses the most
|
||||
* significant 8 bis as control bits, so do not wait these bits while using
|
||||
* FreeRTOS.
|
||||
*
|
||||
*/
|
||||
osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
|
||||
osa_event_flags_t flagsToWait,
|
||||
uint8_t waitAll,
|
||||
uint32_t millisec,
|
||||
osa_event_flags_t *pSetFlags);
|
||||
|
||||
/*!
|
||||
* @brief Destroys a previously created event object.
|
||||
*
|
||||
* @param eventHandle The event handle.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The event is successfully destroyed.
|
||||
* @retval KOSA_StatusError Event destruction failed.
|
||||
*/
|
||||
osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle);
|
||||
|
||||
/*!
|
||||
* @brief Initializes a message queue.
|
||||
*
|
||||
* This function allocates memory for and initializes a message queue. Message queue elements are hardcoded as void*.
|
||||
*
|
||||
* Example below shows how to use this API to create the massage queue handle.
|
||||
* @code
|
||||
* OSA_MSGQ_HANDLE_DEFINE(msgqHandle);
|
||||
* OSA_MsgQCreate((osa_msgq_handle_t)msgqHandle, 5U, sizeof(msg));
|
||||
* @endcode
|
||||
*
|
||||
* @param msgqHandle Pointer to a memory space of size #(OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize) on bare-matel
|
||||
* and #(OSA_MSGQ_HANDLE_SIZE) on FreeRTOS allocated by the caller, message queue handle.
|
||||
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
||||
* You can define the handle in the following two ways:
|
||||
* #OSA_MSGQ_HANDLE_DEFINE(msgqHandle);
|
||||
* or
|
||||
* For bm: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
||||
* For freertos: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
||||
* @param msgNo :number of messages the message queue should accommodate.
|
||||
* @param msgSize :size of a single message structure.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess Message queue successfully Create.
|
||||
* @retval KOSA_StatusError Message queue create failure.
|
||||
*/
|
||||
osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize);
|
||||
|
||||
/*!
|
||||
* @brief Puts a message at the end of the queue.
|
||||
*
|
||||
* This function puts a message to the end of the message queue. If the queue
|
||||
* is full, this function returns the KOSA_StatusError;
|
||||
*
|
||||
* @param msgqHandle Message Queue handler.
|
||||
* @param pMessage Pointer to the message to be put into the queue.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess Message successfully put into the queue.
|
||||
* @retval KOSA_StatusError The queue was full or an invalid parameter was passed.
|
||||
*/
|
||||
osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage);
|
||||
|
||||
/*!
|
||||
* @brief Reads and remove a message at the head of the queue.
|
||||
*
|
||||
* This function gets a message from the head of the message queue. If the
|
||||
* queue is empty, timeout is used to wait.
|
||||
*
|
||||
* @param msgqHandle Message Queue handler.
|
||||
* @param pMessage Pointer to a memory to save the message.
|
||||
* @param millisec The number of milliseconds to wait for a message. If the
|
||||
* queue is empty, pass osaWaitForever_c will wait indefinitely,
|
||||
* pass 0 will return KOSA_StatusTimeout immediately.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess Message successfully obtained from the queue.
|
||||
* @retval KOSA_StatusTimeout The queue remains empty after timeout.
|
||||
* @retval KOSA_StatusError Invalid parameter.
|
||||
*/
|
||||
osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec);
|
||||
|
||||
/*!
|
||||
* @brief Destroys a previously created queue.
|
||||
*
|
||||
* @param msgqHandle Message Queue handler.
|
||||
*
|
||||
* @retval KOSA_StatusSuccess The queue was successfully destroyed.
|
||||
* @retval KOSA_StatusError Message queue destruction failed.
|
||||
*/
|
||||
osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle);
|
||||
|
||||
/*!
|
||||
* @brief Enable all interrupts.
|
||||
*/
|
||||
void OSA_InterruptEnable(void);
|
||||
|
||||
/*!
|
||||
* @brief Disable all interrupts.
|
||||
*/
|
||||
void OSA_InterruptDisable(void);
|
||||
|
||||
/*!
|
||||
* @brief Enable all interrupts using PRIMASK.
|
||||
*/
|
||||
void OSA_EnableIRQGlobal(void);
|
||||
|
||||
/*!
|
||||
* @brief Disable all interrupts using PRIMASK.
|
||||
*/
|
||||
void OSA_DisableIRQGlobal(void);
|
||||
|
||||
/*!
|
||||
* @brief Delays execution for a number of milliseconds.
|
||||
*
|
||||
* @param millisec The time in milliseconds to wait.
|
||||
*/
|
||||
void OSA_TimeDelay(uint32_t millisec);
|
||||
|
||||
/*!
|
||||
* @brief This function gets current time in milliseconds.
|
||||
*
|
||||
* @retval current time in milliseconds
|
||||
*/
|
||||
uint32_t OSA_TimeGetMsec(void);
|
||||
|
||||
/*!
|
||||
* @brief Installs the interrupt handler.
|
||||
*
|
||||
* @param IRQNumber IRQ number of the interrupt.
|
||||
* @param handler The interrupt handler to install.
|
||||
*/
|
||||
void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void));
|
||||
|
||||
/*! @}*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/*! @}*/
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
/*!
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_OS_ABSTRACTION_CONFIG_H_
|
||||
#define _FSL_OS_ABSTRACTION_CONFIG_H_
|
||||
|
||||
#ifndef gMainThreadStackSize_c
|
||||
#define gMainThreadStackSize_c 1024
|
||||
#endif
|
||||
|
||||
#ifndef gMainThreadPriority_c
|
||||
#define gMainThreadPriority_c 1
|
||||
#endif
|
||||
|
||||
#ifndef gTaskMultipleInstancesManagement_c
|
||||
#define gTaskMultipleInstancesManagement_c 0
|
||||
#endif
|
||||
|
||||
/*! @brief Definition to determine whether enable OSA's TASK module. */
|
||||
#ifndef OSA_USED
|
||||
#ifndef FSL_OSA_TASK_ENABLE
|
||||
#define FSL_OSA_TASK_ENABLE 0U
|
||||
#endif
|
||||
#else
|
||||
#if defined(FSL_OSA_TASK_ENABLE)
|
||||
#undef FSL_OSA_TASK_ENABLE
|
||||
#endif
|
||||
#define FSL_OSA_TASK_ENABLE 1U
|
||||
#endif /* OSA_USED */
|
||||
|
||||
#endif /* _FSL_OS_ABSTRACTION_CONFIG_H_ */
|
|
@ -0,0 +1,917 @@
|
|||
/*! *********************************************************************************
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017, 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* This is the source file for the OS Abstraction layer for freertos.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
********************************************************************************** */
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Include
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_os_abstraction.h"
|
||||
#include "fsl_os_abstraction_rtthread.h"
|
||||
#include <string.h>
|
||||
#include "generic_list.h"
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Private macros
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
|
||||
/* Weak function. */
|
||||
#if defined(__GNUC__)
|
||||
#define __WEAK_FUNC __attribute__((weak))
|
||||
#elif defined(__ICCARM__)
|
||||
#define __WEAK_FUNC __weak
|
||||
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||
#define __WEAK_FUNC __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#define millisecToTicks(millisec) (((millisec)*configTICK_RATE_HZ + 999U) / 1000U)
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
#define OS_ASSERT(condition) \
|
||||
if (!(condition)) \
|
||||
while (1) \
|
||||
;
|
||||
#else
|
||||
#define OS_ASSERT(condition) (void)(condition);
|
||||
#endif
|
||||
|
||||
/*! @brief Converts milliseconds to ticks*/
|
||||
#define MSEC_TO_TICK(msec) \
|
||||
(((uint32_t)(msec) + 500uL / (uint32_t)configTICK_RATE_HZ) * (uint32_t)configTICK_RATE_HZ / 1000uL)
|
||||
#define TICKS_TO_MSEC(tick) ((uint32_t)((uint64_t)(tick)*1000uL / (uint64_t)configTICK_RATE_HZ))
|
||||
/************************************************************************************
|
||||
*************************************************************************************
|
||||
* Private type definitions
|
||||
*************************************************************************************
|
||||
************************************************************************************/
|
||||
typedef struct osa_freertos_task
|
||||
{
|
||||
list_element_t link;
|
||||
rt_thread_t taskHandle;
|
||||
} osa_freertos_task_t;
|
||||
|
||||
typedef struct _osa_event_struct
|
||||
{
|
||||
rt_event_t handle; /* The event handle */
|
||||
uint8_t autoClear; /*!< Auto clear or manual clear */
|
||||
} osa_event_struct_t;
|
||||
|
||||
/*! @brief State structure for bm osa manager. */
|
||||
typedef struct _osa_state
|
||||
{
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
list_label_t taskList;
|
||||
OSA_TASK_HANDLE_DEFINE(mainTaskHandle);
|
||||
#endif
|
||||
uint32_t basePriority;
|
||||
int32_t basePriorityNesting;
|
||||
uint32_t interruptDisableCount;
|
||||
} osa_state_t;
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Private prototypes
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
__WEAK_FUNC void main_task(void const *argument);
|
||||
__WEAK_FUNC void main_task(void const *argument)
|
||||
{
|
||||
}
|
||||
|
||||
void startup_task(void *argument);
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Public memory declarations
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
const uint8_t gUseRtos_c = USE_RTOS; // USE_RTOS = 0 for BareMetal and 1 for OS
|
||||
|
||||
static osa_state_t s_osaState = {0};
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Private memory declarations
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Public functions
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MemoryAllocate
|
||||
* Description : Reserves the requested amount of memory in bytes.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void *OSA_MemoryAllocate(uint32_t length)
|
||||
{
|
||||
void *p = rt_malloc(length);
|
||||
|
||||
if (RT_NULL != p)
|
||||
{
|
||||
rt_memset(p, 0, length);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MemoryFree
|
||||
* Description : Frees the memory previously reserved.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_MemoryFree(void *p)
|
||||
{
|
||||
rt_free(p);
|
||||
}
|
||||
|
||||
void OSA_EnterCritical(uint32_t *sr)
|
||||
{
|
||||
if (rt_thread_self() != RT_NULL)
|
||||
rt_enter_critical();
|
||||
}
|
||||
|
||||
void OSA_ExitCritical(uint32_t sr)
|
||||
{
|
||||
if (rt_thread_self() != RT_NULL)
|
||||
rt_exit_critical();
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : startup_task
|
||||
* Description : Wrapper over main_task..
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void startup_task(void *argument)
|
||||
{
|
||||
main_task(argument);
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TaskGetCurrentHandle
|
||||
* Description : This function is used to get current active task's handler.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_task_handle_t OSA_TaskGetCurrentHandle(void)
|
||||
{
|
||||
list_element_handle_t list_element;
|
||||
osa_freertos_task_t *ptask;
|
||||
|
||||
list_element = LIST_GetHead(&s_osaState.taskList);
|
||||
while (NULL != list_element)
|
||||
{
|
||||
ptask = (osa_freertos_task_t *)(void *)list_element;
|
||||
if (ptask->taskHandle == xTaskGetCurrentTaskHandle())
|
||||
{
|
||||
return (osa_task_handle_t)ptask;
|
||||
}
|
||||
list_element = LIST_GetNext(list_element);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TaskYield
|
||||
* Description : When a task calls this function, it will give up CPU and put
|
||||
* itself to the tail of ready list.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskYield(void)
|
||||
{
|
||||
taskYIELD();
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TaskGetPriority
|
||||
* Description : This function returns task's priority by task handler.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
|
||||
{
|
||||
assert(taskHandle);
|
||||
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
||||
return (osa_task_priority_t)(PRIORITY_RTOS_TO_OSA(uxTaskPriorityGet(ptask->taskHandle)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TaskSetPriority
|
||||
* Description : This function sets task's priority by task handler.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
|
||||
{
|
||||
assert(taskHandle);
|
||||
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
||||
vTaskPrioritySet((task_handler_t)ptask->taskHandle, PRIORITY_OSA_TO_RTOS(taskPriority));
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TaskCreate
|
||||
* Description : This function is used to create a task and make it ready.
|
||||
* Param[in] : threadDef - Definition of the thread.
|
||||
* task_param - Parameter to pass to the new thread.
|
||||
* Return Thread handle of the new thread, or NULL if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, osa_task_def_t *thread_def, osa_task_param_t task_param)
|
||||
{
|
||||
assert(sizeof(osa_freertos_task_t) == OSA_TASK_HANDLE_SIZE);
|
||||
assert(taskHandle);
|
||||
TaskHandle_t pxCreatedTask;
|
||||
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
||||
|
||||
if (xTaskCreate((TaskFunction_t)thread_def->pthread, /* pointer to the task */
|
||||
(char const *)thread_def->tname, /* task name for kernel awareness debugging */
|
||||
(configSTACK_DEPTH_TYPE)thread_def->stacksize / sizeof(portSTACK_TYPE), /* task stack size */
|
||||
(task_param_t)task_param, /* optional task startup argument */
|
||||
PRIORITY_OSA_TO_RTOS(thread_def->tpriority), /* initial priority */
|
||||
&pxCreatedTask /* optional task handle to create */
|
||||
) == pdPASS)
|
||||
{
|
||||
ptask->taskHandle = pxCreatedTask;
|
||||
OSA_InterruptDisable();
|
||||
(void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
|
||||
OSA_InterruptEnable();
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TaskDestroy
|
||||
* Description : This function destroy a task.
|
||||
* Param[in] :taskHandle - Thread handle.
|
||||
* Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
|
||||
{
|
||||
assert(taskHandle);
|
||||
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
||||
osa_status_t status;
|
||||
uint16_t oldPriority;
|
||||
/*Change priority to avoid context switches*/
|
||||
oldPriority = OSA_TaskGetPriority(OSA_TaskGetCurrentHandle());
|
||||
(void)OSA_TaskSetPriority(OSA_TaskGetCurrentHandle(), OSA_PRIORITY_REAL_TIME);
|
||||
#if INCLUDE_vTaskDelete /* vTaskDelete() enabled */
|
||||
vTaskDelete((task_handler_t)ptask->taskHandle);
|
||||
status = KOSA_StatusSuccess;
|
||||
#else
|
||||
status = KOSA_StatusError; /* vTaskDelete() not available */
|
||||
#endif
|
||||
(void)OSA_TaskSetPriority(OSA_TaskGetCurrentHandle(), oldPriority);
|
||||
OSA_InterruptDisable();
|
||||
(void)LIST_RemoveElement(taskHandle);
|
||||
OSA_InterruptEnable();
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TimeDelay
|
||||
* Description : This function is used to suspend the active thread for the given number of milliseconds.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_TimeDelay(uint32_t millisec)
|
||||
{
|
||||
rt_thread_mdelay(millisec);
|
||||
}
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_TimeGetMsec
|
||||
* Description : This function gets current time in milliseconds.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
uint32_t OSA_TimeGetMsec(void)
|
||||
{
|
||||
return rt_tick_get_millisecond();
|
||||
}
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_SemaphoreCreate
|
||||
* Description : This function is used to create a semaphore.
|
||||
* Return : Semaphore handle of the new semaphore, or NULL if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
|
||||
{
|
||||
assert(sizeof(osa_semaphore_handle_t) == OSA_SEM_HANDLE_SIZE);
|
||||
assert(semaphoreHandle);
|
||||
|
||||
union
|
||||
{
|
||||
rt_sem_t sem;
|
||||
uint32_t semhandle;
|
||||
} xSemaHandle;
|
||||
|
||||
xSemaHandle.sem = rt_sem_create("osa_sem", initValue, RT_IPC_FLAG_PRIO);
|
||||
if (NULL != xSemaHandle.sem)
|
||||
{
|
||||
*(uint32_t *)semaphoreHandle = xSemaHandle.semhandle;
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_SemaphoreDestroy
|
||||
* Description : This function is used to destroy a semaphore.
|
||||
* Return : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
|
||||
{
|
||||
assert(semaphoreHandle);
|
||||
rt_sem_t sem = (rt_sem_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
|
||||
|
||||
rt_sem_delete(sem);
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_SemaphoreWait
|
||||
* Description : This function checks the semaphore's counting value, if it is
|
||||
* positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout
|
||||
* will be used for wait. The parameter timeout indicates how long should wait
|
||||
* in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will
|
||||
* return KOSA_StatusTimeout immediately if semaphore is not positive.
|
||||
* This function returns KOSA_StatusSuccess if the semaphore is received, returns
|
||||
* KOSA_StatusTimeout if the semaphore is not received within the specified
|
||||
* 'timeout', returns KOSA_StatusError if any errors occur during waiting.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
|
||||
{
|
||||
uint32_t timeoutTicks;
|
||||
assert(semaphoreHandle);
|
||||
rt_sem_t sem = (rt_sem_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
|
||||
|
||||
/* Convert timeout from millisecond to tick. */
|
||||
if (millisec == osaWaitForever_c)
|
||||
{
|
||||
timeoutTicks = RT_WAITING_FOREVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeoutTicks = rt_tick_from_millisecond(millisec);
|
||||
}
|
||||
|
||||
if (RT_EOK != rt_sem_take(sem, timeoutTicks))
|
||||
{
|
||||
return KOSA_StatusTimeout; /* timeout */
|
||||
}
|
||||
else
|
||||
{
|
||||
return KOSA_StatusSuccess; /* semaphore taken */
|
||||
}
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_SemaphorePost
|
||||
* Description : This function is used to wake up one task that wating on the
|
||||
* semaphore. If no task is waiting, increase the semaphore. The function returns
|
||||
* KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns
|
||||
* KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
|
||||
{
|
||||
assert(semaphoreHandle);
|
||||
rt_sem_t sem = (rt_sem_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
|
||||
rt_sem_release(sem);
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MutexCreate
|
||||
* Description : This function is used to create a mutex.
|
||||
* Return : Mutex handle of the new mutex, or NULL if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
|
||||
{
|
||||
assert(sizeof(osa_mutex_handle_t) == OSA_MUTEX_HANDLE_SIZE);
|
||||
assert(mutexHandle);
|
||||
|
||||
union
|
||||
{
|
||||
rt_mutex_t mutex;
|
||||
uint32_t pmutexHandle;
|
||||
} xMutexHandle;
|
||||
|
||||
xMutexHandle.mutex = rt_mutex_create("osa_mutex", RT_IPC_FLAG_PRIO);
|
||||
if (RT_NULL != xMutexHandle.mutex)
|
||||
{
|
||||
*(uint32_t *)mutexHandle = xMutexHandle.pmutexHandle;
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MutexLock
|
||||
* Description : This function checks the mutex's status, if it is unlocked,
|
||||
* lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex.
|
||||
* This function returns KOSA_StatusSuccess if the mutex is obtained, returns
|
||||
* KOSA_StatusError if any errors occur during waiting. If the mutex has been
|
||||
* locked, pass 0 as timeout will return KOSA_StatusTimeout immediately.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
|
||||
{
|
||||
assert(mutexHandle);
|
||||
uint32_t timeoutTicks;
|
||||
rt_mutex_t mutex = (rt_mutex_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
|
||||
|
||||
/* Convert timeout from millisecond to tick. */
|
||||
if (millisec == osaWaitForever_c)
|
||||
{
|
||||
timeoutTicks = RT_WAITING_FOREVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeoutTicks = rt_tick_from_millisecond(millisec);
|
||||
}
|
||||
|
||||
if (RT_EOK != rt_mutex_take(mutex, timeoutTicks))
|
||||
{
|
||||
return KOSA_StatusTimeout; /* timeout */
|
||||
}
|
||||
else
|
||||
{
|
||||
return KOSA_StatusSuccess; /* semaphore taken */
|
||||
}
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MutexUnlock
|
||||
* Description : This function is used to unlock a mutex.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
|
||||
{
|
||||
assert(mutexHandle);
|
||||
rt_mutex_t mutex = (rt_mutex_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
|
||||
rt_mutex_release(mutex);
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MutexDestroy
|
||||
* Description : This function is used to destroy a mutex.
|
||||
* Return : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
|
||||
{
|
||||
assert(mutexHandle);
|
||||
rt_mutex_t mutex = (rt_mutex_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
|
||||
|
||||
rt_mutex_delete(mutex);
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EventCreate
|
||||
* Description : This function is used to create a event object.
|
||||
* Return : Event handle of the new event, or NULL if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
|
||||
{
|
||||
assert(eventHandle);
|
||||
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
||||
|
||||
pEventStruct->handle = rt_event_create("osa_event", RT_IPC_FLAG_PRIO);
|
||||
if (RT_NULL != pEventStruct->handle)
|
||||
{
|
||||
pEventStruct->autoClear = autoClear;
|
||||
}
|
||||
else
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EventSet
|
||||
* Description : Set one or more event flags of an event object.
|
||||
* Return : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
|
||||
{
|
||||
rt_err_t result;
|
||||
assert(eventHandle);
|
||||
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
||||
|
||||
if (RT_NULL == pEventStruct->handle)
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
rt_event_send(pEventStruct->handle, (rt_uint32_t)flagsToSet);
|
||||
|
||||
(void)result;
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EventClear
|
||||
* Description : Clear one or more event flags of an event object.
|
||||
* Return :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
|
||||
{
|
||||
assert(eventHandle);
|
||||
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
||||
|
||||
if (RT_NULL == pEventStruct->handle)
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
rt_uint32_t recved;
|
||||
rt_event_recv(pEventStruct->handle, (rt_uint32_t)flagsToClear, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0, &recved);
|
||||
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EventGet
|
||||
* Description : This function is used to get event's flags that specified by prameter
|
||||
* flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So
|
||||
* you should pass the parameter 0xffffffff to specify you want to check all.
|
||||
* Return :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
|
||||
{
|
||||
assert(eventHandle);
|
||||
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
||||
rt_uint32_t eventFlags;
|
||||
|
||||
if (RT_NULL == pEventStruct->handle)
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
if (RT_NULL == pFlagsOfEvent)
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
if (RT_EOK != rt_event_recv(pEventStruct->handle, (rt_uint32_t)flagsMask, RT_EVENT_FLAG_OR, 0, &eventFlags))
|
||||
{
|
||||
eventFlags = 0;
|
||||
}
|
||||
|
||||
*pFlagsOfEvent = (osa_event_flags_t)eventFlags & flagsMask;
|
||||
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EventWait
|
||||
* Description : This function checks the event's status, if it meets the wait
|
||||
* condition, return KOSA_StatusSuccess, otherwise, timeout will be used for
|
||||
* wait. The parameter timeout indicates how long should wait in milliseconds.
|
||||
* Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value
|
||||
* KOSA_StatusTimeout immediately if wait condition is not met. The event flags
|
||||
* will be cleared if the event is auto clear mode. Flags that wakeup waiting
|
||||
* task could be obtained from the parameter setFlags.
|
||||
* This function returns KOSA_StatusSuccess if wait condition is met, returns
|
||||
* KOSA_StatusTimeout if wait condition is not met within the specified
|
||||
* 'timeout', returns KOSA_StatusError if any errors occur during waiting.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
|
||||
osa_event_flags_t flagsToWait,
|
||||
uint8_t waitAll,
|
||||
uint32_t millisec,
|
||||
osa_event_flags_t *pSetFlags)
|
||||
{
|
||||
assert(eventHandle);
|
||||
rt_uint8_t option = 0;
|
||||
rt_uint32_t timeoutTicks;
|
||||
rt_uint32_t flagsSave;
|
||||
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
||||
|
||||
/* Clean FreeRTOS cotrol flags */
|
||||
flagsToWait = flagsToWait & 0x00FFFFFFU;
|
||||
if (RT_NULL == pEventStruct->handle)
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
/* Convert timeout from millisecond to tick. */
|
||||
if (millisec == osaWaitForever_c)
|
||||
{
|
||||
timeoutTicks = RT_WAITING_FOREVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeoutTicks = rt_tick_from_millisecond(millisec);
|
||||
}
|
||||
|
||||
if (pEventStruct->autoClear != 0U)
|
||||
{
|
||||
option |= RT_EVENT_FLAG_CLEAR;
|
||||
}
|
||||
option |= waitAll ? RT_EVENT_FLAG_AND : RT_EVENT_FLAG_OR;
|
||||
|
||||
rt_err_t status = rt_event_recv(pEventStruct->handle, (rt_uint32_t)flagsToWait, option, timeoutTicks, &flagsSave);
|
||||
|
||||
flagsSave &= (rt_uint32_t)flagsToWait;
|
||||
if (RT_NULL != pSetFlags)
|
||||
{
|
||||
*pSetFlags = (osa_event_flags_t)flagsSave;
|
||||
}
|
||||
|
||||
if (RT_EOK != status)
|
||||
{
|
||||
return KOSA_StatusTimeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EventDestroy
|
||||
* Description : This function is used to destroy a event object. Return
|
||||
* KOSA_StatusSuccess if the event object is destroyed successfully, otherwise
|
||||
* return KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
|
||||
{
|
||||
assert(eventHandle);
|
||||
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
||||
|
||||
if (RT_NULL == pEventStruct->handle)
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
rt_event_delete(pEventStruct->handle);
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MsgQCreate
|
||||
* Description : This function is used to create a message queue.
|
||||
* Return : the handle to the message queue if create successfully, otherwise
|
||||
* return NULL.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize)
|
||||
{
|
||||
assert(sizeof(osa_msgq_handle_t) == OSA_MSGQ_HANDLE_SIZE);
|
||||
assert(msgqHandle);
|
||||
|
||||
union
|
||||
{
|
||||
rt_mq_t msgq;
|
||||
uint32_t pmsgqHandle;
|
||||
} xMsgqHandle;
|
||||
|
||||
/* Create the message queue where the number and size is specified by msgNo and msgSize */
|
||||
xMsgqHandle.msgq = rt_mq_create("osa_mq", msgSize, msgNo, RT_IPC_FLAG_PRIO);
|
||||
if (RT_NULL != xMsgqHandle.msgq)
|
||||
{
|
||||
*(uint32_t *)msgqHandle = xMsgqHandle.pmsgqHandle;
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MsgQPut
|
||||
* Description : This function is used to put a message to a message queue.
|
||||
* Return : KOSA_StatusSuccess if the message is put successfully, otherwise return KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage)
|
||||
{
|
||||
assert(msgqHandle);
|
||||
rt_mq_t handler = (rt_mq_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
||||
|
||||
if (RT_EOK == rt_mq_send(handler, pMessage, handler->msg_size))
|
||||
{
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
else
|
||||
{
|
||||
return KOSA_StatusError;
|
||||
}
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MsgQGet
|
||||
* Description : This function checks the queue's status, if it is not empty,
|
||||
* get message from it and return KOSA_StatusSuccess, otherwise, timeout will
|
||||
* be used for wait. The parameter timeout indicates how long should wait in
|
||||
* milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will return
|
||||
* KOSA_StatusTimeout immediately if queue is empty.
|
||||
* This function returns KOSA_StatusSuccess if message is got successfully,
|
||||
* returns KOSA_StatusTimeout if message queue is empty within the specified
|
||||
* 'timeout', returns KOSA_StatusError if any errors occur during waiting.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec)
|
||||
{
|
||||
osa_status_t osaStatus;
|
||||
assert(msgqHandle);
|
||||
rt_mq_t handler = (rt_mq_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
||||
|
||||
uint32_t timeoutTicks;
|
||||
|
||||
if (millisec == osaWaitForever_c)
|
||||
{
|
||||
timeoutTicks = RT_WAITING_FOREVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeoutTicks = rt_tick_from_millisecond(millisec);
|
||||
}
|
||||
if (RT_EOK != rt_mq_recv(handler, pMessage, handler->msg_size, timeoutTicks))
|
||||
{
|
||||
osaStatus = KOSA_StatusTimeout; /* not able to send it to the queue? */
|
||||
}
|
||||
else
|
||||
{
|
||||
osaStatus = KOSA_StatusSuccess;
|
||||
}
|
||||
return osaStatus;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_MsgQDestroy
|
||||
* Description : This function is used to destroy the message queue.
|
||||
* Return : KOSA_StatusSuccess if the message queue is destroyed successfully, otherwise return KOSA_StatusError.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)
|
||||
{
|
||||
assert(msgqHandle);
|
||||
rt_mq_t handler = (rt_mq_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
||||
|
||||
rt_mq_delete(handler);
|
||||
return KOSA_StatusSuccess;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_InterruptEnable
|
||||
* Description : self explanatory.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_InterruptEnable(void)
|
||||
{
|
||||
rt_exit_critical();
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_InterruptDisable
|
||||
* Description : self explanatory.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_InterruptDisable(void)
|
||||
{
|
||||
rt_enter_critical();
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_EnableIRQGlobal
|
||||
* Description : enable interrupts using PRIMASK register.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_EnableIRQGlobal(void)
|
||||
{
|
||||
if (s_osaState.interruptDisableCount > 0U)
|
||||
{
|
||||
s_osaState.interruptDisableCount--;
|
||||
|
||||
if (0U == s_osaState.interruptDisableCount)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
/* call core API to enable the global interrupt*/
|
||||
}
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_DisableIRQGlobal
|
||||
* Description : disable interrupts using PRIMASK register.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_DisableIRQGlobal(void)
|
||||
{
|
||||
/* call core API to disable the global interrupt*/
|
||||
__disable_irq();
|
||||
|
||||
/* update counter*/
|
||||
s_osaState.interruptDisableCount++;
|
||||
}
|
||||
|
||||
/*FUNCTION**********************************************************************
|
||||
*
|
||||
* Function Name : OSA_InstallIntHandler
|
||||
* Description : This function is used to install interrupt handler.
|
||||
*
|
||||
*END**************************************************************************/
|
||||
void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
|
||||
{
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
_Pragma("diag_suppress = Pm138")
|
||||
#endif
|
||||
#if defined(ENABLE_RAM_VECTOR_TABLE)
|
||||
(void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t) * (uint32_t *)&handler);
|
||||
#endif /* ENABLE_RAM_VECTOR_TABLE. */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
_Pragma("diag_remark = PM138")
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!*********************************************************************************
|
||||
*************************************************************************************
|
||||
* Private functions
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
||||
|
||||
static OSA_TASK_DEFINE(startup_task, gMainThreadPriority_c, 1, gMainThreadStackSize_c, 0);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
extern void BOARD_InitHardware(void);
|
||||
/* Initialize MCU clock */
|
||||
BOARD_InitHardware();
|
||||
LIST_Init((&s_osaState.taskList), 0);
|
||||
|
||||
s_osaState.basePriorityNesting = 0;
|
||||
s_osaState.interruptDisableCount = 0;
|
||||
(void)OSA_TaskCreate((osa_task_handle_t)s_osaState.mainTaskHandle, OSA_TASK(startup_task), NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
return 0;
|
||||
}
|
||||
#endif /* FSL_OSA_TASK_ENABLE */
|
|
@ -0,0 +1,130 @@
|
|||
/*! *********************************************************************************
|
||||
* Copyright (c) 2013-2014, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* ile
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
********************************************************************************** */
|
||||
#if !defined(__FSL_OS_ABSTRACTION_RTTHREAD_H__)
|
||||
#define __FSL_OS_ABSTRACTION_RTTHREAD_H__
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
/**
|
||||
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
|
||||
*/
|
||||
// http://supp.iar.com/Support/?note=24725
|
||||
|
||||
#define MISRAC_DISABLE \
|
||||
_Pragma( \
|
||||
"diag_suppress= \
|
||||
Pm001,Pm002,Pm003,Pm004,Pm005,Pm006,Pm007,Pm008,Pm009,Pm010,Pm011,\
|
||||
Pm012,Pm013,Pm014,Pm015,Pm016,Pm017,Pm018,Pm019,Pm020,Pm021,Pm022,\
|
||||
Pm023,Pm024,Pm025,Pm026,Pm027,Pm028,Pm029,Pm030,Pm031,Pm032,Pm033,\
|
||||
Pm034,Pm035,Pm036,Pm037,Pm038,Pm039,Pm040,Pm041,Pm042,Pm043,Pm044,\
|
||||
Pm045,Pm046,Pm047,Pm048,Pm049,Pm050,Pm051,Pm052,Pm053,Pm054,Pm055,\
|
||||
Pm056,Pm057,Pm058,Pm059,Pm060,Pm061,Pm062,Pm063,Pm064,Pm065,Pm066,\
|
||||
Pm067,Pm068,Pm069,Pm070,Pm071,Pm072,Pm073,Pm074,Pm075,Pm076,Pm077,\
|
||||
Pm078,Pm079,Pm080,Pm081,Pm082,Pm083,Pm084,Pm085,Pm086,Pm087,Pm088,\
|
||||
Pm089,Pm090,Pm091,Pm092,Pm093,Pm094,Pm095,Pm096,Pm097,Pm098,Pm099,\
|
||||
Pm100,Pm101,Pm102,Pm103,Pm104,Pm105,Pm106,Pm107,Pm108,Pm109,Pm110,\
|
||||
Pm111,Pm112,Pm113,Pm114,Pm115,Pm116,Pm117,Pm118,Pm119,Pm120,Pm121,\
|
||||
Pm122,Pm123,Pm124,Pm125,Pm126,Pm127,Pm128,Pm129,Pm130,Pm131,Pm132,\
|
||||
Pm133,Pm134,Pm135,Pm136,Pm137,Pm138,Pm139,Pm140,Pm141,Pm142,Pm143,\
|
||||
Pm144,Pm145,Pm146,Pm147,Pm148,Pm149,Pm150,Pm151,Pm152,Pm153,Pm154,\
|
||||
Pm155")
|
||||
|
||||
#define MISRAC_ENABLE \
|
||||
_Pragma( \
|
||||
"diag_default= \
|
||||
Pm001,Pm002,Pm003,Pm004,Pm005,Pm006,Pm007,Pm008,Pm009,Pm010,Pm011,\
|
||||
Pm012,Pm013,Pm014,Pm015,Pm016,Pm017,Pm018,Pm019,Pm020,Pm021,Pm022,\
|
||||
Pm023,Pm024,Pm025,Pm026,Pm027,Pm028,Pm029,Pm030,Pm031,Pm032,Pm033,\
|
||||
Pm034,Pm035,Pm036,Pm037,Pm038,Pm039,Pm040,Pm041,Pm042,Pm043,Pm044,\
|
||||
Pm045,Pm046,Pm047,Pm048,Pm049,Pm050,Pm051,Pm052,Pm053,Pm054,Pm055,\
|
||||
Pm056,Pm057,Pm058,Pm059,Pm060,Pm061,Pm062,Pm063,Pm064,Pm065,Pm066,\
|
||||
Pm067,Pm068,Pm069,Pm070,Pm071,Pm072,Pm073,Pm074,Pm075,Pm076,Pm077,\
|
||||
Pm078,Pm079,Pm080,Pm081,Pm082,Pm083,Pm084,Pm085,Pm086,Pm087,Pm088,\
|
||||
Pm089,Pm090,Pm091,Pm092,Pm093,Pm094,Pm095,Pm096,Pm097,Pm098,Pm099,\
|
||||
Pm100,Pm101,Pm102,Pm103,Pm104,Pm105,Pm106,Pm107,Pm108,Pm109,Pm110,\
|
||||
Pm111,Pm112,Pm113,Pm114,Pm115,Pm116,Pm117,Pm118,Pm119,Pm120,Pm121,\
|
||||
Pm122,Pm123,Pm124,Pm125,Pm126,Pm127,Pm128,Pm129,Pm130,Pm131,Pm132,\
|
||||
Pm133,Pm134,Pm135,Pm136,Pm137,Pm138,Pm139,Pm140,Pm141,Pm142,Pm143,\
|
||||
Pm144,Pm145,Pm146,Pm147,Pm148,Pm149,Pm150,Pm151,Pm152,Pm153,Pm154,\
|
||||
Pm155")
|
||||
#else
|
||||
/* Empty MISRA C macros for other toolchains. */
|
||||
#define MISRAC_DISABLE
|
||||
#define MISRAC_ENABLE
|
||||
#endif
|
||||
|
||||
MISRAC_DISABLE
|
||||
#include <rtthread.h>
|
||||
MISRAC_ENABLE
|
||||
|
||||
/*!
|
||||
* @addtogroup os_abstraction_free_rtos
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Declarations
|
||||
******************************************************************************/
|
||||
/*! @brief Type for a task handler, returned by the OSA_TaskCreate function. */
|
||||
typedef rt_thread_t task_handler_t;
|
||||
|
||||
/*! @brief Type for a task stack.*/
|
||||
typedef rt_uint32_t task_stack_t;
|
||||
|
||||
/*! @brief Type for task parameter */
|
||||
typedef void *task_param_t;
|
||||
|
||||
/*! @brief Type for an event flags object.*/
|
||||
typedef rt_uint32_t event_flags_t;
|
||||
|
||||
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
|
||||
#define OSA_WAIT_FOREVER 0xFFFFFFFFU
|
||||
|
||||
/*! @brief OSA's time range in millisecond, OSA time wraps if exceeds this value. */
|
||||
#define FSL_OSA_TIME_RANGE 0xFFFFFFFFU
|
||||
|
||||
/*! @brief The default interrupt handler installed in vector table. */
|
||||
#define OSA_DEFAULT_INT_HANDLER ((osa_int_handler_t)(&DefaultISR))
|
||||
|
||||
extern void DefaultISR(void);
|
||||
|
||||
/*!
|
||||
* @name Thread management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief To provide unified task piority for upper layer, OSA layer makes conversion.
|
||||
*/
|
||||
#define PRIORITY_OSA_TO_RTOS(osa_prio) ((UBaseType_t)configMAX_PRIORITIES - (osa_prio)-2U)
|
||||
#define PRIORITY_RTOS_TO_OSA(rtos_prio) ((UBaseType_t)configMAX_PRIORITIES - (rtos_prio)-2U)
|
||||
|
||||
/* @}*/
|
||||
|
||||
/*!
|
||||
* @name Message queues
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief This macro statically reserves the memory required for the queue.
|
||||
*
|
||||
* @param name Identifier for the memory region.
|
||||
* @param number Number of elements in the queue.
|
||||
* @param size Size of every elements in words.
|
||||
*/
|
||||
#define MSG_QUEUE_DECLARE(name, number, size) msg_queue_t *name = NULL
|
||||
|
||||
/* @}*/
|
||||
|
||||
/*! @}*/
|
||||
/*! @}*/
|
||||
/*! @}*/
|
||||
|
||||
#endif // __FSL_OS_ABSTRACTION_RTTHREAD_H__
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Copyright 2018-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Include
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
#include "generic_list.h"
|
||||
|
||||
static list_status_t LIST_Error_Check(list_handle_t list, list_element_handle_t newElement)
|
||||
{
|
||||
list_status_t listStatus = kLIST_Ok;
|
||||
list_element_handle_t element = list->head;
|
||||
|
||||
if ((list->max != 0U) && (list->max == list->size))
|
||||
{
|
||||
listStatus = kLIST_Full; /*List is full*/
|
||||
}
|
||||
else
|
||||
{
|
||||
while (element != NULL) /*Scan list*/
|
||||
{
|
||||
/* Determine if element is duplicated */
|
||||
if (element == newElement)
|
||||
{
|
||||
listStatus = kLIST_DuplicateError;
|
||||
break;
|
||||
}
|
||||
element = element->next;
|
||||
}
|
||||
}
|
||||
|
||||
return listStatus;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Public functions
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
/*! *********************************************************************************
|
||||
* \brief Initialises the list descriptor.
|
||||
*
|
||||
* \param[in] list - LIST_ handle to init.
|
||||
* max - Maximum number of elements in list. 0 for unlimited.
|
||||
*
|
||||
* \return void.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
void LIST_Init(list_handle_t list, uint32_t max)
|
||||
{
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->max = (uint16_t)max;
|
||||
list->size = 0;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Gets the list that contains the given element.
|
||||
*
|
||||
* \param[in] element - Handle of the element.
|
||||
*
|
||||
* \return NULL if element is orphan.
|
||||
* Handle of the list the element is inserted into.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_handle_t LIST_GetList(list_element_handle_t element)
|
||||
{
|
||||
return element->list;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Links element to the tail of the list.
|
||||
*
|
||||
* \param[in] list - ID of list to insert into.
|
||||
* element - element to add
|
||||
*
|
||||
* \return kLIST_Full if list is full.
|
||||
* kLIST_Ok if insertion was successful.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element)
|
||||
{
|
||||
uint32_t regPrimask = DisableGlobalIRQ();
|
||||
list_status_t listStatus = kLIST_Ok;
|
||||
|
||||
listStatus = LIST_Error_Check(list, element);
|
||||
if (listStatus == kLIST_Ok) /* Avoiding list status error */
|
||||
{
|
||||
if (list->size == 0U)
|
||||
{
|
||||
list->head = element;
|
||||
}
|
||||
else
|
||||
{
|
||||
list->tail->next = element;
|
||||
}
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
#else
|
||||
element->prev = list->tail;
|
||||
#endif
|
||||
element->list = list;
|
||||
element->next = NULL;
|
||||
list->tail = element;
|
||||
list->size++;
|
||||
}
|
||||
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
return listStatus;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Links element to the head of the list.
|
||||
*
|
||||
* \param[in] list - ID of list to insert into.
|
||||
* element - element to add
|
||||
*
|
||||
* \return kLIST_Full if list is full.
|
||||
* kLIST_Ok if insertion was successful.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element)
|
||||
{
|
||||
uint32_t regPrimask = DisableGlobalIRQ();
|
||||
list_status_t listStatus = kLIST_Ok;
|
||||
|
||||
listStatus = LIST_Error_Check(list, element);
|
||||
if (listStatus == kLIST_Ok) /* Avoiding list status error */
|
||||
{
|
||||
/* Links element to the head of the list */
|
||||
if (list->size == 0U)
|
||||
{
|
||||
list->tail = element;
|
||||
}
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
#else
|
||||
else
|
||||
{
|
||||
list->head->prev = element;
|
||||
}
|
||||
element->prev = NULL;
|
||||
#endif
|
||||
element->list = list;
|
||||
element->next = list->head;
|
||||
list->head = element;
|
||||
list->size++;
|
||||
}
|
||||
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
return listStatus;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Unlinks element from the head of the list.
|
||||
*
|
||||
* \param[in] list - ID of list to remove from.
|
||||
*
|
||||
* \return NULL if list is empty.
|
||||
* ID of removed element(pointer) if removal was successful.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_element_handle_t LIST_RemoveHead(list_handle_t list)
|
||||
{
|
||||
list_element_handle_t element;
|
||||
|
||||
uint32_t regPrimask = DisableGlobalIRQ();
|
||||
|
||||
if ((NULL == list) || (list->size == 0U))
|
||||
{
|
||||
element = NULL; /*LIST_ is empty*/
|
||||
}
|
||||
else
|
||||
{
|
||||
element = list->head;
|
||||
list->size--;
|
||||
if (list->size == 0U)
|
||||
{
|
||||
list->tail = NULL;
|
||||
}
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
#else
|
||||
else
|
||||
{
|
||||
element->next->prev = NULL;
|
||||
}
|
||||
#endif
|
||||
element->list = NULL;
|
||||
list->head = element->next; /*Is NULL if element is head*/
|
||||
}
|
||||
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
return element;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Gets head element ID.
|
||||
*
|
||||
* \param[in] list - ID of list.
|
||||
*
|
||||
* \return NULL if list is empty.
|
||||
* ID of head element if list is not empty.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_element_handle_t LIST_GetHead(list_handle_t list)
|
||||
{
|
||||
return list->head;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Gets next element ID.
|
||||
*
|
||||
* \param[in] element - ID of the element.
|
||||
*
|
||||
* \return NULL if element is tail.
|
||||
* ID of next element if exists.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_element_handle_t LIST_GetNext(list_element_handle_t element)
|
||||
{
|
||||
return element->next;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Gets previous element ID.
|
||||
*
|
||||
* \param[in] element - ID of the element.
|
||||
*
|
||||
* \return NULL if element is head.
|
||||
* ID of previous element if exists.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_element_handle_t LIST_GetPrev(list_element_handle_t element)
|
||||
{
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
return NULL;
|
||||
#else
|
||||
return element->prev;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Unlinks an element from its list.
|
||||
*
|
||||
* \param[in] element - ID of the element to remove.
|
||||
*
|
||||
* \return kLIST_OrphanElement if element is not part of any list.
|
||||
* kLIST_Ok if removal was successful.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_status_t LIST_RemoveElement(list_element_handle_t element)
|
||||
{
|
||||
list_status_t listStatus = kLIST_Ok;
|
||||
uint32_t regPrimask = DisableGlobalIRQ();
|
||||
|
||||
if (element->list == NULL)
|
||||
{
|
||||
listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
list_element_handle_t element_list = element->list->head;
|
||||
while (element_list)
|
||||
{
|
||||
if (element->list->head == element)
|
||||
{
|
||||
element->list->head = element_list->next;
|
||||
break;
|
||||
}
|
||||
if (element_list->next == element)
|
||||
{
|
||||
element_list->next = element->next;
|
||||
break;
|
||||
}
|
||||
element_list = element_list->next;
|
||||
}
|
||||
#else
|
||||
if (element->prev == NULL) /*Element is head or solo*/
|
||||
{
|
||||
element->list->head = element->next; /*is null if solo*/
|
||||
}
|
||||
if (element->next == NULL) /*Element is tail or solo*/
|
||||
{
|
||||
element->list->tail = element->prev; /*is null if solo*/
|
||||
}
|
||||
if (element->prev != NULL) /*Element is not head*/
|
||||
{
|
||||
element->prev->next = element->next;
|
||||
}
|
||||
if (element->next != NULL) /*Element is not tail*/
|
||||
{
|
||||
element->next->prev = element->prev;
|
||||
}
|
||||
#endif
|
||||
element->list->size--;
|
||||
element->list = NULL;
|
||||
}
|
||||
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
return listStatus;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Links an element in the previous position relative to a given member
|
||||
* of a list.
|
||||
*
|
||||
* \param[in] element - ID of a member of a list.
|
||||
* newElement - new element to insert before the given member.
|
||||
*
|
||||
* \return kLIST_OrphanElement if element is not part of any list.
|
||||
* kLIST_Full if list is full.
|
||||
* kLIST_Ok if insertion was successful.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement)
|
||||
{
|
||||
list_status_t listStatus = kLIST_Ok;
|
||||
uint32_t regPrimask = DisableGlobalIRQ();
|
||||
|
||||
if (element->list == NULL)
|
||||
{
|
||||
listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/
|
||||
}
|
||||
else
|
||||
{
|
||||
listStatus = LIST_Error_Check(element->list, newElement);
|
||||
if (listStatus == kLIST_Ok)
|
||||
{
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
list_element_handle_t element_list = element->list->head;
|
||||
while (element_list)
|
||||
{
|
||||
if ((element_list->next == element) || (element_list == element))
|
||||
{
|
||||
if (element_list == element)
|
||||
{
|
||||
element->list->head = newElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
element_list->next = newElement;
|
||||
}
|
||||
newElement->list = element->list;
|
||||
newElement->next = element;
|
||||
element->list->size++;
|
||||
break;
|
||||
}
|
||||
element_list = element_list->next;
|
||||
}
|
||||
|
||||
#else
|
||||
if (element->prev == NULL) /*Element is list head*/
|
||||
{
|
||||
element->list->head = newElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
element->prev->next = newElement;
|
||||
}
|
||||
newElement->list = element->list;
|
||||
element->list->size++;
|
||||
newElement->next = element;
|
||||
newElement->prev = element->prev;
|
||||
element->prev = newElement;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
EnableGlobalIRQ(regPrimask);
|
||||
return listStatus;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Gets the current size of a list.
|
||||
*
|
||||
* \param[in] list - ID of the list.
|
||||
*
|
||||
* \return Current size of the list.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
uint32_t LIST_GetSize(list_handle_t list)
|
||||
{
|
||||
return list->size;
|
||||
}
|
||||
|
||||
/*! *********************************************************************************
|
||||
* \brief Gets the number of free places in the list.
|
||||
*
|
||||
* \param[in] list - ID of the list.
|
||||
*
|
||||
* \return Available size of the list.
|
||||
*
|
||||
* \pre
|
||||
*
|
||||
* \post
|
||||
*
|
||||
* \remarks
|
||||
*
|
||||
********************************************************************************** */
|
||||
uint32_t LIST_GetAvailableSize(list_handle_t list)
|
||||
{
|
||||
return ((uint32_t)list->max - (uint32_t)list->size); /*Gets the number of free places in the list*/
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright 2018-2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _GENERIC_LIST_H_
|
||||
#define _GENERIC_LIST_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
/*!
|
||||
* @addtogroup GenericList
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!*********************************************************************************
|
||||
*************************************************************************************
|
||||
* Include
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Public macro definitions
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
#ifndef GENERIC_LIST_LIGHT
|
||||
#define GENERIC_LIST_LIGHT (0)
|
||||
#endif
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Public type definitions
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
/*! @brief The list status */
|
||||
typedef enum _list_status
|
||||
{
|
||||
kLIST_Ok = kStatus_Success, /*!< Success */
|
||||
kLIST_DuplicateError = MAKE_STATUS(kStatusGroup_LIST, 1), /*!< Duplicate Error */
|
||||
kLIST_Full = MAKE_STATUS(kStatusGroup_LIST, 2), /*!< FULL */
|
||||
kLIST_Empty = MAKE_STATUS(kStatusGroup_LIST, 3), /*!< Empty */
|
||||
kLIST_OrphanElement = MAKE_STATUS(kStatusGroup_LIST, 4), /*!< Orphan Element */
|
||||
kLIST_NotSupport = MAKE_STATUS(kStatusGroup_LIST, 5), /*!< Not Support */
|
||||
} list_status_t;
|
||||
|
||||
/*! @brief The list structure*/
|
||||
typedef struct list_label
|
||||
{
|
||||
struct list_element_tag *head; /*!< list head */
|
||||
struct list_element_tag *tail; /*!< list tail */
|
||||
uint16_t size; /*!< list size */
|
||||
uint16_t max; /*!< list max number of elements */
|
||||
} list_label_t, *list_handle_t;
|
||||
#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
|
||||
/*! @brief The list element*/
|
||||
typedef struct list_element_tag
|
||||
{
|
||||
struct list_element_tag *next; /*!< next list element */
|
||||
struct list_label *list; /*!< pointer to the list */
|
||||
} list_element_t, *list_element_handle_t;
|
||||
#else
|
||||
/*! @brief The list element*/
|
||||
typedef struct list_element_tag
|
||||
{
|
||||
struct list_element_tag *next; /*!< next list element */
|
||||
struct list_element_tag *prev; /*!< previous list element */
|
||||
struct list_label *list; /*!< pointer to the list */
|
||||
} list_element_t, *list_element_handle_t;
|
||||
#endif
|
||||
/*! *********************************************************************************
|
||||
*************************************************************************************
|
||||
* Public prototypes
|
||||
*************************************************************************************
|
||||
********************************************************************************** */
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* _cplusplus */
|
||||
/*!
|
||||
* @brief Initialize the list.
|
||||
*
|
||||
* This function initialize the list.
|
||||
*
|
||||
* @param list - List handle to initialize.
|
||||
* @param max - Maximum number of elements in list. 0 for unlimited.
|
||||
*/
|
||||
void LIST_Init(list_handle_t list, uint32_t max);
|
||||
|
||||
/*!
|
||||
* @brief Gets the list that contains the given element.
|
||||
*
|
||||
*
|
||||
* @param element - Handle of the element.
|
||||
* @retval NULL if element is orphan, Handle of the list the element is inserted into.
|
||||
*/
|
||||
list_handle_t LIST_GetList(list_element_handle_t element);
|
||||
|
||||
/*!
|
||||
* @brief Links element to the head of the list.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
* @param element - Handle of the element.
|
||||
* @retval kLIST_Full if list is full, kLIST_Ok if insertion was successful.
|
||||
*/
|
||||
list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element);
|
||||
|
||||
/*!
|
||||
* @brief Links element to the tail of the list.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
* @param element - Handle of the element.
|
||||
* @retval kLIST_Full if list is full, kLIST_Ok if insertion was successful.
|
||||
*/
|
||||
list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element);
|
||||
|
||||
/*!
|
||||
* @brief Unlinks element from the head of the list.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
*
|
||||
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
|
||||
*/
|
||||
list_element_handle_t LIST_RemoveHead(list_handle_t list);
|
||||
|
||||
/*!
|
||||
* @brief Gets head element handle.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
*
|
||||
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
|
||||
*/
|
||||
list_element_handle_t LIST_GetHead(list_handle_t list);
|
||||
|
||||
/*!
|
||||
* @brief Gets next element handle for given element handle.
|
||||
*
|
||||
* @param element - Handle of the element.
|
||||
*
|
||||
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
|
||||
*/
|
||||
list_element_handle_t LIST_GetNext(list_element_handle_t element);
|
||||
|
||||
/*!
|
||||
* @brief Gets previous element handle for given element handle.
|
||||
*
|
||||
* @param element - Handle of the element.
|
||||
*
|
||||
* @retval NULL if list is empty, handle of removed element(pointer) if removal was successful.
|
||||
*/
|
||||
list_element_handle_t LIST_GetPrev(list_element_handle_t element);
|
||||
|
||||
/*!
|
||||
* @brief Unlinks an element from its list.
|
||||
*
|
||||
* @param element - Handle of the element.
|
||||
*
|
||||
* @retval kLIST_OrphanElement if element is not part of any list.
|
||||
* @retval kLIST_Ok if removal was successful.
|
||||
*/
|
||||
list_status_t LIST_RemoveElement(list_element_handle_t element);
|
||||
|
||||
/*!
|
||||
* @brief Links an element in the previous position relative to a given member of a list.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
* @param element - Handle of the element.
|
||||
* @param newElement - New element to insert before the given member.
|
||||
*
|
||||
* @retval kLIST_OrphanElement if element is not part of any list.
|
||||
* @retval kLIST_Ok if removal was successful.
|
||||
*/
|
||||
list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement);
|
||||
|
||||
/*!
|
||||
* @brief Gets the current size of a list.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
*
|
||||
* @retval Current size of the list.
|
||||
*/
|
||||
uint32_t LIST_GetSize(list_handle_t list);
|
||||
|
||||
/*!
|
||||
* @brief Gets the number of free places in the list.
|
||||
*
|
||||
* @param list - Handle of the list.
|
||||
*
|
||||
* @retval Available size of the list.
|
||||
*/
|
||||
uint32_t LIST_GetAvailableSize(list_handle_t list);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*! @}*/
|
||||
#endif /*_GENERIC_LIST_H_*/
|
|
@ -367,7 +367,6 @@ Reset_Handler:
|
|||
blt .LC4
|
||||
#endif /* __STARTUP_INITIALIZE_NONCACHEDATA */
|
||||
|
||||
#ifdef __STARTUP_CLEAR_BSS
|
||||
/* This part of work usually is done in C library startup code. Otherwise,
|
||||
* define this macro to enable it in this startup.
|
||||
*
|
||||
|
@ -385,7 +384,6 @@ Reset_Handler:
|
|||
itt lt
|
||||
strlt r0, [r1], #4
|
||||
blt .LC5
|
||||
#endif /* __STARTUP_CLEAR_BSS */
|
||||
|
||||
cpsie i /* Unmask interrupts */
|
||||
#ifndef __START
|
||||
|
|
|
@ -53,9 +53,6 @@ if GetDepend(['BSP_USING_SDRAM']):
|
|||
if GetDepend(['BSP_USING_LCD']):
|
||||
src += ['MIMXRT1052/drivers/fsl_elcdif.c']
|
||||
|
||||
if GetDepend(['RT_USING_USB_HOST']) or GetDepend(['RT_USING_USB_DEVICE']):
|
||||
src += ['MIMXRT1052/drivers/fsl_usdhc.c']
|
||||
|
||||
if GetDepend(['BSP_USING_CAN']):
|
||||
src += ['MIMXRT1052/drivers/fsl_flexcan.c']
|
||||
|
||||
|
@ -77,7 +74,17 @@ if GetDepend(['BSP_USING_DMA']):
|
|||
src += ['MIMXRT1052/drivers/fsl_edma.c']
|
||||
src += ['MIMXRT1052/drivers/fsl_lpuart_edma.c']
|
||||
src += ['MIMXRT1052/drivers/fsl_lpspi_edma.c']
|
||||
|
||||
if GetDepend(['BSP_USING_PULSE_ENCODER']):
|
||||
src += ['MIMXRT1052/drivers/fsl_enc.c']
|
||||
|
||||
#Adding this as XBAR is used in pin mux
|
||||
src += ['MIMXRT1052/drivers/fsl_xbara.c']
|
||||
src += ['MIMXRT1052/drivers/fsl_xbarb.c']
|
||||
|
||||
#fsl os abstract files
|
||||
src += ['MIMXRT1052/drivers/fsl_os_abstraction_rtthread.c']
|
||||
src += ['MIMXRT1052/drivers/generic_list.c']
|
||||
|
||||
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path)
|
||||
|
||||
|
|
|
@ -54,15 +54,22 @@ if GetDepend('BSP_USING_AUDIO'):
|
|||
|
||||
if GetDepend('BSP_USING_SDIO'):
|
||||
src += ['drv_sdio.c']
|
||||
|
||||
if GetDepend('BSP_USING_USB_DEVICE'):
|
||||
|
||||
if GetDepend('BSP_USING_PULSE_ENCODER'):
|
||||
src += ['drv_pulse_encoder.c']
|
||||
|
||||
if GetDepend('RT_USING_USB_DEVICE'):
|
||||
src += ['drv_usbd.c']
|
||||
src += Glob('usb/device/*.c')
|
||||
|
||||
if GetDepend('BSP_USING_USB_DEVICE'):
|
||||
if GetDepend('RT_USING_USB_DEVICE') or GetDepend('RT_USING_USB_HOST'):
|
||||
src += Glob('usb/phy/*.c')
|
||||
CPPDEFINES += ['ENDIANNESS']
|
||||
CPPDEFINES += ['ENDIANNESS','USE_RTOS']
|
||||
|
||||
if GetDepend('RT_USING_USB_HOST'):
|
||||
src += ['drv_usbh.c']
|
||||
src += Glob('usb/host/*.c')
|
||||
|
||||
path = [cwd,cwd + '/config']
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES=CPPDEFINES)
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-08-23 balanceTWK first version
|
||||
* 2021-01-19 Leslie Lee port to imxrt series
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#ifdef BSP_USING_PULSE_ENCODER
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_enc.h"
|
||||
|
||||
#define LOG_TAG "drv.pulse_encoder"
|
||||
#include <drv_log.h>
|
||||
|
||||
#if !defined(BSP_USING_PULSE_ENCODER1) && !defined(BSP_USING_PULSE_ENCODER2) && !defined(BSP_USING_PULSE_ENCODER3) \
|
||||
&& !defined(BSP_USING_PULSE_ENCODER4)
|
||||
#error "Please define at least one BSP_USING_PULSE_ENCODERx"
|
||||
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
|
||||
#elif (defined(BSP_USING_PULSE_ENCODER2) || defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1015_SERIES)
|
||||
#error "IMXRT1015 had only one quadrature decoder module"
|
||||
#elif (defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1020_SERIES)
|
||||
#error "IMXRT1020 had only two quadrature decoder module"
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
#ifdef BSP_USING_PULSE_ENCODER1
|
||||
PULSE_ENCODER1_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_PULSE_ENCODER2
|
||||
PULSE_ENCODER2_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_PULSE_ENCODER3
|
||||
PULSE_ENCODER3_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_PULSE_ENCODER4
|
||||
PULSE_ENCODER4_INDEX,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct imxrt_pulse_encoder_device
|
||||
{
|
||||
struct rt_pulse_encoder_device pulse_encoder;
|
||||
ENC_Type *base;
|
||||
char *name;
|
||||
};
|
||||
typedef struct imxrt_pulse_encoder_device imxrt_pulse_enccoder_device_t;
|
||||
|
||||
static imxrt_pulse_enccoder_device_t imxrt_pulse_encoder_obj[] =
|
||||
{
|
||||
#ifdef BSP_USING_PULSE_ENCODER1
|
||||
{
|
||||
.base = ENC1,
|
||||
.name = "pulse1"
|
||||
},
|
||||
#endif
|
||||
#ifdef BSP_USING_PULSE_ENCODER2
|
||||
{
|
||||
.base = ENC2,
|
||||
.name = "pulse2"
|
||||
},
|
||||
#endif
|
||||
#ifdef BSP_USING_PULSE_ENCODER3
|
||||
{
|
||||
.base = ENC3,
|
||||
.name = "pulse3"
|
||||
},
|
||||
#endif
|
||||
#ifdef BSP_USING_PULSE_ENCODER4
|
||||
{
|
||||
.base = ENC4,
|
||||
.name = "pulse4"
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
rt_err_t pulse_encoder_init(struct rt_pulse_encoder_device *pulse_encoder)
|
||||
{
|
||||
ENC_Type *base = ((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base;
|
||||
enc_config_t enc_config;
|
||||
ENC_GetDefaultConfig(&enc_config);
|
||||
ENC_Init(base, &enc_config);
|
||||
ENC_DoSoftwareLoadInitialPositionValue(base); /* Update the position counter with initial value. */
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t pulse_encoder_clear_count(struct rt_pulse_encoder_device *pulse_encoder)
|
||||
{
|
||||
ENC_SetInitialPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base, 0);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_int32_t pulse_encoder_get_count(struct rt_pulse_encoder_device *pulse_encoder)
|
||||
{
|
||||
return (rt_int32_t)ENC_GetPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
|
||||
}
|
||||
|
||||
rt_err_t pulse_encoder_control(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
result = RT_EOK;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case PULSE_ENCODER_CMD_ENABLE:
|
||||
result = pulse_encoder->ops->init(pulse_encoder);
|
||||
break;
|
||||
case PULSE_ENCODER_CMD_DISABLE:
|
||||
ENC_Deinit(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
|
||||
break;
|
||||
default:
|
||||
result = -RT_ENOSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct rt_pulse_encoder_ops _ops =
|
||||
{
|
||||
.init = pulse_encoder_init,
|
||||
.get_count = pulse_encoder_get_count,
|
||||
.clear_count = pulse_encoder_clear_count,
|
||||
.control = pulse_encoder_control,
|
||||
};
|
||||
|
||||
int rt_hw_pulse_encoder_init(void)
|
||||
{
|
||||
int i;
|
||||
int result;
|
||||
|
||||
result = RT_EOK;
|
||||
for (i = 0; i < sizeof(imxrt_pulse_encoder_obj) / sizeof(imxrt_pulse_encoder_obj[0]); i++)
|
||||
{
|
||||
imxrt_pulse_encoder_obj[i].pulse_encoder.type = AB_PHASE_PULSE_ENCODER;
|
||||
imxrt_pulse_encoder_obj[i].pulse_encoder.ops = &_ops;
|
||||
imxrt_pulse_encoder_obj[i].pulse_encoder.parent.user_data = &(imxrt_pulse_encoder_obj[i]);
|
||||
|
||||
if (rt_device_pulse_encoder_register(&imxrt_pulse_encoder_obj[i].pulse_encoder, imxrt_pulse_encoder_obj[i].name, &imxrt_pulse_encoder_obj[i]) != RT_EOK)
|
||||
{
|
||||
LOG_E("%s register failed", imxrt_pulse_encoder_obj[i].name);
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_pulse_encoder_init);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-10-30 ZYH the first version
|
||||
* 2019-12-19 tyustli port to stm32 series
|
||||
* 2021-01-19 Leslie Lee port to imxrt series
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
|
||||
#if defined(BSP_USB0_HOST) || defined(BSP_USB1_HOST)
|
||||
#include "drv_usbh.h"
|
||||
#include <usb/include/usb_host_config.h>
|
||||
#include <usb/include/usb.h>
|
||||
#include <usb/phy/usb_phy.h>
|
||||
#include <usb/host/usb_host.h>
|
||||
#include <usb/host/usb_host_hci.h>
|
||||
#include <usb/host/usb_host_ehci.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
|
||||
/* USB PHY configuration */
|
||||
#ifndef BOARD_USB_PHY_D_CAL
|
||||
#define BOARD_USB_PHY_D_CAL (0x0CU)
|
||||
#endif
|
||||
#ifndef BOARD_USB_PHY_TXCAL45DP
|
||||
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
|
||||
#endif
|
||||
#ifndef BOARD_USB_PHY_TXCAL45DM
|
||||
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
|
||||
#endif
|
||||
|
||||
#define USB_HOST_INTERRUPT_PRIORITY 3
|
||||
|
||||
enum
|
||||
{
|
||||
#ifdef BSP_USB0_HOST
|
||||
USBH0_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USB1_HOST
|
||||
USBH1_INDEX,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct imxrt_usb_host_pipe
|
||||
{
|
||||
usb_host_pipe_handle pipe_handle;
|
||||
struct rt_completion urb_completion;
|
||||
usb_status_t transfer_status;
|
||||
};
|
||||
|
||||
struct imxrt_usb_host
|
||||
{
|
||||
struct uhcd uhcd;
|
||||
usb_host_handle host_handle;
|
||||
usb_device_handle device_handle;
|
||||
struct imxrt_usb_host_pipe pipes[16];
|
||||
volatile rt_bool_t connect_status;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct imxrt_usb_host imxrt_usb_host_obj[] =
|
||||
{
|
||||
#ifdef BSP_USB0_HOST
|
||||
{
|
||||
.connect_status = RT_FALSE,
|
||||
.name = "usbh0"
|
||||
},
|
||||
#endif
|
||||
#ifdef BSP_USB1_HOST
|
||||
{
|
||||
.connect_status = RT_FALSE,
|
||||
.name = "usbh1"
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static void _imxrt_usb_host_send_callback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
||||
{
|
||||
struct imxrt_usb_host_pipe *pipe = (struct imxrt_usb_host_pipe *)param;
|
||||
pipe->transfer_status = status;
|
||||
rt_completion_done(&pipe->urb_completion);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Initializes USB specific setting that was not set by the Clocks tool.
|
||||
*/
|
||||
static void USB_HostClockInit(usb_controller_index_t controller_id)
|
||||
{
|
||||
usb_phy_config_struct_t phyConfig = {
|
||||
BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM,
|
||||
};
|
||||
uint32_t notUsed = 0;
|
||||
|
||||
if (controller_id == kUSB_ControllerEhci0)
|
||||
{
|
||||
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
|
||||
}
|
||||
|
||||
USB_EhciPhyInit(controller_id, 24000000U, &phyConfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables interrupt service routines for device.
|
||||
*/
|
||||
void USB_HostIsrEnable(usb_controller_index_t controller_id)
|
||||
{
|
||||
uint8_t irqNumber;
|
||||
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
|
||||
IRQn_Type usbHOSTEhciIrq[] = USBHS_IRQS;
|
||||
irqNumber = usbHOSTEhciIrq[controller_id - kUSB_ControllerEhci0];
|
||||
#endif
|
||||
/* Install isr, set priority, and enable IRQ. */
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
|
||||
#else
|
||||
NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
|
||||
#endif
|
||||
EnableIRQ((IRQn_Type)irqNumber);
|
||||
}
|
||||
|
||||
#ifdef BSP_USB0_HOST
|
||||
void USB_OTG1_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
USB_HostEhciIsrFunction(imxrt_usb_host_obj[USBH0_INDEX].host_handle);
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
static rt_err_t _ehci0_reset_port(rt_uint8_t port)
|
||||
{
|
||||
// No reset port function available
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static uint8_t _ehci0_pipe_buf[64];
|
||||
static uint8_t _ehci0_pipe_idx;
|
||||
|
||||
static int _ehci0_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
|
||||
{
|
||||
int timeout = timeouts;
|
||||
|
||||
if (!imxrt_usb_host_obj[USBH0_INDEX].connect_status)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
usb_host_transfer_t *transfer;
|
||||
if (imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle == NULL)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("error operation on null pipe\n"));
|
||||
return -1;
|
||||
}
|
||||
if (USB_HostMallocTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, &transfer) != kStatus_USB_Success)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("error to get transfer\n"));
|
||||
return -1;
|
||||
}
|
||||
transfer->transferBuffer = buffer;
|
||||
transfer->transferLength = nbytes;
|
||||
transfer->transferSofar = 0;
|
||||
transfer->callbackFn = _imxrt_usb_host_send_callback;
|
||||
transfer->callbackParam = &(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index]);
|
||||
transfer->direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT;
|
||||
if (pipe->ep.bmAttributes == USB_ENDPOINT_CONTROL)
|
||||
{
|
||||
if (token == USBH_PID_SETUP)
|
||||
{
|
||||
struct urequest *setup = (struct urequest *)buffer;
|
||||
transfer->setupStatus = 0;
|
||||
transfer->setupPacket->bmRequestType = setup->request_type;
|
||||
transfer->setupPacket->bRequest = setup->bRequest;
|
||||
transfer->setupPacket->wIndex = setup->wIndex;
|
||||
transfer->setupPacket->wLength = setup->wLength;
|
||||
transfer->setupPacket->wValue = setup->wValue;
|
||||
transfer->transferBuffer = RT_NULL;
|
||||
transfer->transferLength = 0;
|
||||
transfer->next = RT_NULL;
|
||||
if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
|
||||
{
|
||||
transfer->direction = USB_IN;
|
||||
transfer->transferBuffer = _ehci0_pipe_buf;
|
||||
transfer->transferLength = setup->wLength;
|
||||
_ehci0_pipe_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer->direction = USB_OUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_memcpy(buffer, _ehci0_pipe_buf + _ehci0_pipe_idx, nbytes);
|
||||
imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].transfer_status = kStatus_USB_Success;
|
||||
transfer->transferSofar = nbytes;
|
||||
_ehci0_pipe_idx += nbytes;
|
||||
if (_ehci0_pipe_idx >= 64)
|
||||
{
|
||||
_ehci0_pipe_idx = 0;
|
||||
}
|
||||
goto _ehci0_pipe_xfer_finish;
|
||||
}
|
||||
|
||||
}
|
||||
rt_completion_init(&(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].urb_completion));
|
||||
if (USB_HostEhciWritePipe(((usb_host_instance_t *)imxrt_usb_host_obj[USBH0_INDEX].host_handle)->controllerHandle, imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle, transfer) != kStatus_USB_Success)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb host failed to send\n"));
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
}
|
||||
if (-RT_ETIMEOUT == rt_completion_wait(&(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].urb_completion), RT_WAITING_FOREVER))
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb transfer timeout\n"));
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
}
|
||||
_ehci0_pipe_xfer_finish:
|
||||
switch (imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].transfer_status)
|
||||
{
|
||||
case kStatus_USB_Success:
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
|
||||
pipe->status = UPIPE_STATUS_OK;
|
||||
if (pipe->callback != RT_NULL)
|
||||
{
|
||||
pipe->callback(pipe);
|
||||
}
|
||||
size_t size = transfer->transferSofar;
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
|
||||
if (pipe->ep.bEndpointAddress & 0x80)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
else if (pipe->ep.bEndpointAddress & 0x00)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
return nbytes;
|
||||
break;
|
||||
}
|
||||
case kStatus_USB_TransferStall:
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
|
||||
pipe->status = UPIPE_STATUS_STALL;
|
||||
if (pipe->callback != RT_NULL)
|
||||
{
|
||||
pipe->callback(pipe);
|
||||
}
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case kStatus_USB_TransferFailed:
|
||||
default:
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
|
||||
pipe->status = UPIPE_STATUS_ERROR;
|
||||
if (pipe->callback != RT_NULL)
|
||||
{
|
||||
pipe->callback(pipe);
|
||||
}
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static rt_uint16_t _ehci0_pipe_index = 0;
|
||||
static rt_uint8_t _ehci0_get_free_pipe_index(void)
|
||||
{
|
||||
rt_uint8_t idx;
|
||||
for (idx = 1; idx < 16; idx++)
|
||||
{
|
||||
if (!(_ehci0_pipe_index & (0x01 << idx)))
|
||||
{
|
||||
_ehci0_pipe_index |= (0x01 << idx);
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static void _ehci0_free_pipe_index(rt_uint8_t index)
|
||||
{
|
||||
_ehci0_pipe_index &= ~(0x01 << index);
|
||||
}
|
||||
|
||||
static rt_err_t _ehci0_open_pipe(upipe_t pipe)
|
||||
{
|
||||
pipe->pipe_index = _ehci0_get_free_pipe_index();
|
||||
if (pipe->pipe_index == 0xFF)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
usb_host_pipe_init_t pipe_init =
|
||||
{
|
||||
.devInstance = imxrt_usb_host_obj[USBH0_INDEX].device_handle,
|
||||
.pipeType = pipe->ep.bmAttributes,
|
||||
.direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT,
|
||||
.endpointAddress = (pipe->ep.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
|
||||
.interval = pipe->ep.bInterval,
|
||||
.maxPacketSize = (uint16_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK),
|
||||
.numberPerUframe = (uint8_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK),
|
||||
.nakCount = USB_HOST_CONFIG_MAX_NAK,
|
||||
};
|
||||
USB_HostOpenPipe(imxrt_usb_host_obj[USBH0_INDEX].host_handle, &imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle, &pipe_init);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t _ehci0_close_pipe(upipe_t pipe)
|
||||
{
|
||||
(void)USB_HostClosePipe(imxrt_usb_host_obj[USBH0_INDEX].host_handle, imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle);
|
||||
_ehci0_free_pipe_index(pipe->pipe_index);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static struct uhcd_ops _ehci0_uhcd_ops =
|
||||
{
|
||||
_ehci0_reset_port,
|
||||
_ehci0_pipe_xfer,
|
||||
_ehci0_open_pipe,
|
||||
_ehci0_close_pipe,
|
||||
};
|
||||
|
||||
static usb_status_t usb0_host_callback(usb_device_handle handle, usb_host_configuration_handle config_handle, rt_uint32_t event_code)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
|
||||
switch (event_code)
|
||||
{
|
||||
case kUSB_HostEventAttach:
|
||||
if (!imxrt_usb_host_obj[USBH0_INDEX].connect_status)
|
||||
{
|
||||
imxrt_usb_host_obj[USBH0_INDEX].connect_status = RT_TRUE;
|
||||
imxrt_usb_host_obj[USBH0_INDEX].device_handle = handle;
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
|
||||
rt_usbh_root_hub_connect_handler(&(imxrt_usb_host_obj[USBH0_INDEX].uhcd), OTG_PORT, RT_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case kUSB_HostEventNotSupported:
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb device not supported\n"));
|
||||
break;
|
||||
|
||||
case kUSB_HostEventEnumerationDone:
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("enumeration done\n"));
|
||||
break;
|
||||
|
||||
case kUSB_HostEventDetach:
|
||||
if (imxrt_usb_host_obj[USBH0_INDEX].connect_status)
|
||||
{
|
||||
imxrt_usb_host_obj[USBH0_INDEX].connect_status = RT_FALSE;
|
||||
imxrt_usb_host_obj[USBH0_INDEX].device_handle = handle;
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
|
||||
rt_usbh_root_hub_disconnect_handler(&(imxrt_usb_host_obj[USBH0_INDEX].uhcd), OTG_PORT);
|
||||
(void)USB_HostCloseDeviceInterface(handle, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
rt_thread_t usbh0_thread;
|
||||
|
||||
static void _ehci0_usbh_thread(void* param)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
USB_HostEhciTaskFunction(imxrt_usb_host_obj[USBH0_INDEX].host_handle);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t _ehci0_usbh_init(rt_device_t device)
|
||||
{
|
||||
USB_HostClockInit(kUSB_ControllerEhci0);
|
||||
|
||||
if (kStatus_USB_Success == USB_HostInit(kUSB_ControllerEhci0, &imxrt_usb_host_obj[USBH0_INDEX].host_handle, usb0_host_callback))
|
||||
{
|
||||
usbh0_thread = rt_thread_create("ehci0", _ehci0_usbh_thread, RT_NULL, 500, 4, 9999999);
|
||||
rt_thread_startup(usbh0_thread);
|
||||
USB_HostIsrEnable(kUSB_ControllerEhci0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("USB_HostInit ehci0 error\r\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USB1_HOST
|
||||
void USB_OTG2_IRQHandler(void)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
USB_HostEhciIsrFunction(imxrt_usb_host_obj[USBH1_INDEX].host_handle);
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
static rt_err_t _ehci1_reset_port(rt_uint8_t port)
|
||||
{
|
||||
// No reset port function available
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static uint8_t _ehci1_pipe_buf[64];
|
||||
static uint8_t _ehci1_pipe_idx;
|
||||
|
||||
static int _ehci1_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
|
||||
{
|
||||
int timeout = timeouts;
|
||||
|
||||
if (!imxrt_usb_host_obj[USBH1_INDEX].connect_status)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
usb_host_transfer_t *transfer;
|
||||
if (imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle == NULL)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("error operation on null pipe\n"));
|
||||
return -1;
|
||||
}
|
||||
if (USB_HostMallocTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, &transfer) != kStatus_USB_Success)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("error to get transfer\n"));
|
||||
return -1;
|
||||
}
|
||||
transfer->transferBuffer = buffer;
|
||||
transfer->transferLength = nbytes;
|
||||
transfer->transferSofar = 0;
|
||||
transfer->callbackFn = _imxrt_usb_host_send_callback;
|
||||
transfer->callbackParam = &(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index]);
|
||||
transfer->direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT;
|
||||
if (pipe->ep.bmAttributes == USB_ENDPOINT_CONTROL)
|
||||
{
|
||||
if (token == USBH_PID_SETUP)
|
||||
{
|
||||
struct urequest *setup = (struct urequest *)buffer;
|
||||
transfer->setupStatus = 0;
|
||||
transfer->setupPacket->bmRequestType = setup->request_type;
|
||||
transfer->setupPacket->bRequest = setup->bRequest;
|
||||
transfer->setupPacket->wIndex = setup->wIndex;
|
||||
transfer->setupPacket->wLength = setup->wLength;
|
||||
transfer->setupPacket->wValue = setup->wValue;
|
||||
transfer->transferBuffer = RT_NULL;
|
||||
transfer->transferLength = 0;
|
||||
transfer->next = RT_NULL;
|
||||
if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
|
||||
{
|
||||
transfer->direction = USB_IN;
|
||||
transfer->transferBuffer = _ehci1_pipe_buf;
|
||||
transfer->transferLength = setup->wLength;
|
||||
_ehci1_pipe_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer->direction = USB_OUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_memcpy(buffer, _ehci1_pipe_buf + _ehci1_pipe_idx, nbytes);
|
||||
imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].transfer_status = kStatus_USB_Success;
|
||||
transfer->transferSofar = nbytes;
|
||||
_ehci1_pipe_idx += nbytes;
|
||||
if (_ehci1_pipe_idx >= 64)
|
||||
{
|
||||
_ehci1_pipe_idx = 0;
|
||||
}
|
||||
goto _ehci1_pipe_xfer_finish;
|
||||
}
|
||||
|
||||
}
|
||||
rt_completion_init(&(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].urb_completion));
|
||||
if (USB_HostEhciWritePipe(((usb_host_instance_t *)imxrt_usb_host_obj[USBH1_INDEX].host_handle)->controllerHandle, imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle, transfer) != kStatus_USB_Success)
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb host failed to send\n"));
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
}
|
||||
if (-RT_ETIMEOUT == rt_completion_wait(&(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].urb_completion), RT_WAITING_FOREVER))
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb transfer timeout\n"));
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
}
|
||||
// rt_thread_mdelay(1);
|
||||
_ehci1_pipe_xfer_finish:
|
||||
switch (imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].transfer_status)
|
||||
{
|
||||
case kStatus_USB_Success:
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
|
||||
pipe->status = UPIPE_STATUS_OK;
|
||||
if (pipe->callback != RT_NULL)
|
||||
{
|
||||
pipe->callback(pipe);
|
||||
}
|
||||
size_t size = transfer->transferSofar;
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
|
||||
if (pipe->ep.bEndpointAddress & 0x80)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
else if (pipe->ep.bEndpointAddress & 0x00)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
return nbytes;
|
||||
break;
|
||||
}
|
||||
case kStatus_USB_TransferStall:
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
|
||||
pipe->status = UPIPE_STATUS_STALL;
|
||||
if (pipe->callback != RT_NULL)
|
||||
{
|
||||
pipe->callback(pipe);
|
||||
}
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case kStatus_USB_TransferFailed:
|
||||
default:
|
||||
{
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
|
||||
pipe->status = UPIPE_STATUS_ERROR;
|
||||
if (pipe->callback != RT_NULL)
|
||||
{
|
||||
pipe->callback(pipe);
|
||||
}
|
||||
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static rt_uint16_t _ehci1_pipe_index = 0;
|
||||
static rt_uint8_t _ehci1_get_free_pipe_index(void)
|
||||
{
|
||||
rt_uint8_t idx;
|
||||
for (idx = 1; idx < 16; idx++)
|
||||
{
|
||||
if (!(_ehci1_pipe_index & (0x01 << idx)))
|
||||
{
|
||||
_ehci1_pipe_index |= (0x01 << idx);
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static void _ehci1_free_pipe_index(rt_uint8_t index)
|
||||
{
|
||||
_ehci1_pipe_index &= ~(0x01 << index);
|
||||
}
|
||||
|
||||
static rt_err_t _ehci1_open_pipe(upipe_t pipe)
|
||||
{
|
||||
pipe->pipe_index = _ehci1_get_free_pipe_index();
|
||||
if (pipe->pipe_index == 0xFF)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
usb_host_pipe_init_t pipe_init =
|
||||
{
|
||||
.devInstance = imxrt_usb_host_obj[USBH1_INDEX].device_handle,
|
||||
.pipeType = pipe->ep.bmAttributes,
|
||||
.direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT,
|
||||
.endpointAddress = (pipe->ep.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
|
||||
.interval = pipe->ep.bInterval,
|
||||
.maxPacketSize = (uint16_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK),
|
||||
.numberPerUframe = (uint8_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK),
|
||||
.nakCount = USB_HOST_CONFIG_MAX_NAK,
|
||||
};
|
||||
USB_HostOpenPipe(imxrt_usb_host_obj[USBH1_INDEX].host_handle, &imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle, &pipe_init);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t _ehci1_close_pipe(upipe_t pipe)
|
||||
{
|
||||
(void)USB_HostClosePipe(imxrt_usb_host_obj[USBH1_INDEX].host_handle, imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle);
|
||||
_ehci1_free_pipe_index(pipe->pipe_index);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static struct uhcd_ops _ehci1_uhcd_ops =
|
||||
{
|
||||
_ehci1_reset_port,
|
||||
_ehci1_pipe_xfer,
|
||||
_ehci1_open_pipe,
|
||||
_ehci1_close_pipe,
|
||||
};
|
||||
|
||||
static usb_status_t usb1_host_callback(usb_device_handle handle, usb_host_configuration_handle config_handle, rt_uint32_t event_code)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
|
||||
switch (event_code)
|
||||
{
|
||||
case kUSB_HostEventAttach:
|
||||
if (!imxrt_usb_host_obj[USBH1_INDEX].connect_status)
|
||||
{
|
||||
imxrt_usb_host_obj[USBH1_INDEX].connect_status = RT_TRUE;
|
||||
imxrt_usb_host_obj[USBH1_INDEX].device_handle = handle;
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
|
||||
rt_usbh_root_hub_connect_handler(&(imxrt_usb_host_obj[USBH1_INDEX].uhcd), OTG_PORT, RT_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case kUSB_HostEventNotSupported:
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb device not supported\n"));
|
||||
break;
|
||||
|
||||
case kUSB_HostEventEnumerationDone:
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("enumeration done\n"));
|
||||
break;
|
||||
|
||||
case kUSB_HostEventDetach:
|
||||
if (imxrt_usb_host_obj[USBH1_INDEX].connect_status)
|
||||
{
|
||||
imxrt_usb_host_obj[USBH1_INDEX].connect_status = RT_FALSE;
|
||||
imxrt_usb_host_obj[USBH1_INDEX].device_handle = handle;
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
|
||||
rt_usbh_root_hub_disconnect_handler(&(imxrt_usb_host_obj[USBH1_INDEX].uhcd), OTG_PORT);
|
||||
(void)USB_HostCloseDeviceInterface(handle, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
rt_thread_t usbh1_thread;
|
||||
|
||||
static void _ehci1_usbh_thread(void* param)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
USB_HostEhciTaskFunction(imxrt_usb_host_obj[USBH1_INDEX].host_handle);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t _ehci1_usbh_init(rt_device_t device)
|
||||
{
|
||||
USB_HostClockInit(kUSB_ControllerEhci1);
|
||||
|
||||
if (kStatus_USB_Success == USB_HostInit(kUSB_ControllerEhci1, &imxrt_usb_host_obj[USBH1_INDEX].host_handle, usb1_host_callback))
|
||||
{
|
||||
usbh1_thread = rt_thread_create("ehci1", _ehci1_usbh_thread, RT_NULL, 500, 4, 9999999);
|
||||
rt_thread_startup(usbh1_thread);
|
||||
USB_HostIsrEnable(kUSB_ControllerEhci1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("USB_HostInit ehci1 error\r\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int imxrt_usbh_register(void)
|
||||
{
|
||||
rt_err_t res = -RT_ERROR;
|
||||
struct imxrt_usb_host *usb_host_obj;
|
||||
|
||||
#ifdef BSP_USB0_HOST
|
||||
usb_host_obj = &(imxrt_usb_host_obj[USBH0_INDEX]);
|
||||
rt_memset((void *)(&(usb_host_obj->uhcd)), 0, sizeof(struct uhcd));
|
||||
usb_host_obj->uhcd.parent.type = RT_Device_Class_USBHost;
|
||||
usb_host_obj->uhcd.parent.init = _ehci0_usbh_init;
|
||||
usb_host_obj->uhcd.parent.user_data = usb_host_obj;
|
||||
usb_host_obj->uhcd.ops = &_ehci0_uhcd_ops;
|
||||
usb_host_obj->uhcd.num_ports = OTG_PORT;
|
||||
res = rt_device_register(&(usb_host_obj->uhcd.parent), usb_host_obj->name, RT_DEVICE_FLAG_DEACTIVATE);
|
||||
if (res != RT_EOK)
|
||||
{
|
||||
rt_kprintf("register usb0 host failed res = %d\r\n", res);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_usb_host_init(usb_host_obj->name);
|
||||
#endif
|
||||
#ifdef BSP_USB1_HOST
|
||||
usb_host_obj = &(imxrt_usb_host_obj[USBH1_INDEX]);
|
||||
rt_memset((void *)(&(usb_host_obj->uhcd)), 0, sizeof(struct uhcd));
|
||||
usb_host_obj->uhcd.parent.type = RT_Device_Class_USBHost;
|
||||
usb_host_obj->uhcd.parent.init = _ehci1_usbh_init;
|
||||
usb_host_obj->uhcd.parent.user_data = usb_host_obj;
|
||||
usb_host_obj->uhcd.ops = &_ehci1_uhcd_ops;
|
||||
usb_host_obj->uhcd.num_ports = OTG_PORT;
|
||||
res = rt_device_register(&(usb_host_obj->uhcd.parent), usb_host_obj->name, RT_DEVICE_FLAG_DEACTIVATE);
|
||||
if (res != RT_EOK)
|
||||
{
|
||||
rt_kprintf("register usb0 host failed res = %d\r\n", res);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_usb_host_init(usb_host_obj->name);
|
||||
#endif
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(imxrt_usbh_register);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-12-12 ZYH the first version
|
||||
* 2019-12-19 tyustli port to stm32 series
|
||||
* 2021-01-19 Leslie Lee port to imxrt series
|
||||
*/
|
||||
#ifndef __DRV_USBH_H__
|
||||
#define __DRV_USBH_H__
|
||||
#include <rtthread.h>
|
||||
|
||||
#define OTG_PORT 1
|
||||
|
||||
int imxrt_usbh_register(void);
|
||||
|
||||
#endif
|
||||
|
||||
/************* end of file ************/
|
|
@ -1,31 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* Copyright 2016 - 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_HOST_H_
|
||||
|
@ -68,6 +46,16 @@ typedef enum _usb_host_event
|
|||
kUSB_HostEventDetach, /*!< Device is detached */
|
||||
kUSB_HostEventEnumerationDone, /*!< Device's enumeration is done and the device is supported */
|
||||
kUSB_HostEventNotSupported, /*!< Device's enumeration is done and the device is not supported */
|
||||
/*! Device's enumeration failed due to errors
|
||||
* fail reason is put in the high 2 bytes of callback event code.
|
||||
* kStatus_USB_TransferFailed - the transfer failed.
|
||||
* kStatus_USB_TransferCancel - transfer is canceled by application.
|
||||
* kStatus_USB_Error - parsing descriptor failed, the power cannot satisfy device's requirement,
|
||||
* device addresss allocation failed, transfer is not enough
|
||||
* or the transfer API failed.
|
||||
* kStatus_USB_AllocFail - malloc failed.
|
||||
*/
|
||||
kUSB_HostEventEnumerationFail,
|
||||
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
|
||||
kUSB_HostEventNotSuspended, /*!< Suspend failed */
|
||||
kUSB_HostEventSuspended, /*!< Suspend successful */
|
||||
|
@ -103,7 +91,60 @@ typedef enum _usb_host_dev_info
|
|||
kUSB_HostGetConfigurationDes, /*!< Device's configuration descriptor pointer */
|
||||
kUSB_HostGetConfigurationLength, /*!< Device's configuration descriptor pointer */
|
||||
} usb_host_dev_info_t;
|
||||
/*! @brief Request type */
|
||||
typedef enum _usb_host_request_type
|
||||
{
|
||||
kRequestDevice = 1U, /*!< Control request object is device */
|
||||
kRequestInterface, /*!< Control request object is interface */
|
||||
kRequestEndpoint, /*!< Control request object is endpoint */
|
||||
} usb_host_request_type_t;
|
||||
/*! @brief For USB_REQUEST_STANDARD_GET_DESCRIPTOR and USB_REQUEST_STANDARD_SET_DESCRIPTOR */
|
||||
typedef struct _usb_host_process_descriptor_param
|
||||
{
|
||||
uint8_t descriptorType; /*!< See the usb_spec.h, such as the USB_DESCRIPTOR_TYPE_DEVICE */
|
||||
uint8_t descriptorIndex; /*!< The descriptor index is used to select a specific descriptor (only for configuration
|
||||
and string descriptors) when several descriptors of the same type are implemented in a
|
||||
device */
|
||||
uint8_t languageId; /*!< It specifies the language ID for string descriptors or is reset to zero for other
|
||||
descriptors */
|
||||
uint8_t *descriptorBuffer; /*!< Buffer pointer */
|
||||
uint16_t descriptorLength; /*!< Buffer data length */
|
||||
} usb_host_process_descriptor_param_t;
|
||||
/*! @brief For USB_REQUEST_STANDARD_CLEAR_FEATURE and USB_REQUEST_STANDARD_SET_FEATURE */
|
||||
typedef struct _usb_host_process_feature_param
|
||||
{
|
||||
uint8_t requestType; /*!< See the #usb_host_request_type_t */
|
||||
uint8_t featureSelector; /*!< Set/cleared feature */
|
||||
uint8_t interfaceOrEndpoint; /*!< Interface or end pointer */
|
||||
} usb_host_process_feature_param_t;
|
||||
/*! @brief For USB_REQUEST_STANDARD_GET_INTERFACE */
|
||||
typedef struct _usb_host_get_interface_param
|
||||
{
|
||||
uint8_t interface; /*!< Interface number */
|
||||
uint8_t *alternateInterfaceBuffer; /*!< Save the transfer result */
|
||||
} usb_host_get_interface_param_t;
|
||||
|
||||
/*! @brief For USB_REQUEST_STANDARD_GET_STATUS */
|
||||
typedef struct _usb_host_get_status_param
|
||||
{
|
||||
uint16_t statusSelector; /*!< Interface number, the end pointer number or OTG status selector */
|
||||
uint8_t requestType; /*!< See the #usb_host_request_type_t */
|
||||
uint8_t *statusBuffer; /*!< Save the transfer result */
|
||||
} usb_host_get_status_param_t;
|
||||
|
||||
/*! @brief For USB_REQUEST_STANDARD_SET_INTERFACE */
|
||||
typedef struct _usb_host_set_interface_param
|
||||
{
|
||||
uint8_t alternateSetting; /*!< Alternate setting value */
|
||||
uint8_t interface; /*!< Interface number */
|
||||
} usb_host_set_interface_param_t;
|
||||
|
||||
/*! @brief For USB_REQUEST_STANDARD_SYNCH_FRAME */
|
||||
typedef struct _usb_host_synch_frame_param
|
||||
{
|
||||
uint8_t endpoint; /*!< Endpoint number */
|
||||
uint8_t *frameNumberBuffer; /*!< Frame number data buffer */
|
||||
} usb_host_synch_frame_param_t;
|
||||
/*!
|
||||
* @brief Host callback function typedef.
|
||||
*
|
||||
|
@ -243,8 +284,8 @@ typedef struct _usb_host_pipe_init
|
|||
/*! @brief Cancel transfer parameter structure */
|
||||
typedef struct _usb_host_cancel_param
|
||||
{
|
||||
usb_host_pipe_handle pipeHandle; /*!< Cancelling pipe handle*/
|
||||
usb_host_transfer_t *transfer; /*!< Cancelling transfer*/
|
||||
usb_host_pipe_handle pipeHandle; /*!< Canceling pipe handle*/
|
||||
usb_host_transfer_t *transfer; /*!< Canceling transfer*/
|
||||
} usb_host_cancel_param_t;
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -342,7 +383,7 @@ extern usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handl
|
|||
* @retval kStatus_USB_InvalidParameter The deviceHandle instance don't belong to hostHandle instance.
|
||||
*/
|
||||
extern usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle);
|
||||
|
||||
#if (defined(USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI > 0U))
|
||||
/*!
|
||||
* @brief KHCI task function.
|
||||
*
|
||||
|
@ -353,7 +394,8 @@ extern usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostKhciTaskFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
|
||||
/*!
|
||||
* @brief EHCI task function.
|
||||
*
|
||||
|
@ -364,7 +406,8 @@ extern void USB_HostKhciTaskFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostEhciTaskFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
|
||||
/*!
|
||||
* @brief OHCI task function.
|
||||
*
|
||||
|
@ -375,7 +418,8 @@ extern void USB_HostEhciTaskFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostOhciTaskFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
|
||||
/*!
|
||||
* @brief IP3516HS task function.
|
||||
*
|
||||
|
@ -386,7 +430,8 @@ extern void USB_HostOhciTaskFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostIp3516HsTaskFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI > 0U))
|
||||
/*!
|
||||
* @brief Device KHCI ISR function.
|
||||
*
|
||||
|
@ -395,7 +440,8 @@ extern void USB_HostIp3516HsTaskFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostKhciIsrFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
|
||||
/*!
|
||||
* @brief Device EHCI ISR function.
|
||||
*
|
||||
|
@ -404,7 +450,8 @@ extern void USB_HostKhciIsrFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostEhciIsrFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
|
||||
/*!
|
||||
* @brief Device OHCI ISR function.
|
||||
*
|
||||
|
@ -413,7 +460,8 @@ extern void USB_HostEhciIsrFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostOhciIsrFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
#if (defined(USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
|
||||
/*!
|
||||
* @brief Device IP3516HS ISR function.
|
||||
*
|
||||
|
@ -422,7 +470,7 @@ extern void USB_HostOhciIsrFunction(void *hostHandle);
|
|||
* @param[in] hostHandle The host handle.
|
||||
*/
|
||||
extern void USB_HostIp3516HsIsrFunction(void *hostHandle);
|
||||
|
||||
#endif
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
|
@ -566,7 +614,7 @@ extern usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_tr
|
|||
* This function sends the USB standard request packet.
|
||||
*
|
||||
* @param[in] deviceHandle The device handle for control transfer.
|
||||
* @param[in] usbRequest A USB standard request code. Se the usb_spec.h.
|
||||
* @param[in] usbRequest A USB standard request code. See the usb_spec.h.
|
||||
* @param[in] transfer The used transfer.
|
||||
* @param[in] param The parameter structure is different for different request, see
|
||||
* usb_host_framework.h.
|
||||
|
@ -694,10 +742,10 @@ extern usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
|
|||
/*!
|
||||
* @brief Update the lpm param.
|
||||
*
|
||||
* The function is used to configuure the lpm token.
|
||||
* The function is used to configure the lpm token.
|
||||
*
|
||||
* @param[in] hostHandle The host handle.
|
||||
* @param[in] lpmParam HIRD vaule and whether enable remotewakeup.
|
||||
* @param[in] lpmParam HIRD value and whether enable remotewakeup.
|
||||
*
|
||||
*/
|
||||
extern usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam);
|
||||
|
@ -715,6 +763,19 @@ extern usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t ti
|
|||
|
||||
#endif
|
||||
|
||||
#if ((defined(USB_HOST_CONFIG_BATTERY_CHARGER)) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U))
|
||||
/*!
|
||||
* @brief Set the charger type. It is only supported on RT600 currently.
|
||||
*
|
||||
* The set charger type becomes valid in next attach.
|
||||
*
|
||||
* @param[in] hostHandle The host handle.
|
||||
* @param[in] type.
|
||||
*
|
||||
*/
|
||||
extern usb_status_t USB_HostSetChargerType(usb_host_handle hostHandle, uint8_t type);
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,31 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_HOST_DEV_MNG_H_
|
||||
|
@ -79,11 +57,11 @@ typedef struct _usb_host_device_instance
|
|||
usb_descriptor_device_t *deviceDescriptor; /*!< Standard device descriptor */
|
||||
usb_host_pipe_handle controlPipe; /*!< Device's control pipe */
|
||||
uint8_t *configurationDesc; /*!< Configuration descriptor pointer */
|
||||
uint8_t *enumBuffer; /*!< Buffer for enumeration */
|
||||
uint16_t configurationLen; /*!< Configuration descriptor length */
|
||||
uint16_t configurationValue; /*!< Configuration index */
|
||||
uint8_t interfaceStatus[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interfaces' status, please reference to
|
||||
#usb_host_interface_state_t */
|
||||
uint8_t *enumBuffer; /*!< Buffer for enumeration */
|
||||
uint8_t configurationValue; /*!< Configuration index */
|
||||
uint8_t state; /*!< Device state for enumeration */
|
||||
uint8_t enumRetries; /*!< Re-enumeration when error in control transfer */
|
||||
uint8_t stallRetries; /*!< Re-transfer when stall */
|
||||
|
@ -104,11 +82,10 @@ typedef struct _usb_host_device_instance
|
|||
|
||||
typedef struct _usb_host_enum_process_entry
|
||||
{
|
||||
uint8_t successState; /*!< When the last step is successful, the next state value */
|
||||
uint8_t retryState; /*!< When the last step need retry, the next state value */
|
||||
usb_status_t (*process)(usb_host_device_instance_t *deviceInstance); /*!< When the last step transfer is done, the
|
||||
function is used to process the transfer
|
||||
data */
|
||||
usb_host_device_enumeration_status_t successState; /*!< When the last step is successful, the next state value */
|
||||
usb_host_device_enumeration_status_t retryState; /*!< When the last step need retry, the next state value */
|
||||
/*! When the last step transfer is done, the function is used to process the transfer data */
|
||||
usb_status_t (*process)(usb_host_device_instance_t *deviceInstance, uint32_t dataLength);
|
||||
} usb_host_enum_process_entry_t;
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,31 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* Copyright 2016,2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_HOST_CONTROLLER_EHCI_H_
|
||||
|
@ -39,95 +17,95 @@
|
|||
* Definitions
|
||||
******************************************************************************/
|
||||
/* EHCI host macros */
|
||||
#define EHCI_HOST_T_INVALID_VALUE (1U)
|
||||
#define EHCI_HOST_POINTER_TYPE_ITD (0x00U)
|
||||
#define EHCI_HOST_POINTER_TYPE_QH (0x00000002U)
|
||||
#define EHCI_HOST_POINTER_TYPE_SITD (0x00000004U)
|
||||
#define EHCI_HOST_POINTER_TYPE_FSTN (0x00000006U)
|
||||
#define EHCI_HOST_POINTER_TYPE_MASK (0x00000006U)
|
||||
#define EHCI_HOST_T_INVALID_VALUE (1U)
|
||||
#define EHCI_HOST_POINTER_TYPE_ITD (0x00U)
|
||||
#define EHCI_HOST_POINTER_TYPE_QH (0x00000002U)
|
||||
#define EHCI_HOST_POINTER_TYPE_SITD (0x00000004U)
|
||||
#define EHCI_HOST_POINTER_TYPE_FSTN (0x00000006U)
|
||||
#define EHCI_HOST_POINTER_TYPE_MASK (0x00000006U)
|
||||
#define EHCI_HOST_POINTER_ADDRESS_MASK (0xFFFFFFE0U)
|
||||
#define EHCI_HOST_PID_OUT (0U)
|
||||
#define EHCI_HOST_PID_IN (1U)
|
||||
#define EHCI_HOST_PID_SETUP (2U)
|
||||
#define EHCI_HOST_PID_OUT (0UL)
|
||||
#define EHCI_HOST_PID_IN (1UL)
|
||||
#define EHCI_HOST_PID_SETUP (2UL)
|
||||
|
||||
#define EHCI_HOST_QH_RL_SHIFT (28U)
|
||||
#define EHCI_HOST_QH_RL_MASK (0xF0000000U)
|
||||
#define EHCI_HOST_QH_C_SHIFT (27U)
|
||||
#define EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT (16U)
|
||||
#define EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK (0x07FF0000U)
|
||||
#define EHCI_HOST_QH_H_SHIFT (15U)
|
||||
#define EHCI_HOST_QH_DTC_SHIFT (14U)
|
||||
#define EHCI_HOST_QH_EPS_SHIFT (12U)
|
||||
#define EHCI_HOST_QH_ENDPT_SHIFT (8U)
|
||||
#define EHCI_HOST_QH_I_SHIFT (7U)
|
||||
#define EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT (0U)
|
||||
#define EHCI_HOST_QH_MULT_SHIFT (30U)
|
||||
#define EHCI_HOST_QH_PORT_NUMBER_SHIFT (23U)
|
||||
#define EHCI_HOST_QH_HUB_ADDR_SHIFT (16U)
|
||||
#define EHCI_HOST_QH_UFRAME_CMASK_SHIFT (8U)
|
||||
#define EHCI_HOST_QH_UFRAME_SMASK_SHIFT (0U)
|
||||
#define EHCI_HOST_QH_STATUS_ERROR_MASK (0x0000007EU)
|
||||
#define EHCI_HOST_QH_RL_SHIFT (28U)
|
||||
#define EHCI_HOST_QH_RL_MASK (0xF0000000U)
|
||||
#define EHCI_HOST_QH_C_SHIFT (27U)
|
||||
#define EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT (16U)
|
||||
#define EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK (0x07FF0000U)
|
||||
#define EHCI_HOST_QH_H_SHIFT (15U)
|
||||
#define EHCI_HOST_QH_DTC_SHIFT (14U)
|
||||
#define EHCI_HOST_QH_EPS_SHIFT (12U)
|
||||
#define EHCI_HOST_QH_ENDPT_SHIFT (8U)
|
||||
#define EHCI_HOST_QH_I_SHIFT (7U)
|
||||
#define EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT (0U)
|
||||
#define EHCI_HOST_QH_MULT_SHIFT (30U)
|
||||
#define EHCI_HOST_QH_PORT_NUMBER_SHIFT (23U)
|
||||
#define EHCI_HOST_QH_HUB_ADDR_SHIFT (16U)
|
||||
#define EHCI_HOST_QH_UFRAME_CMASK_SHIFT (8U)
|
||||
#define EHCI_HOST_QH_UFRAME_SMASK_SHIFT (0U)
|
||||
#define EHCI_HOST_QH_STATUS_ERROR_MASK (0x0000007EU)
|
||||
#define EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK (0x0000003EU)
|
||||
|
||||
#define EHCI_HOST_QTD_DT_SHIFT (31U)
|
||||
#define EHCI_HOST_QTD_DT_MASK (0x80000000U)
|
||||
#define EHCI_HOST_QTD_TOTAL_BYTES_SHIFT (16U)
|
||||
#define EHCI_HOST_QTD_TOTAL_BYTES_MASK (0x7FFF0000U)
|
||||
#define EHCI_HOST_QTD_IOC_MASK (0x00008000U)
|
||||
#define EHCI_HOST_QTD_C_PAGE_SHIFT (12U)
|
||||
#define EHCI_HOST_QTD_CERR_SHIFT (10U)
|
||||
#define EHCI_HOST_QTD_CERR_MAX_VALUE (0x00000003U)
|
||||
#define EHCI_HOST_QTD_PID_CODE_SHIFT (8U)
|
||||
#define EHCI_HOST_QTD_STATUS_SHIFT (0U)
|
||||
#define EHCI_HOST_QTD_CURRENT_OFFSET_MASK (0x00000FFFU)
|
||||
#define EHCI_HOST_QTD_BUFFER_POINTER_SHIFT (12U)
|
||||
#define EHCI_HOST_QTD_STATUS_ACTIVE_MASK (0x00000080U)
|
||||
#define EHCI_HOST_QTD_STATUS_MASK (0x000000ffU)
|
||||
#define EHCI_HOST_QTD_STATUS_ERROR_MASK (0x0000007EU)
|
||||
#define EHCI_HOST_QTD_DT_SHIFT (31U)
|
||||
#define EHCI_HOST_QTD_DT_MASK (0x80000000U)
|
||||
#define EHCI_HOST_QTD_TOTAL_BYTES_SHIFT (16U)
|
||||
#define EHCI_HOST_QTD_TOTAL_BYTES_MASK (0x7FFF0000U)
|
||||
#define EHCI_HOST_QTD_IOC_MASK (0x00008000U)
|
||||
#define EHCI_HOST_QTD_C_PAGE_SHIFT (12U)
|
||||
#define EHCI_HOST_QTD_CERR_SHIFT (10U)
|
||||
#define EHCI_HOST_QTD_CERR_MAX_VALUE (0x00000003UL)
|
||||
#define EHCI_HOST_QTD_PID_CODE_SHIFT (8U)
|
||||
#define EHCI_HOST_QTD_STATUS_SHIFT (0U)
|
||||
#define EHCI_HOST_QTD_CURRENT_OFFSET_MASK (0x00000FFFU)
|
||||
#define EHCI_HOST_QTD_BUFFER_POINTER_SHIFT (12U)
|
||||
#define EHCI_HOST_QTD_STATUS_ACTIVE_MASK (0x00000080U)
|
||||
#define EHCI_HOST_QTD_STATUS_MASK (0x000000ffU)
|
||||
#define EHCI_HOST_QTD_STATUS_ERROR_MASK (0x0000007EU)
|
||||
#define EHCI_HOST_QTD_STATUS_STALL_ERROR_MASK (0x00000040U)
|
||||
|
||||
#define EHCI_HOST_ITD_STATUS_ACTIVE_MASK (0x80000000U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT (16U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_LEN_MASK (0x0FFF0000U)
|
||||
#define EHCI_HOST_ITD_IOC_SHIFT (15U)
|
||||
#define EHCI_HOST_ITD_PG_SHIFT (12U)
|
||||
#define EHCI_HOST_ITD_STATUS_ACTIVE_MASK (0x80000000U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT (16U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_LEN_MASK (0x0FFF0000U)
|
||||
#define EHCI_HOST_ITD_IOC_SHIFT (15U)
|
||||
#define EHCI_HOST_ITD_PG_SHIFT (12U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_OFFSET_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK (0x00000FFFU)
|
||||
#define EHCI_HOST_ITD_BUFFER_POINTER_SHIFT (12U)
|
||||
#define EHCI_HOST_ITD_ENDPT_SHIFT (8U)
|
||||
#define EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_MULT_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_DIRECTION_SHIFT (11U)
|
||||
#define EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK (0x00000FFFU)
|
||||
#define EHCI_HOST_ITD_BUFFER_POINTER_SHIFT (12U)
|
||||
#define EHCI_HOST_ITD_ENDPT_SHIFT (8U)
|
||||
#define EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_MULT_SHIFT (0U)
|
||||
#define EHCI_HOST_ITD_DIRECTION_SHIFT (11U)
|
||||
|
||||
#define EHCI_HOST_SITD_STATUS_ACTIVE_MASK (0x00000080U)
|
||||
#define EHCI_HOST_SITD_DIRECTION_SHIFT (31U)
|
||||
#define EHCI_HOST_SITD_PORT_NUMBER_SHIFT (24U)
|
||||
#define EHCI_HOST_SITD_HUB_ADDR_SHIFT (16U)
|
||||
#define EHCI_HOST_SITD_ENDPT_SHIFT (8U)
|
||||
#define EHCI_HOST_SITD_STATUS_ACTIVE_MASK (0x00000080U)
|
||||
#define EHCI_HOST_SITD_DIRECTION_SHIFT (31U)
|
||||
#define EHCI_HOST_SITD_PORT_NUMBER_SHIFT (24U)
|
||||
#define EHCI_HOST_SITD_HUB_ADDR_SHIFT (16U)
|
||||
#define EHCI_HOST_SITD_ENDPT_SHIFT (8U)
|
||||
#define EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT (0U)
|
||||
#define EHCI_HOST_SITD_CMASK_SHIFT (8U)
|
||||
#define EHCI_HOST_SITD_SMASK_SHIFT (0U)
|
||||
#define EHCI_HOST_SITD_TOTAL_BYTES_SHIFT (16U)
|
||||
#define EHCI_HOST_SITD_TOTAL_BYTES_MASK (0x03FF0000U)
|
||||
#define EHCI_HOST_SITD_TP_SHIFT (3U)
|
||||
#define EHCI_HOST_SITD_TCOUNT_SHIFT (0U)
|
||||
#define EHCI_HOST_SITD_IOC_SHIFT (31U)
|
||||
#define EHCI_HOST_SITD_CMASK_SHIFT (8U)
|
||||
#define EHCI_HOST_SITD_SMASK_SHIFT (0U)
|
||||
#define EHCI_HOST_SITD_TOTAL_BYTES_SHIFT (16U)
|
||||
#define EHCI_HOST_SITD_TOTAL_BYTES_MASK (0x03FF0000U)
|
||||
#define EHCI_HOST_SITD_TP_SHIFT (3U)
|
||||
#define EHCI_HOST_SITD_TCOUNT_SHIFT (0U)
|
||||
#define EHCI_HOST_SITD_IOC_SHIFT (31U)
|
||||
|
||||
/* register related MACROs */
|
||||
#define EHCI_PORTSC1_W1_BITS (0x0000002AU)
|
||||
#define EHCI_PORTSC1_W1_BITS (0x0000002AU)
|
||||
#define EHCI_MAX_UFRAME_VALUE (0x00003FFFU)
|
||||
|
||||
/* task event */
|
||||
#define EHCI_TASK_EVENT_DEVICE_ATTACH (0x01U)
|
||||
#define EHCI_TASK_EVENT_DEVICE_ATTACH (0x01U)
|
||||
#define EHCI_TASK_EVENT_TRANSACTION_DONE (0x02U)
|
||||
#define EHCI_TASK_EVENT_DEVICE_DETACH (0x04U)
|
||||
#define EHCI_TASK_EVENT_PORT_CHANGE (0x08U)
|
||||
#define EHCI_TASK_EVENT_TIMER0 (0x10U)
|
||||
#define EHCI_TASK_EVENT_TIMER1 (0x20U)
|
||||
#define EHCI_TASK_EVENT_DEVICE_DETACH (0x04U)
|
||||
#define EHCI_TASK_EVENT_PORT_CHANGE (0x08U)
|
||||
#define EHCI_TASK_EVENT_TIMER0 (0x10U)
|
||||
#define EHCI_TASK_EVENT_TIMER1 (0x20U)
|
||||
|
||||
#define USB_HostEhciLock() USB_OsaMutexLock(ehciInstance->ehciMutex)
|
||||
#define USB_HostEhciUnlock() USB_OsaMutexUnlock(ehciInstance->ehciMutex)
|
||||
#define USB_HostEhciLock() (void)OSA_MutexLock(ehciInstance->ehciMutex, USB_OSA_WAIT_TIMEOUT)
|
||||
#define USB_HostEhciUnlock() (void)OSA_MutexUnlock(ehciInstance->ehciMutex)
|
||||
|
||||
/*******************************************************************************
|
||||
* KHCI driver public structures, enumerations, macros, functions
|
||||
|
@ -144,6 +122,8 @@
|
|||
#define USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY (101U)
|
||||
/*! @brief Delay for port reset */
|
||||
#define USB_HOST_EHCI_PORT_RESET_DELAY (11U)
|
||||
/*! @brief The MAX continuous transfers that application can send. */
|
||||
#define USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER (8U)
|
||||
/*! @brief The SITD inserts a frame interval for putting more SITD continuously.
|
||||
* There is an interval when an application sends two FS/LS ISO transfers.
|
||||
* When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two
|
||||
|
@ -171,7 +151,7 @@
|
|||
*/
|
||||
#define USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER (16U)
|
||||
/*! @brief Control or bulk transaction timeout value (unit: 100 ms) */
|
||||
#define USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE (20U)
|
||||
#define USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE (50U)
|
||||
|
||||
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
|
||||
typedef enum _bus_ehci_suspend_request_state
|
||||
|
@ -323,8 +303,10 @@ typedef struct _usb_host_ehci_instance
|
|||
usb_host_ehci_pipe_t *ehciPipeIndexBase; /*!< Pipe buffer's start pointer*/
|
||||
usb_host_ehci_pipe_t *ehciPipeList; /*!< Idle pipe list pointer*/
|
||||
usb_host_ehci_pipe_t *ehciRunningPipeList; /*!< Running pipe list pointer*/
|
||||
usb_osa_mutex_handle ehciMutex; /*!< EHCI mutex*/
|
||||
usb_osa_event_handle taskEventHandle; /*!< EHCI task event*/
|
||||
osa_mutex_handle_t ehciMutex; /*!< EHCI mutex*/
|
||||
uint32_t mutexBuffer[(OSA_MUTEX_HANDLE_SIZE + 3) / 4]; /*!< The mutex buffer. */
|
||||
osa_event_handle_t taskEventHandle; /*!< EHCI task event*/
|
||||
uint32_t taskEventHandleBuffer[(OSA_EVENT_HANDLE_SIZE + 3) / 4]; /*!< EHCI task event handle buffer*/
|
||||
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
|
||||
uint64_t matchTick;
|
||||
USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */
|
||||
|
@ -355,6 +337,10 @@ typedef struct _usb_host_ehci_data
|
|||
#endif
|
||||
#if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
|
||||
usb_host_ehci_itd_t ehciItd[USB_HOST_CONFIG_EHCI_MAX_ITD]; /*!< Idle ITD list array*/
|
||||
/* add additional 32bytes because the itd cannot cross over 4K boundary,
|
||||
* If one ITD cross over 4K boundary, the code will move 32 bytes for ITD.
|
||||
*/
|
||||
uint32_t reserved[8];
|
||||
#endif
|
||||
#if ((defined(USB_HOST_CONFIG_EHCI_MAX_SITD)) && (USB_HOST_CONFIG_EHCI_MAX_SITD > 0U))
|
||||
usb_host_ehci_sitd_t ehciSitd[USB_HOST_CONFIG_EHCI_MAX_SITD]; /*!< Idle SITD list array*/
|
||||
|
@ -488,6 +474,45 @@ extern usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandl
|
|||
uint32_t ioctlEvent,
|
||||
void *ioctlParam);
|
||||
|
||||
/*!
|
||||
* @brief control ehci bus.
|
||||
*
|
||||
* @param ehciInstance ehci instance pointer.
|
||||
* @param bus_control control code.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
extern usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl);
|
||||
|
||||
/*!
|
||||
* @brief ehci port change interrupt process function.
|
||||
*
|
||||
* @param ehciInstance ehci instance pointer.
|
||||
*/
|
||||
extern void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance);
|
||||
|
||||
/*!
|
||||
* @brief ehci timer0 interrupt process function.
|
||||
* cancel control/bulk transfer that time out.
|
||||
*
|
||||
* @param ehciInstance ehci instance pointer.
|
||||
*/
|
||||
extern void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance);
|
||||
|
||||
/*!
|
||||
* @brief host ehci start async schedule.
|
||||
*
|
||||
* @param ehciInstance ehci instance pointer.
|
||||
*/
|
||||
extern void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance);
|
||||
|
||||
/*!
|
||||
* @brief host ehci start periodic schedule.
|
||||
*
|
||||
* @param ehciInstance ehci instance pointer.
|
||||
*/
|
||||
extern void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <usb/include/usb_host_config.h>
|
||||
#include "usb_host.h"
|
||||
#include "usb_host_hci.h"
|
||||
#include "usb_host_devices.h"
|
||||
#include "usb_host_framework.h"
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "middleware.usb.host.fatfs_usb_stack"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
uint8_t *buffer,
|
||||
uint32_t bufferLen)
|
||||
{
|
||||
/* initialize transfer */
|
||||
transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)bufferLen);
|
||||
transfer->transferBuffer = buffer;
|
||||
transfer->transferLength = bufferLen;
|
||||
|
||||
if (USB_HostSendSetup(deviceInstance->hostHandle, deviceInstance->controlPipe, transfer) !=
|
||||
kStatus_USB_Success) /* send setup transfer */
|
||||
{
|
||||
#ifdef HOST_ECHO
|
||||
usb_echo("failed for USB_HostSendSetup\r\n");
|
||||
#endif
|
||||
(void)USB_HostFreeTransfer(deviceInstance->hostHandle, transfer);
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_get_status_param_t *statusParam;
|
||||
uint8_t length;
|
||||
|
||||
/* initialize transfer */
|
||||
statusParam = (usb_host_get_status_param_t *)param;
|
||||
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD;
|
||||
if (statusParam->requestType == (uint8_t)kRequestDevice)
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
|
||||
}
|
||||
else if (statusParam->requestType == (uint8_t)kRequestInterface)
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
|
||||
}
|
||||
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(statusParam->statusSelector);
|
||||
|
||||
length = 2;
|
||||
if (statusParam->statusSelector == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
|
||||
{
|
||||
length = 1;
|
||||
}
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, statusParam->statusBuffer, length);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_process_feature_param_t *featureParam;
|
||||
|
||||
/* initialize transfer */
|
||||
featureParam = (usb_host_process_feature_param_t *)param;
|
||||
if (featureParam->requestType == (uint8_t)kRequestDevice)
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
|
||||
}
|
||||
else if (featureParam->requestType == (uint8_t)kRequestInterface)
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
|
||||
}
|
||||
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->featureSelector);
|
||||
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->interfaceOrEndpoint);
|
||||
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
uint8_t address;
|
||||
|
||||
/* initialize transfer */
|
||||
address = *(uint8_t *)param;
|
||||
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(address);
|
||||
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_process_descriptor_param_t *descriptorParam;
|
||||
|
||||
/* initialize transfer */
|
||||
descriptorParam = (usb_host_process_descriptor_param_t *)param;
|
||||
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(
|
||||
(uint16_t)((uint16_t)descriptorParam->descriptorType << 8) | descriptorParam->descriptorIndex);
|
||||
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(descriptorParam->languageId);
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, descriptorParam->descriptorBuffer,
|
||||
descriptorParam->descriptorLength);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_get_interface_param_t *interfaceParam;
|
||||
|
||||
/* initialize transfer */
|
||||
interfaceParam = (usb_host_get_interface_param_t *)param;
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
||||
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(interfaceParam->interface);
|
||||
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, interfaceParam->alternateInterfaceBuffer, 1);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_set_interface_param_t *setParam;
|
||||
|
||||
/* initialize transfer */
|
||||
setParam = (usb_host_set_interface_param_t *)param;
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
||||
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(setParam->interface);
|
||||
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(setParam->alternateSetting);
|
||||
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_synch_frame_param_t *frameParam;
|
||||
|
||||
/* initialize transfer */
|
||||
frameParam = (usb_host_synch_frame_param_t *)param;
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
|
||||
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(frameParam->endpoint);
|
||||
|
||||
return USB_HostCh9RequestCommon(deviceInstance, transfer, frameParam->frameNumberBuffer, 2);
|
||||
}
|
||||
|
||||
usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
|
||||
uint8_t usbRequest,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param)
|
||||
{
|
||||
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
|
||||
if (deviceHandle == NULL)
|
||||
{
|
||||
return kStatus_USB_InvalidHandle;
|
||||
}
|
||||
|
||||
/* reset transfer fields */
|
||||
transfer->setupPacket->bmRequestType = 0x00;
|
||||
transfer->setupPacket->bRequest = usbRequest;
|
||||
transfer->setupPacket->wIndex = 0;
|
||||
transfer->setupPacket->wLength = 0;
|
||||
transfer->setupPacket->wValue = 0;
|
||||
|
||||
switch (usbRequest)
|
||||
{
|
||||
case USB_REQUEST_STANDARD_GET_STATUS: /* standard get status request */
|
||||
status = USB_HostStandardGetStatus(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_CLEAR_FEATURE: /* standard clear status request */
|
||||
case USB_REQUEST_STANDARD_SET_FEATURE: /* standard set feature request */
|
||||
status = USB_HostStandardSetClearFeature(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_SET_ADDRESS: /* standard set address request */
|
||||
status = USB_HostStandardSetAddress(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_GET_DESCRIPTOR: /* standard get descriptor request */
|
||||
case USB_REQUEST_STANDARD_SET_DESCRIPTOR: /* standard set descriptor request */
|
||||
if (usbRequest == USB_REQUEST_STANDARD_GET_DESCRIPTOR)
|
||||
{
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
||||
}
|
||||
status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_GET_CONFIGURATION: /* standard get configuration descriptor request */
|
||||
transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
|
||||
status =
|
||||
USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, (uint8_t *)param, 1);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_SET_CONFIGURATION: /* standard set configuration request */
|
||||
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(*((uint8_t *)param));
|
||||
status = USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, NULL, 0);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_GET_INTERFACE: /* standard get interface request */
|
||||
status = USB_HostStandardGetInterface(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_SET_INTERFACE: /* standard set interface request */
|
||||
status = USB_HostStandardSetInterface(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
case USB_REQUEST_STANDARD_SYNCH_FRAME: /* standard synch frame request */
|
||||
status = USB_HostStandardSyncFrame(deviceInstance, transfer, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
/*no action*/
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_HOST_CH9_H_
|
||||
#define _USB_HOST_CH9_H_
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @addtogroup usb_host_drv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief standard control transfer common code.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param buffer data buffer pointer.
|
||||
* @param bufferLen data length.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
uint8_t *buffer,
|
||||
uint32_t bufferLen);
|
||||
|
||||
/*!
|
||||
* @brief standard get status implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
|
||||
/*!
|
||||
* @brief standard set/clear feature implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
|
||||
/*!
|
||||
* @brief standard set address implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
|
||||
/*!
|
||||
* @brief standard set/get descriptor implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
|
||||
/*!
|
||||
* @brief standard get interface implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
|
||||
/*!
|
||||
* @brief standard set interface implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
|
||||
/*!
|
||||
* @brief standard sync frame implementation.
|
||||
*
|
||||
* @param deviceInstance device instance handle.
|
||||
* @param transfer transfer.
|
||||
* @param param parameter.
|
||||
*
|
||||
* @return kStatus_USB_Success or error codes.
|
||||
*/
|
||||
usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
|
||||
usb_host_transfer_t *transfer,
|
||||
void *param);
|
||||
#endif /* _USB_HOST_CH9_H_ */
|
|
@ -1,34 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* Copyright 2016 - 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <usb/include/usb_device_config.h>
|
||||
#include <usb/include/usb_host_config.h>
|
||||
#include "fsl_common.h"
|
||||
#include "usb_host.h"
|
||||
#include "usb_host_hci.h"
|
||||
|
@ -42,16 +20,24 @@
|
|||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "middleware.usb.host_stack"
|
||||
#endif
|
||||
|
||||
#if defined __CORTEX_M && (__CORTEX_M == 7U)
|
||||
#if (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
|
||||
#warning USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE is not supported.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
||||
|
||||
extern uint32_t USB_HostHubGetTotalThinkTime(usb_host_handle hostHandle, uint8_t parentHubNo);
|
||||
|
||||
extern usb_status_t USB_HostHubSuspendDevice(usb_host_handle hostHandle);
|
||||
|
||||
extern usb_status_t USB_HostHubResumeDevice(usb_host_handle hostHandle);
|
||||
#include "usb_host_hub.h"
|
||||
#include "usb_host_hub_app.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -77,15 +63,6 @@ static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance);
|
|||
static void USB_HostGetControllerInterface(uint8_t controllerId,
|
||||
const usb_host_controller_interface_t **controllerTable);
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
|
||||
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
|
||||
extern void USB_HostEhciTestModeInit(usb_device_handle devHandle);
|
||||
#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
|
||||
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
|
||||
extern void USB_HostIp3516HsTestModeInit(usb_device_handle devHandle);
|
||||
#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
|
||||
#endif /* USB_HOST_CONFIG_EHCI */
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
@ -94,8 +71,7 @@ usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
|
|||
|
||||
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
|
||||
#include "usb_host_ehci.h"
|
||||
static const usb_host_controller_interface_t s_EhciInterface = \
|
||||
{
|
||||
static const usb_host_controller_interface_t s_EhciInterface = {
|
||||
USB_HostEhciCreate, USB_HostEhciDestory, USB_HostEhciOpenPipe, USB_HostEhciClosePipe,
|
||||
USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl,
|
||||
};
|
||||
|
@ -103,8 +79,7 @@ static const usb_host_controller_interface_t s_EhciInterface = \
|
|||
|
||||
#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
|
||||
#include "usb_host_khci.h"
|
||||
static const usb_host_controller_interface_t s_KhciInterface = \
|
||||
{
|
||||
static const usb_host_controller_interface_t s_KhciInterface = {
|
||||
USB_HostKhciCreate, USB_HostKhciDestory, USB_HostKhciOpenPipe, USB_HostKhciClosePipe,
|
||||
USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl,
|
||||
};
|
||||
|
@ -112,8 +87,7 @@ static const usb_host_controller_interface_t s_KhciInterface = \
|
|||
|
||||
#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
|
||||
#include "usb_host_ohci.h"
|
||||
static const usb_host_controller_interface_t s_OhciInterface = \
|
||||
{
|
||||
static const usb_host_controller_interface_t s_OhciInterface = {
|
||||
USB_HostOhciCreate, USB_HostOhciDestory, USB_HostOhciOpenPipe, USB_HostOhciClosePipe,
|
||||
USB_HostOhciWritePipe, USB_HostOhciReadPipe, USB_HostOhciIoctl,
|
||||
};
|
||||
|
@ -121,65 +95,67 @@ static const usb_host_controller_interface_t s_OhciInterface = \
|
|||
|
||||
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
|
||||
#include "usb_host_ip3516hs.h"
|
||||
static const usb_host_controller_interface_t s_Ip3516HsInterface = \
|
||||
{
|
||||
static const usb_host_controller_interface_t s_Ip3516HsInterface = {
|
||||
USB_HostIp3516HsCreate, USB_HostIp3516HsDestory, USB_HostIp3516HsOpenPipe, USB_HostIp3516HsClosePipe,
|
||||
USB_HostIp3516HsWritePipe, USB_HostIp3516HsReadPipe, USB_HostIp3516HsIoctl,
|
||||
};
|
||||
#endif /* USB_HOST_CONFIG_IP3516HS */
|
||||
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)];
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)];
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
|
||||
/*FUNCTION*----------------------------------------------------------------
|
||||
*
|
||||
* Function Name : usb_test_mode_init
|
||||
* Returned Value : None
|
||||
* Comments :
|
||||
* This function is called by common class to initialize the class driver. It
|
||||
* is called in response to a select interface call by application
|
||||
*
|
||||
*END*--------------------------------------------------------------------*/
|
||||
*
|
||||
* Function Name : usb_test_mode_init
|
||||
* Returned Value : None
|
||||
* Comments :
|
||||
* This function is called by common class to initialize the class driver. It
|
||||
* is called in response to a select interface call by application
|
||||
*
|
||||
*END*--------------------------------------------------------------------*/
|
||||
usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
|
||||
{
|
||||
#if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \
|
||||
((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)))
|
||||
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
|
||||
#endif
|
||||
uint32_t productId;
|
||||
uint32_t vendorId;
|
||||
|
||||
usb_echo("usb host test init\r\n");
|
||||
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
|
||||
USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceVID, &vendorId);
|
||||
usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
|
||||
(void)usb_echo("usb host test init\r\n");
|
||||
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDevicePID, &productId);
|
||||
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceVID, &vendorId);
|
||||
(void)usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
|
||||
|
||||
if ((productId != 0x0200U) && (productId != 0x0101) && (productId != 0x0102) && (productId != 0x0103) &&
|
||||
(productId != 0x0104) && (productId != 0x0105) && (productId != 0x0106) && (productId != 0x0107) &&
|
||||
(productId != 0x0108))
|
||||
if ((productId != 0x0200U) && (productId != 0x0101U) && (productId != 0x0102U) && (productId != 0x0103U) &&
|
||||
(productId != 0x0104U) && (productId != 0x0105U) && (productId != 0x0106U) && (productId != 0x0107U) &&
|
||||
(productId != 0x0108U))
|
||||
{
|
||||
usb_echo("Unsupported Device\r\n");
|
||||
(void)usb_echo("Unsupported Device\r\n");
|
||||
}
|
||||
|
||||
if (productId == 0x0200U)
|
||||
{
|
||||
usb_echo("PET test device attached\r\n");
|
||||
(void)usb_echo("PET test device attached\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
|
||||
if (hostInstance->controllerTable == &s_EhciInterface)
|
||||
{
|
||||
USB_HostEhciTestModeInit(deviceHandle);
|
||||
(void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
|
||||
(void *)deviceHandle);
|
||||
}
|
||||
#elif((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
|
||||
#elif ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
|
||||
if (hostInstance->controllerTable == &s_Ip3516HsInterface)
|
||||
{
|
||||
USB_HostIp3516HsTestModeInit(deviceHandle);
|
||||
(void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
|
||||
(void *)deviceHandle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -190,13 +166,14 @@ usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
|
|||
|
||||
static usb_host_instance_t *USB_HostGetInstance(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t i = 0;
|
||||
uint32_t index = 0;
|
||||
USB_OSA_SR_ALLOC();
|
||||
USB_OSA_ENTER_CRITICAL();
|
||||
void *temp;
|
||||
OSA_SR_ALLOC();
|
||||
OSA_ENTER_CRITICAL();
|
||||
for (; i < USB_HOST_CONFIG_MAX_HOST; i++)
|
||||
{
|
||||
if (g_UsbHostInstance[i].occupied != 1)
|
||||
if (g_UsbHostInstance[i].occupied != 1U)
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i];
|
||||
for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++)
|
||||
|
@ -204,53 +181,53 @@ static usb_host_instance_t *USB_HostGetInstance(void)
|
|||
buffer[j] = 0x00U;
|
||||
}
|
||||
g_UsbHostInstance[i].occupied = 1;
|
||||
USB_OSA_EXIT_CRITICAL();
|
||||
OSA_EXIT_CRITICAL();
|
||||
for (index = 0; index < USB_HOST_CONFIG_MAX_TRANSFERS; ++index)
|
||||
{
|
||||
g_UsbHostInstance[i].transferList[index].setupPacket =
|
||||
(usb_setup_struct_t *)&(s_Setupbuffer[i][index][0]);
|
||||
temp = (void *)&(s_Setupbuffer[i][index][0]);
|
||||
g_UsbHostInstance[i].transferList[index].setupPacket = (usb_setup_struct_t *)temp;
|
||||
}
|
||||
return &g_UsbHostInstance[i];
|
||||
}
|
||||
}
|
||||
USB_OSA_EXIT_CRITICAL();
|
||||
OSA_EXIT_CRITICAL();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance)
|
||||
{
|
||||
USB_OSA_SR_ALLOC();
|
||||
USB_OSA_ENTER_CRITICAL();
|
||||
OSA_SR_ALLOC();
|
||||
OSA_ENTER_CRITICAL();
|
||||
hostInstance->occupied = 0;
|
||||
USB_OSA_EXIT_CRITICAL();
|
||||
OSA_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
static void USB_HostGetControllerInterface(uint8_t controllerId,
|
||||
const usb_host_controller_interface_t **controllerTable)
|
||||
{
|
||||
#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
|
||||
if (controllerId == kUSB_ControllerKhci0)
|
||||
if (controllerId == (uint8_t)kUSB_ControllerKhci0)
|
||||
{
|
||||
*controllerTable = &s_KhciInterface;
|
||||
}
|
||||
#endif /* USB_HOST_CONFIG_KHCI */
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
|
||||
if ((controllerId == kUSB_ControllerEhci0) || (controllerId == kUSB_ControllerEhci1))
|
||||
if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
|
||||
{
|
||||
*controllerTable = &s_EhciInterface;
|
||||
}
|
||||
#endif /* USB_HOST_CONFIG_EHCI */
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
|
||||
if (controllerId == kUSB_ControllerOhci0)
|
||||
if (controllerId == (uint8_t)kUSB_ControllerOhci0)
|
||||
{
|
||||
*controllerTable = &s_OhciInterface;
|
||||
}
|
||||
#endif /* USB_HOST_CONFIG_OHCI */
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
|
||||
if (controllerId == kUSB_ControllerIp3516Hs0)
|
||||
if (controllerId == (uint8_t)kUSB_ControllerIp3516Hs0)
|
||||
{
|
||||
*controllerTable = &s_Ip3516HsInterface;
|
||||
}
|
||||
|
@ -259,10 +236,10 @@ static void USB_HostGetControllerInterface(uint8_t controllerId,
|
|||
|
||||
usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = NULL;
|
||||
usb_host_transfer_t *transferPrev = NULL;
|
||||
uint8_t i = 0;
|
||||
uint8_t i = 0;
|
||||
|
||||
hostInstance = USB_HostGetInstance(); /* get one host instance */
|
||||
if (hostInstance == NULL)
|
||||
|
@ -291,10 +268,11 @@ usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, hos
|
|||
}
|
||||
|
||||
/* HOST instance init*/
|
||||
hostInstance->controllerId = controllerId;
|
||||
hostInstance->controllerId = controllerId;
|
||||
hostInstance->deviceCallback = callbackFn;
|
||||
hostInstance->deviceList = NULL;
|
||||
if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&hostInstance->hostMutex))
|
||||
hostInstance->deviceList = NULL;
|
||||
hostInstance->hostMutex = (osa_mutex_handle_t)(&hostInstance->mutexBuffer[0]);
|
||||
if (KOSA_StatusSuccess != OSA_MutexCreate(hostInstance->hostMutex))
|
||||
{
|
||||
USB_HostReleaseInstance(hostInstance);
|
||||
#ifdef HOST_ECHO
|
||||
|
@ -306,19 +284,19 @@ usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, hos
|
|||
/* initialize transfer list */
|
||||
|
||||
hostInstance->transferHead = &hostInstance->transferList[0];
|
||||
transferPrev = hostInstance->transferHead;
|
||||
transferPrev = hostInstance->transferHead;
|
||||
for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i)
|
||||
{
|
||||
transferPrev->next = &hostInstance->transferList[i];
|
||||
transferPrev = transferPrev->next;
|
||||
transferPrev = transferPrev->next;
|
||||
}
|
||||
|
||||
/* controller create */
|
||||
/* controller create, the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status =
|
||||
hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle));
|
||||
if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL))
|
||||
{
|
||||
USB_OsaMutexDestroy(hostInstance->hostMutex);
|
||||
(void)OSA_MutexDestroy(hostInstance->hostMutex);
|
||||
USB_HostReleaseInstance(hostInstance);
|
||||
#ifdef HOST_ECHO
|
||||
usb_echo("host init: controller init fail\r\n");
|
||||
|
@ -332,8 +310,8 @@ usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, hos
|
|||
|
||||
usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
usb_host_device_instance_t *deviceInstance = NULL;
|
||||
|
||||
if (hostHandle == NULL)
|
||||
|
@ -346,23 +324,23 @@ usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
|
|||
while (deviceInstance != NULL)
|
||||
{
|
||||
deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
|
||||
USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
|
||||
(void)USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
|
||||
}
|
||||
|
||||
/* controller instance destory */
|
||||
status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
|
||||
/* controller instance destroy, the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
|
||||
hostInstance->controllerHandle = NULL;
|
||||
if (status != kStatus_USB_Success)
|
||||
{
|
||||
#ifdef HOST_ECHO
|
||||
usb_echo("host controller destory fail\r\n");
|
||||
usb_echo("host controller destroy fail\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* resource release */
|
||||
if (hostInstance->hostMutex)
|
||||
if (NULL != hostInstance->hostMutex)
|
||||
{
|
||||
USB_OsaMutexDestroy(hostInstance->hostMutex);
|
||||
(void)OSA_MutexDestroy(hostInstance->hostMutex);
|
||||
hostInstance->hostMutex = NULL;
|
||||
}
|
||||
USB_HostReleaseInstance(hostInstance);
|
||||
|
@ -374,7 +352,7 @@ usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
|
|||
usb_host_pipe_handle *pipeHandle,
|
||||
usb_host_pipe_init_t *pipeInit)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
|
||||
if ((hostHandle == NULL) || (pipeInit == NULL))
|
||||
|
@ -382,7 +360,7 @@ usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
|
|||
return kStatus_USB_InvalidHandle;
|
||||
}
|
||||
|
||||
/* call controller open pipe interface */
|
||||
/* call controller open pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit);
|
||||
|
||||
return status;
|
||||
|
@ -390,7 +368,7 @@ usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
|
|||
|
||||
usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
|
||||
if ((hostHandle == NULL) || (pipeHandle == NULL))
|
||||
|
@ -398,7 +376,7 @@ usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle
|
|||
return kStatus_USB_InvalidHandle;
|
||||
}
|
||||
|
||||
/* call controller close pipe interface */
|
||||
/* call controller close pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle);
|
||||
|
||||
return status;
|
||||
|
@ -406,7 +384,7 @@ usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle
|
|||
|
||||
usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
|
||||
if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
|
||||
|
@ -416,9 +394,9 @@ usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeH
|
|||
|
||||
/* initialize transfer */
|
||||
transfer->transferSofar = 0;
|
||||
transfer->direction = USB_OUT;
|
||||
transfer->direction = USB_OUT;
|
||||
|
||||
USB_HostLock(); /* This api can be called by host task and app task */
|
||||
(void)USB_HostLock(); /* This api can be called by host task and app task */
|
||||
/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
|
||||
*/
|
||||
#if 0
|
||||
|
@ -435,9 +413,10 @@ usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeH
|
|||
DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
|
||||
}
|
||||
#endif
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
|
||||
|
||||
USB_HostUnlock();
|
||||
(void)USB_HostUnlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -445,7 +424,7 @@ usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
|
|||
usb_host_pipe_handle pipeHandle,
|
||||
usb_host_transfer_t *transfer)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
|
||||
if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
|
||||
|
@ -455,8 +434,8 @@ usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
|
|||
|
||||
/* initialize transfer */
|
||||
transfer->transferSofar = 0;
|
||||
transfer->next = NULL;
|
||||
transfer->setupStatus = 0;
|
||||
transfer->next = NULL;
|
||||
transfer->setupStatus = 0;
|
||||
if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
|
||||
{
|
||||
transfer->direction = USB_IN;
|
||||
|
@ -466,7 +445,7 @@ usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
|
|||
transfer->direction = USB_OUT;
|
||||
}
|
||||
|
||||
USB_HostLock(); /* This API can be called by host task and application task */
|
||||
(void)USB_HostLock(); /* This API can be called by host task and application task */
|
||||
/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
|
||||
*/
|
||||
#if 0
|
||||
|
@ -484,15 +463,16 @@ usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
|
|||
DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
|
||||
}
|
||||
#endif
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
|
||||
|
||||
USB_HostUnlock();
|
||||
(void)USB_HostUnlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
|
||||
if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
|
||||
|
@ -502,9 +482,9 @@ usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeH
|
|||
|
||||
/* initialize transfer */
|
||||
transfer->transferSofar = 0;
|
||||
transfer->direction = USB_IN;
|
||||
transfer->direction = USB_IN;
|
||||
|
||||
USB_HostLock(); /* This API can be called by host task and application task */
|
||||
(void)USB_HostLock(); /* This API can be called by host task and application task */
|
||||
/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
|
||||
*/
|
||||
#if 0
|
||||
|
@ -521,9 +501,10 @@ usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeH
|
|||
DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
|
||||
}
|
||||
#endif
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer);
|
||||
|
||||
USB_HostUnlock();
|
||||
(void)USB_HostUnlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -531,7 +512,7 @@ usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
|
|||
usb_host_pipe_handle pipeHandle,
|
||||
usb_host_transfer_t *transfer)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_status_t status = kStatus_USB_Success;
|
||||
usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
usb_host_cancel_param_t cancelParam;
|
||||
|
||||
|
@ -542,9 +523,10 @@ usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
|
|||
|
||||
/* initialize cancel parameter */
|
||||
cancelParam.pipeHandle = pipeHandle;
|
||||
cancelParam.transfer = transfer;
|
||||
cancelParam.transfer = transfer;
|
||||
|
||||
/* USB_HostLock(); This api can be called by host task and app task */
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer,
|
||||
&cancelParam);
|
||||
/* USB_HostUnlock(); */
|
||||
|
@ -562,18 +544,18 @@ usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfe
|
|||
}
|
||||
|
||||
/* get one from the transfer_head */
|
||||
USB_HostLock();
|
||||
(void)USB_HostLock();
|
||||
if (hostInstance->transferHead != NULL)
|
||||
{
|
||||
*transfer = hostInstance->transferHead;
|
||||
*transfer = hostInstance->transferHead;
|
||||
hostInstance->transferHead = hostInstance->transferHead->next;
|
||||
USB_HostUnlock();
|
||||
(void)USB_HostUnlock();
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
*transfer = NULL;
|
||||
USB_HostUnlock();
|
||||
(void)USB_HostUnlock();
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
}
|
||||
|
@ -592,10 +574,10 @@ usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_
|
|||
}
|
||||
|
||||
/* release one to the transfer_head */
|
||||
USB_HostLock();
|
||||
transfer->next = hostInstance->transferHead;
|
||||
(void)USB_HostLock();
|
||||
transfer->next = hostInstance->transferHead;
|
||||
hostInstance->transferHead = transfer;
|
||||
USB_HostUnlock();
|
||||
(void)USB_HostUnlock();
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
|
@ -604,23 +586,28 @@ usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHand
|
|||
uint32_t *infoValue)
|
||||
{
|
||||
usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
|
||||
uint32_t *temp;
|
||||
usb_host_dev_info_t devInfo;
|
||||
if ((deviceHandle == NULL) || (infoValue == NULL))
|
||||
{
|
||||
return kStatus_USB_InvalidParameter;
|
||||
}
|
||||
|
||||
switch (infoCode)
|
||||
devInfo = (usb_host_dev_info_t)infoCode;
|
||||
switch (devInfo)
|
||||
{
|
||||
case kUSB_HostGetDeviceAddress: /* device address */
|
||||
|
||||
*infoValue = (uint32_t)deviceInstance->setAddress;
|
||||
break;
|
||||
|
||||
case kUSB_HostGetDeviceControlPipe: /* device control pipe */
|
||||
*infoValue = (uint32_t)deviceInstance->controlPipe;
|
||||
temp = (uint32_t *)deviceInstance->controlPipe;
|
||||
*infoValue = (uint32_t)temp;
|
||||
break;
|
||||
|
||||
case kUSB_HostGetHostHandle: /* device host handle */
|
||||
*infoValue = (uint32_t)deviceInstance->hostHandle;
|
||||
temp = (uint32_t *)deviceInstance->hostHandle;
|
||||
*infoValue = (uint32_t)temp;
|
||||
break;
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
||||
|
@ -685,7 +672,8 @@ usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHand
|
|||
break;
|
||||
|
||||
default:
|
||||
return kStatus_USB_Error;
|
||||
/*no action*/
|
||||
break;
|
||||
}
|
||||
|
||||
return kStatus_USB_Success;
|
||||
|
@ -698,26 +686,27 @@ usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle inter
|
|||
uint32_t endPosition;
|
||||
usb_descriptor_union_t *unionDes;
|
||||
usb_host_ep_t *epParse;
|
||||
|
||||
void *temp;
|
||||
if (interfaceHandle == NULL)
|
||||
{
|
||||
return kStatus_USB_InvalidHandle;
|
||||
}
|
||||
|
||||
if (alternateSetting == 0)
|
||||
if (alternateSetting == 0U)
|
||||
{
|
||||
return kStatus_USB_InvalidParameter;
|
||||
}
|
||||
|
||||
/* parse configuration descriptor */
|
||||
unionDes = (usb_descriptor_union_t *)((usb_host_interface_t *)interfaceHandle)
|
||||
->interfaceDesc; /* interface extend descriptor start */
|
||||
temp = (void *)((usb_host_interface_t *)interfaceHandle)->interfaceDesc;
|
||||
;
|
||||
unionDes = (usb_descriptor_union_t *)temp; /* interface extend descriptor start */
|
||||
endPosition =
|
||||
(uint32_t)unionDes +
|
||||
((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength; /* interface extend descriptor end */
|
||||
unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
|
||||
|
||||
/* search for the alternate setting interface descritpor */
|
||||
/* search for the alternate setting interface descriptor */
|
||||
while ((uint32_t)unionDes < endPosition)
|
||||
{
|
||||
if (unionDes->interface.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
|
||||
|
@ -742,12 +731,12 @@ usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle inter
|
|||
}
|
||||
|
||||
/* initialize interface handle structure instance */
|
||||
interface->interfaceDesc = &unionDes->interface;
|
||||
interface->alternateSettingNumber = 0;
|
||||
interface->epCount = 0;
|
||||
interface->interfaceExtension = NULL;
|
||||
interface->interfaceExtensionLength = 0;
|
||||
interface->interfaceIndex = unionDes->interface.bInterfaceNumber;
|
||||
interface->interfaceDesc = &unionDes->interface;
|
||||
interface->alternateSettingNumber = 0U;
|
||||
interface->epCount = 0U;
|
||||
interface->interfaceExtension = NULL;
|
||||
interface->interfaceExtensionLength = 0U;
|
||||
interface->interfaceIndex = unionDes->interface.bInterfaceNumber;
|
||||
|
||||
/* search for endpoint descriptor start position */
|
||||
unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
|
||||
|
@ -770,7 +759,7 @@ usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle inter
|
|||
}
|
||||
|
||||
/* parse endpoint descriptor */
|
||||
if (interface->interfaceDesc->bNumEndpoints != 0)
|
||||
if (interface->interfaceDesc->bNumEndpoints != 0U)
|
||||
{
|
||||
if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
|
||||
(interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
|
||||
|
@ -790,11 +779,12 @@ usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle inter
|
|||
#endif
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
epParse = (usb_host_ep_t *)&interface->epList[interface->epCount];
|
||||
epParse->epDesc = (usb_descriptor_endpoint_t *)unionDes;
|
||||
epParse = (usb_host_ep_t *)&interface->epList[interface->epCount];
|
||||
temp = (void *)unionDes;
|
||||
epParse->epDesc = (usb_descriptor_endpoint_t *)temp;
|
||||
epParse->epExtensionLength = 0;
|
||||
epParse->epExtension = NULL;
|
||||
unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
|
||||
epParse->epExtension = NULL;
|
||||
unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
|
||||
while ((uint32_t)unionDes < endPosition)
|
||||
{
|
||||
if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
|
||||
|
@ -820,7 +810,7 @@ usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle inter
|
|||
|
||||
void USB_HostGetVersion(uint32_t *version)
|
||||
{
|
||||
if (version)
|
||||
if (NULL != version)
|
||||
{
|
||||
*version =
|
||||
(uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
|
||||
|
@ -828,12 +818,12 @@ void USB_HostGetVersion(uint32_t *version)
|
|||
}
|
||||
|
||||
#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
|
||||
/* Send BUS or specific device suepend request */
|
||||
/* Send BUS or specific device suspend request */
|
||||
usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
|
||||
{
|
||||
usb_host_instance_t *hostInstance;
|
||||
usb_host_device_instance_t *deviceInstance;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_host_bus_control_t type = kUSB_HostBusSuspend;
|
||||
|
||||
if (hostHandle == NULL)
|
||||
|
@ -849,6 +839,7 @@ usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_devic
|
|||
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
||||
status = USB_HostHubSuspendDevice(hostInstance);
|
||||
#else
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status =
|
||||
hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
|
||||
#endif
|
||||
|
@ -857,11 +848,12 @@ usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_devic
|
|||
{
|
||||
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
||||
deviceInstance = (usb_host_device_instance_t *)deviceHandle;
|
||||
if (0 == deviceInstance->hubNumber)
|
||||
if (0U == deviceInstance->hubNumber)
|
||||
{
|
||||
#endif
|
||||
if (hostInstance->deviceList == deviceHandle)
|
||||
{
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
|
||||
kUSB_HostBusControl, &type);
|
||||
}
|
||||
|
@ -888,7 +880,7 @@ usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device
|
|||
{
|
||||
usb_host_instance_t *hostInstance;
|
||||
usb_host_device_instance_t *deviceInstance;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_host_bus_control_t type = kUSB_HostBusResume;
|
||||
|
||||
if (hostHandle == NULL)
|
||||
|
@ -905,6 +897,7 @@ usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device
|
|||
|
||||
if (NULL == deviceHandle)
|
||||
{
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status =
|
||||
hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
|
||||
}
|
||||
|
@ -912,11 +905,12 @@ usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device
|
|||
{
|
||||
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
||||
deviceInstance = (usb_host_device_instance_t *)deviceHandle;
|
||||
if (0 == deviceInstance->hubNumber)
|
||||
if (0U == deviceInstance->hubNumber)
|
||||
{
|
||||
#endif
|
||||
if (hostInstance->deviceList == deviceHandle)
|
||||
{
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
|
||||
kUSB_HostBusControl, &type);
|
||||
}
|
||||
|
@ -935,13 +929,13 @@ usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device
|
|||
return status;
|
||||
}
|
||||
#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
|
||||
/* Send BUS or specific device suepend request */
|
||||
/* Send BUS or specific device suspend request */
|
||||
usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
|
||||
usb_device_handle deviceHandle,
|
||||
uint8_t sleepType)
|
||||
{
|
||||
usb_host_instance_t *hostInstance;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_host_bus_control_t type = kUSB_HostBusL1Sleep;
|
||||
|
||||
if (hostHandle == NULL)
|
||||
|
@ -955,8 +949,9 @@ usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
|
|||
if (1U == sleepType)
|
||||
{
|
||||
/*#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))*/
|
||||
/*To do, implete hub L1 suspend device*/
|
||||
/*To do, incomplete hub L1 suspend device*/
|
||||
/*#else*/
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status =
|
||||
hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
|
||||
/*#endif*/
|
||||
|
@ -968,6 +963,7 @@ usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
|
|||
#endif
|
||||
if (hostInstance->deviceList == deviceHandle)
|
||||
{
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
|
||||
&type);
|
||||
}
|
||||
|
@ -978,7 +974,7 @@ usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
|
|||
}
|
||||
return status;
|
||||
}
|
||||
/* Send BUS or specific device suepend request */
|
||||
/* Send BUS or specific device suspend request */
|
||||
usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam)
|
||||
{
|
||||
usb_host_instance_t *hostInstance;
|
||||
|
@ -989,7 +985,7 @@ usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uin
|
|||
return kStatus_USB_InvalidHandle;
|
||||
}
|
||||
hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status =
|
||||
hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostL1Config, lpmParam);
|
||||
|
||||
|
@ -1003,7 +999,7 @@ usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
|
|||
{
|
||||
usb_host_instance_t *hostInstance;
|
||||
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
usb_host_bus_control_t type = kUSB_HostBusL1Resume;
|
||||
|
||||
if (hostHandle == NULL)
|
||||
|
@ -1014,17 +1010,19 @@ usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
|
|||
|
||||
if (1U == sleepType)
|
||||
{
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status =
|
||||
hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
||||
/*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
|
||||
/*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
|
||||
|
||||
#endif
|
||||
if (hostInstance->deviceList == deviceHandle)
|
||||
{
|
||||
/* the callbackFn is initialized in USB_HostGetControllerInterface */
|
||||
status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
|
||||
&type);
|
||||
}
|
||||
|
@ -1050,3 +1048,18 @@ usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick)
|
|||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((defined(USB_HOST_CONFIG_BATTERY_CHARGER)) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U))
|
||||
usb_status_t USB_HostSetChargerType(usb_host_handle hostHandle, uint8_t type)
|
||||
{
|
||||
usb_host_instance_t *hostInstance;
|
||||
|
||||
if (hostHandle == NULL)
|
||||
{
|
||||
return kStatus_USB_InvalidHandle;
|
||||
}
|
||||
hostInstance = (usb_host_instance_t *)hostHandle;
|
||||
return hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostSetChargerType,
|
||||
&type);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,31 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* Copyright 2016 - 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_HOST_HCI_H_
|
||||
|
@ -36,9 +14,9 @@
|
|||
******************************************************************************/
|
||||
|
||||
/*! @brief USB host lock */
|
||||
#define USB_HostLock() USB_OsaMutexLock(hostInstance->hostMutex)
|
||||
#define USB_HostLock() OSA_MutexLock(hostInstance->hostMutex, USB_OSA_WAIT_TIMEOUT)
|
||||
/*! @brief USB host unlock */
|
||||
#define USB_HostUnlock() USB_OsaMutexUnlock(hostInstance->hostMutex)
|
||||
#define USB_HostUnlock() OSA_MutexUnlock(hostInstance->hostMutex)
|
||||
|
||||
/*!
|
||||
* @addtogroup usb_host_controller_driver
|
||||
|
@ -56,6 +34,10 @@ typedef enum _usb_host_controller_control
|
|||
kUSB_HostPortAttachDisable, /*!< Disable the port attach event */
|
||||
kUSB_HostPortAttachEnable, /*!< Enable the port attach event */
|
||||
kUSB_HostL1Config, /*!< L1 suspend Bus control code */
|
||||
kUSB_HostSetChargerType, /*!< set charger type */
|
||||
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
|
||||
kUSB_HostTestModeInit, /*!< intialize charger type */
|
||||
#endif
|
||||
} usb_host_controller_control_t;
|
||||
|
||||
/*! @brief USB host controller bus control code */
|
||||
|
@ -97,7 +79,9 @@ typedef struct _usb_host_controller_interface
|
|||
uint32_t ioctlEvent,
|
||||
void *ioctlParam); /*!< Control a controller function prototype*/
|
||||
} usb_host_controller_interface_t;
|
||||
|
||||
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
|
||||
usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle);
|
||||
#endif
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
|
@ -110,7 +94,8 @@ typedef struct _usb_host_instance
|
|||
{
|
||||
void *controllerHandle; /*!< The low level controller handle*/
|
||||
host_callback_t deviceCallback; /*!< Device attach/detach callback*/
|
||||
usb_osa_mutex_handle hostMutex; /*!< Host layer mutex*/
|
||||
osa_mutex_handle_t hostMutex; /*!< Host layer mutex*/
|
||||
uint32_t mutexBuffer[(OSA_MUTEX_HANDLE_SIZE + 3) / 4]; /*!< Host layer mutex*/
|
||||
usb_host_transfer_t transferList[USB_HOST_CONFIG_MAX_TRANSFERS]; /*!< Transfer resource*/
|
||||
usb_host_transfer_t *transferHead; /*!< Idle transfer head*/
|
||||
const usb_host_controller_interface_t *controllerTable; /*!< KHCI/EHCI interface*/
|
||||
|
@ -126,6 +111,7 @@ typedef struct _usb_host_instance
|
|||
uint8_t controllerId; /*!< The controller ID*/
|
||||
} usb_host_instance_t;
|
||||
|
||||
extern usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _USB_HOST_HCI_H_ */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <fsl_common.h>
|
||||
#include <fsl_os_abstraction.h>
|
||||
#include "usb_misc.h"
|
||||
#include "usb_spec.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 - 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_HOST_CONFIG_H_
|
||||
#define _USB_HOST_CONFIG_H_
|
||||
|
||||
/* Host Controller Enable */
|
||||
/*!
|
||||
* @brief host khci instance count, meantime it indicates khci enable or disable.
|
||||
* - if 0, host khci driver is disable.
|
||||
* - if greater than 0, host khci driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_KHCI (0U)
|
||||
|
||||
/*!
|
||||
* @brief host ehci instance count, meantime it indicates ehci enable or disable.
|
||||
* - if 0, host ehci driver is disable.
|
||||
* - if greater than 0, host ehci driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_EHCI (2U)
|
||||
|
||||
/*!
|
||||
* @brief host ohci instance count, meantime it indicates ohci enable or disable.
|
||||
* - if 0, host ohci driver is disable.
|
||||
* - if greater than 0, host ohci driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_OHCI (0U)
|
||||
|
||||
/*!
|
||||
* @brief host ip3516hs instance count, meantime it indicates ohci enable or disable.
|
||||
* - if 0, host ip3516hs driver is disable.
|
||||
* - if greater than 0, host ip3516hs driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_IP3516HS (0U)
|
||||
|
||||
/* Common configuration macros for all controllers */
|
||||
|
||||
/*!
|
||||
* @brief host driver instance max count.
|
||||
* for example: 2 - one for khci, one for ehci.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_MAX_HOST \
|
||||
(USB_HOST_CONFIG_KHCI + USB_HOST_CONFIG_EHCI + USB_HOST_CONFIG_OHCI + USB_HOST_CONFIG_IP3516HS)
|
||||
|
||||
/*!
|
||||
* @brief host pipe max count.
|
||||
* pipe is the host driver resource for device endpoint, one endpoint need one pipe.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_MAX_PIPES (16U)
|
||||
|
||||
/*!
|
||||
* @brief host transfer max count.
|
||||
* transfer is the host driver resource for data transmission mission, one transmission mission need one transfer.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_MAX_TRANSFERS (16U)
|
||||
|
||||
/*!
|
||||
* @brief the max endpoint for one interface.
|
||||
* the max endpoint descriptor number that one interface descriptor contain.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_INTERFACE_MAX_EP (4U)
|
||||
|
||||
/*!
|
||||
* @brief the max interface for one configuration.
|
||||
* the max interface descriptor number that one configuration descriptor can contain.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE (5U)
|
||||
|
||||
/*!
|
||||
* @brief the max power for one device.
|
||||
* the max power the host can provide for one device.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_MAX_POWER (250U)
|
||||
|
||||
/*!
|
||||
* @brief the max retries for enumeration.
|
||||
* retry time when enumeration fail.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES (3U)
|
||||
|
||||
/*!
|
||||
* @brief the max retries for enumeration setup stall.
|
||||
* the max times for one transfer can stall.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES (1U)
|
||||
|
||||
/*!
|
||||
* @brief the max NAK count for one transaction.
|
||||
* when nak count reach to the value, the transaction fail.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_MAX_NAK (3000U)
|
||||
|
||||
/*! @brief Whether the transfer buffer is cache-enabled or not. */
|
||||
#ifndef USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE
|
||||
#define USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U)
|
||||
#endif
|
||||
/*! @brief if 1, enable usb compliance test codes; if 0, disable usb compliance test codes. */
|
||||
#define USB_HOST_CONFIG_COMPLIANCE_TEST (0U)
|
||||
|
||||
/*! @brief if 1, class driver clear stall automatically; if 0, class driver don't clear stall. */
|
||||
#define USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL (0U)
|
||||
|
||||
/* KHCI configuration */
|
||||
#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
|
||||
|
||||
/*!
|
||||
* @brief khci dma align fix buffer size.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER (64U)
|
||||
|
||||
#endif
|
||||
|
||||
/* EHCI configuration */
|
||||
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
|
||||
|
||||
/*!
|
||||
* @brief ehci periodic frame list size.
|
||||
* the value can be 1024, 512, 256, 128, 64, 32, 16 or 8.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
|
||||
|
||||
/*!
|
||||
* @brief ehci QH max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_EHCI_MAX_QH (8U)
|
||||
|
||||
/*!
|
||||
* @brief ehci QTD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_EHCI_MAX_QTD (8U)
|
||||
|
||||
/*!
|
||||
* @brief ehci ITD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_EHCI_MAX_ITD (0U)
|
||||
|
||||
/*!
|
||||
* @brief ehci SITD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_EHCI_MAX_SITD (0U)
|
||||
|
||||
#endif
|
||||
|
||||
/* OHCI configuration */
|
||||
#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI))
|
||||
|
||||
/*!
|
||||
* @brief ohci ED max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_OHCI_MAX_ED (8U)
|
||||
|
||||
/*!
|
||||
* @brief ohci GTD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_OHCI_MAX_GTD (8U)
|
||||
|
||||
/*!
|
||||
* @brief ohci ITD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_OHCI_MAX_ITD (8U)
|
||||
|
||||
#endif
|
||||
|
||||
/* OHCI configuration */
|
||||
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
|
||||
|
||||
#define USB_HOST_CONFIG_IP3516HS_MAX_PIPE (32U)
|
||||
|
||||
/*!
|
||||
* @brief ohci ED max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_IP3516HS_MAX_ATL (32U)
|
||||
|
||||
/*!
|
||||
* @brief ohci GTD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_IP3516HS_MAX_INT (32U)
|
||||
|
||||
/*!
|
||||
* @brief ohci ITD max count.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_IP3516HS_MAX_ISO (0U)
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief host HUB class instance count, meantime it indicates HUB class enable or disable.
|
||||
* - if 0, host HUB class driver is disable.
|
||||
* - if greater than 0, host HUB class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_HUB (0U)
|
||||
|
||||
/*!
|
||||
* @brief host HID class instance count, meantime it indicates HID class enable or disable.
|
||||
* - if 0, host HID class driver is disable.
|
||||
* - if greater than 0, host HID class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_HID (0U)
|
||||
|
||||
/*!
|
||||
* @brief host MSD class instance count, meantime it indicates MSD class enable or disable.
|
||||
* - if 0, host MSD class driver is disable.
|
||||
* - if greater than 0, host MSD class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_MSD (0U)
|
||||
|
||||
/*!
|
||||
* @brief host CDC class instance count, meantime it indicates CDC class enable or disable.
|
||||
* - if 0, host CDC class driver is disable.
|
||||
* - if greater than 0, host CDC class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_CDC (0U)
|
||||
|
||||
/*!
|
||||
* @brief host AUDIO class instance count, meantime it indicates AUDIO class enable or disable.
|
||||
* - if 0, host AUDIO class driver is disable.
|
||||
* - if greater than 0, host AUDIO class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_AUDIO (0U)
|
||||
|
||||
/*!
|
||||
* @brief host PHDC class instance count, meantime it indicates PHDC class enable or disable.
|
||||
* - if 0, host PHDC class driver is disable.
|
||||
* - if greater than 0, host PHDC class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_PHDC (0U)
|
||||
|
||||
/*!
|
||||
* @brief host printer class instance count, meantime it indicates printer class enable or disable.
|
||||
* - if 0, host printer class driver is disable.
|
||||
* - if greater than 0, host printer class driver is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_PRINTER (0U)
|
||||
|
||||
/*!
|
||||
* @brief host charger detect enable or disable. It is only supported on RT600 currently.
|
||||
* - if 0, host charger detect is disable.
|
||||
* - if greater than 0, host charger detect is enable.
|
||||
*/
|
||||
#define USB_HOST_CONFIG_BATTERY_CHARGER (0U)
|
||||
|
||||
#endif /* _USB_HOST_CONFIG_H_ */
|
|
@ -1,46 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* Copyright 2016, 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __USB_MISC_H__
|
||||
#define __USB_MISC_H__
|
||||
|
||||
#ifndef ENDIANNESS
|
||||
|
||||
#error ENDIANNESS should be defined, and then rebulid the project.
|
||||
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Define big endian */
|
||||
#define USB_BIG_ENDIAN (0U)
|
||||
/*! @brief Define little endian */
|
||||
#define USB_LITTLE_ENDIAN (1U)
|
||||
|
||||
/*! @brief Define current endian */
|
||||
#ifndef ENDIANNESS
|
||||
#define ENDIANNESS USB_LITTLE_ENDIAN
|
||||
#endif
|
||||
/*! @brief Define default timeout value */
|
||||
#if (defined(USE_RTOS) && (USE_RTOS > 0))
|
||||
#define USB_OSA_WAIT_TIMEOUT (osaWaitForever_c)
|
||||
#else
|
||||
#define USB_OSA_WAIT_TIMEOUT (0U)
|
||||
#endif /* (defined(USE_RTOS) && (USE_RTOS > 0)) */
|
||||
|
||||
/*! @brief Define USB printf */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
@ -52,10 +40,14 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef __DSC__
|
||||
#if defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE < 1)
|
||||
#define usb_echo printf
|
||||
#else
|
||||
#define usb_echo DbgConsole_Printf
|
||||
#define usb_echo rt_kprintf
|
||||
#endif
|
||||
#else
|
||||
#define usb_echo
|
||||
#endif
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
|
@ -78,7 +70,7 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
#define STRUCT_UNPACKED __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#elif defined(__CC_ARM)
|
||||
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION))
|
||||
|
||||
#ifndef STRUCT_PACKED
|
||||
#define STRUCT_PACKED _Pragma("pack(1U)")
|
||||
|
@ -112,7 +104,7 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
|
||||
#define USB_ASSIGN_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
|
||||
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
|
||||
*((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \
|
||||
*((uint8_t *)&(n) + 2) = *((uint8_t *)&(m) + 2); \
|
||||
*((uint8_t *)&(n) + 3) = *((uint8_t *)&(m) + 3); \
|
||||
|
@ -120,13 +112,13 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
|
||||
#define USB_ASSIGN_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
|
||||
*((uint8_t *)&(n)) = *((uint8_t *)&(m)); \
|
||||
*((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \
|
||||
}
|
||||
|
||||
#define USB_ASSIGN_MACRO_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(n)) = (uint8_t)m; \
|
||||
*((uint8_t *)&(n)) = (uint8_t)m; \
|
||||
*((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \
|
||||
*((uint8_t *)&(n) + 2) = (uint8_t)(m >> 16); \
|
||||
*((uint8_t *)&(n) + 3) = (uint8_t)(m >> 24); \
|
||||
|
@ -134,7 +126,7 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
|
||||
#define USB_ASSIGN_MACRO_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(n)) = (uint8_t)m; \
|
||||
*((uint8_t *)&(n)) = (uint8_t)m; \
|
||||
*((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \
|
||||
}
|
||||
|
||||
|
@ -150,65 +142,66 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
#define USB_SHORT_FROM_BIG_ENDIAN(n) (n)
|
||||
#define USB_LONG_FROM_BIG_ENDIAN(n) (n)
|
||||
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[3] = ((n >> 24U) & 0xFFU); \
|
||||
m[2] = ((n >> 16U) & 0xFFU); \
|
||||
m[1] = ((n >> 8U) & 0xFFU); \
|
||||
m[0] = (n & 0xFFU); \
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[3] = (uint8_t)((((uint32_t)(n)) >> 24U) & 0xFFU); \
|
||||
m[2] = (uint8_t)((((uint32_t)(n)) >> 16U) & 0xFFU); \
|
||||
m[1] = (uint8_t)((((uint32_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[0] = (uint8_t)(((uint32_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \
|
||||
(((uint8_t)n[0]) << 0U)))
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint32_t)n[3]) << 24U) | (((uint32_t)n[2]) << 16U) | (((uint32_t)n[1]) << 8U) | \
|
||||
(((uint32_t)n[0]) << 0U)))
|
||||
|
||||
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((n >> 24U) & 0xFFU); \
|
||||
m[1] = ((n >> 16U) & 0xFFU); \
|
||||
m[2] = ((n >> 8U) & 0xFFU); \
|
||||
m[3] = (n & 0xFFU); \
|
||||
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
|
||||
m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
|
||||
m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[3] = (((uint32_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \
|
||||
(((uint8_t)n[3]) << 0U)))
|
||||
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint32_t)n[0]) << 24U) | (((uint32_t)n[1]) << 16U) | (((uint32_t)n[2]) << 8U) | \
|
||||
(((uint32_t)n[3]) << 0U)))
|
||||
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[1] = ((n >> 8U) & 0xFFU); \
|
||||
m[0] = (n & 0xFFU); \
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[0] = (((uint16_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U)))
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[1]) << 8U) | (((uint16_t)n[0]) << 0U)))
|
||||
|
||||
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((n >> 8U) & 0xFFU); \
|
||||
m[1] = (n & 0xFFU); \
|
||||
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[1] = (((uint16_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U)))
|
||||
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[0]) << 8U) | (((uint16_t)n[1]) << 0U)))
|
||||
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 3) = ((n >> 24U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 2) = ((n >> 16U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 0) = (n & 0xFFU); \
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
|
||||
((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \
|
||||
((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U)))
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
|
||||
((uint32_t)(((uint32_t)(*((uint8_t *)&(n) + 3)) << 24U) | ((uint32_t)(*((uint8_t *)&(n) + 2)) << 16U) | \
|
||||
((uint32_t)(*((uint8_t *)&(n) + 1)) << 8U) | ((uint32_t)(*((uint8_t *)&(n))) << 0U)))
|
||||
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m)) = ((n)&0xFFU); \
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))))))
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) \
|
||||
((uint16_t)((uint16_t)(*((uint8_t *)&(n) + 1)) << 8U) | ((uint16_t)(*((uint8_t *)&(n)))))
|
||||
|
||||
#else
|
||||
|
||||
|
@ -222,75 +215,76 @@ extern int DbgConsole_Printf(const char *fmt_s, ...);
|
|||
#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
|
||||
#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
|
||||
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[3] = ((n >> 24U) & 0xFFU); \
|
||||
m[2] = ((n >> 16U) & 0xFFU); \
|
||||
m[1] = ((n >> 8U) & 0xFFU); \
|
||||
m[0] = (n & 0xFFU); \
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[3] = (uint8_t)((((uint32_t)(n)) >> 24U) & 0xFFU); \
|
||||
m[2] = (uint8_t)((((uint32_t)(n)) >> 16U) & 0xFFU); \
|
||||
m[1] = (uint8_t)((((uint32_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[0] = (uint8_t)(((uint32_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \
|
||||
(((uint8_t)n[0]) << 0U)))
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint32_t)n[3]) << 24U) | (((uint32_t)n[2]) << 16U) | (((uint32_t)n[1]) << 8U) | \
|
||||
(((uint32_t)n[0]) << 0U)))
|
||||
|
||||
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((n >> 24U) & 0xFFU); \
|
||||
m[1] = ((n >> 16U) & 0xFFU); \
|
||||
m[2] = ((n >> 8U) & 0xFFU); \
|
||||
m[3] = (n & 0xFFU); \
|
||||
#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
|
||||
m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
|
||||
m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[3] = (((uint32_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \
|
||||
(((uint8_t)n[3]) << 0U)))
|
||||
#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
|
||||
((uint32_t)((((uint32_t)n[0]) << 24U) | (((uint32_t)n[1]) << 16U) | (((uint32_t)n[2]) << 8U) | \
|
||||
(((uint32_t)n[3]) << 0U)))
|
||||
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[1] = ((n >> 8U) & 0xFFU); \
|
||||
m[0] = (n & 0xFFU); \
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[0] = (((uint16_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U)))
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[1]) << 8U) | (((uint16_t)n[0]) << 0U)))
|
||||
|
||||
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((n >> 8U) & 0xFFU); \
|
||||
m[1] = (n & 0xFFU); \
|
||||
#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
|
||||
{ \
|
||||
m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
|
||||
m[1] = (((uint16_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U)))
|
||||
#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[0]) << 8U) | (((uint16_t)n[1]) << 0U)))
|
||||
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 3) = ((n >> 24U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 2) = ((n >> 16U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 0) = (n & 0xFFU); \
|
||||
#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
|
||||
((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \
|
||||
((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U)))
|
||||
#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \
|
||||
((uint32_t)(((uint32_t)(*((uint8_t *)&(n) + 3)) << 24U) | ((uint32_t)(*((uint8_t *)&(n) + 2)) << 16U) | \
|
||||
((uint32_t)(*((uint8_t *)&(n) + 1)) << 8U) | ((uint32_t)(*((uint8_t *)&(n))) << 0U)))
|
||||
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m)) = ((n)&0xFFU); \
|
||||
#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \
|
||||
{ \
|
||||
*((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \
|
||||
*((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \
|
||||
}
|
||||
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))))))
|
||||
#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) \
|
||||
((uint16_t)(((uint16_t)(*(((uint8_t *)&(n)) + 1)) << 8U) | ((uint16_t)(*((uint8_t *)&(n))))))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALIGNMENT, etc) are only used for USB device stack.
|
||||
* The USB device global variables are put into the section m_usb_global and m_usb_bdt or the section
|
||||
* .bss.m_usb_global and .bss.m_usb_bdt by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device
|
||||
* The USB device global variables are put into the section m_usb_global and m_usb_bdt
|
||||
* by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device
|
||||
* global variables can be linked into USB dedicated RAM by USB_STACK_USE_DEDICATED_RAM.
|
||||
* The MACRO USB_STACK_USE_DEDICATED_RAM is used to decide the USB stack uses dedicated RAM or not. The value of
|
||||
* the marco can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT.
|
||||
* the macro can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT.
|
||||
* The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL means USB device global variables, including USB_BDT and
|
||||
* USB_GLOBAL, are put into the USB dedicated RAM. This feature can only be enabled when the USB dedicated RAM
|
||||
* is not less than 2K Bytes.
|
||||
|
@ -313,40 +307,63 @@ _Pragma("diag_suppress=Pm120")
|
|||
#define USB_RAM_ADDRESS_ALIGNMENT(n) USB_ALIGN_PRAGMA(data_alignment = n)
|
||||
_Pragma("diag_suppress=Pm120")
|
||||
#define USB_LINK_SECTION_PART(str) _Pragma(#str)
|
||||
#define USB_LINK_SECTION_SUB(sec) USB_LINK_SECTION_PART(location = #sec)
|
||||
#define USB_LINK_DMA_INIT_DATA(sec) USB_LINK_SECTION_PART(location = #sec)
|
||||
#define USB_LINK_USB_GLOBAL _Pragma("location = \"m_usb_global\"")
|
||||
#define USB_LINK_USB_BDT _Pragma("location = \"m_usb_bdt\"")
|
||||
#define USB_LINK_USB_GLOBAL_BSS _Pragma("location = \".bss.m_usb_global\"")
|
||||
#define USB_LINK_USB_BDT_BSS _Pragma("location = \".bss.m_usb_bdt\"")
|
||||
#define USB_LINK_USB_GLOBAL_BSS
|
||||
#define USB_LINK_USB_BDT_BSS
|
||||
_Pragma("diag_default=Pm120")
|
||||
#define USB_LINK_DMA_NONINIT_DATA _Pragma("location = \"m_usb_dma_noninit_data\"")
|
||||
#define USB_LINK_NONCACHE_NONINIT_DATA _Pragma("location = \"NonCacheable\"")
|
||||
#elif defined(__CC_ARM)
|
||||
#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION))
|
||||
|
||||
#define USB_WEAK_VAR __attribute__((weak))
|
||||
#define USB_WEAK_FUN __weak
|
||||
#define USB_WEAK_FUN __attribute__((weak))
|
||||
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
|
||||
#define USB_LINK_SECTION_SUB(sec) __attribute__((section(#sec)))
|
||||
#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec)))
|
||||
#if defined(__CC_ARM)
|
||||
#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init))
|
||||
#else
|
||||
#define USB_LINK_USB_GLOBAL __attribute__((section(".bss.m_usb_global")))
|
||||
#endif
|
||||
#if defined(__CC_ARM)
|
||||
#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init))
|
||||
#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global"))) __attribute__((zero_init))
|
||||
#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt"))) __attribute__((zero_init))
|
||||
#else
|
||||
#define USB_LINK_USB_BDT __attribute__((section(".bss.m_usb_bdt")))
|
||||
#endif
|
||||
#define USB_LINK_USB_GLOBAL_BSS
|
||||
#define USB_LINK_USB_BDT_BSS
|
||||
#if defined(__CC_ARM)
|
||||
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data"))) __attribute__((zero_init))
|
||||
#else
|
||||
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section(".bss.m_usb_dma_noninit_data")))
|
||||
#endif
|
||||
#if defined(__CC_ARM)
|
||||
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable"))) __attribute__((zero_init))
|
||||
#else
|
||||
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section(".bss.NonCacheable")))
|
||||
#endif
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define USB_WEAK_VAR __attribute__((weak))
|
||||
#define USB_WEAK_FUN __attribute__((weak))
|
||||
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
|
||||
#define USB_LINK_SECTION_SUB(sec) __attribute__((section(#sec)))
|
||||
#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec)))
|
||||
#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global, \"aw\", %nobits @")))
|
||||
#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt, \"aw\", %nobits @")))
|
||||
#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global, \"aw\", %nobits @")))
|
||||
#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt, \"aw\", %nobits @")))
|
||||
#define USB_LINK_USB_GLOBAL_BSS
|
||||
#define USB_LINK_USB_BDT_BSS
|
||||
#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data, \"aw\", %nobits @")))
|
||||
#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable, \"aw\", %nobits @")))
|
||||
|
||||
#elif (defined(__DSC__) && defined(__CW__))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define USB_WEAK_VAR __attribute__((weak))
|
||||
#define USB_WEAK_FUN __attribute__((weak))
|
||||
#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n)))
|
||||
#define USB_LINK_USB_BDT_BSS
|
||||
#define USB_LINK_USB_GLOBAL_BSS
|
||||
#else
|
||||
#error The tool-chain is not supported.
|
||||
#endif
|
||||
|
@ -356,28 +373,32 @@ _Pragma("diag_suppress=Pm120")
|
|||
|
||||
#if ((defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) && (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
|
||||
#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#elif(defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))
|
||||
#elif (defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))
|
||||
#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, 0)
|
||||
#elif(defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))
|
||||
#elif (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))
|
||||
#define USB_CACHE_LINESIZE MAX(0, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#else
|
||||
#define USB_CACHE_LINESIZE 4
|
||||
#define USB_CACHE_LINESIZE 4U
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define USB_CACHE_LINESIZE 4
|
||||
#define USB_CACHE_LINESIZE 4U
|
||||
#endif
|
||||
|
||||
#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \
|
||||
((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)))
|
||||
#define USB_DATA_ALIGN 64
|
||||
#define USB_DATA_ALIGN 64U
|
||||
#else
|
||||
#define USB_DATA_ALIGN 4
|
||||
#define USB_DATA_ALIGN 4U
|
||||
#endif
|
||||
|
||||
#define USB_DATA_ALIGN_SIZE MAX(USB_CACHE_LINESIZE, USB_DATA_ALIGN)
|
||||
#if (USB_CACHE_LINESIZE > USB_DATA_ALIGN)
|
||||
#define USB_DATA_ALIGN_SIZE USB_CACHE_LINESIZE
|
||||
#else
|
||||
#define USB_DATA_ALIGN_SIZE USB_DATA_ALIGN
|
||||
#endif
|
||||
|
||||
#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) ((n + USB_DATA_ALIGN_SIZE - 1) & (~(USB_DATA_ALIGN_SIZE - 1)))
|
||||
#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) (((n) + USB_DATA_ALIGN_SIZE - 1U) & (~(USB_DATA_ALIGN_SIZE - 1U)))
|
||||
|
||||
#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL)
|
||||
|
||||
|
@ -387,13 +408,19 @@ _Pragma("diag_suppress=Pm120")
|
|||
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \
|
||||
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
|
||||
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_SECTION_SUB(m_usb_dma_init_data)
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
|
||||
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#else
|
||||
#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE))
|
||||
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init)
|
||||
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#else
|
||||
#define USB_DMA_DATA_NONINIT_SUB
|
||||
#define USB_DMA_DATA_INIT_SUB
|
||||
#define USB_CONTROLLER_DATA USB_LINK_USB_GLOBAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT)
|
||||
|
||||
|
@ -403,7 +430,13 @@ _Pragma("diag_suppress=Pm120")
|
|||
(defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
|
||||
#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA
|
||||
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_SECTION_SUB(m_usb_dma_init_data)
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
|
||||
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#else
|
||||
#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE))
|
||||
#define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init)
|
||||
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#else
|
||||
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
|
||||
|
@ -411,6 +444,7 @@ _Pragma("diag_suppress=Pm120")
|
|||
#define USB_DMA_DATA_INIT_SUB
|
||||
#define USB_CONTROLLER_DATA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
|
@ -420,9 +454,17 @@ _Pragma("diag_suppress=Pm120")
|
|||
#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA
|
||||
#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_SECTION_SUB(m_usb_dma_init_data)
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data)
|
||||
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
|
||||
|
||||
#else
|
||||
|
||||
#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE))
|
||||
#define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init)
|
||||
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
|
||||
#else
|
||||
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
|
||||
#define USB_BDT USB_LINK_USB_BDT_BSS
|
||||
|
@ -433,6 +475,8 @@ _Pragma("diag_suppress=Pm120")
|
|||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define USB_DMA_NONINIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_NONINIT_SUB
|
||||
#define USB_DMA_INIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_INIT_SUB
|
||||
|
||||
|
|
|
@ -844,7 +844,7 @@ int nu_usbh_register(void)
|
|||
RT_ASSERT(res == RT_EOK);
|
||||
|
||||
/*initialize the usb host function */
|
||||
res = rt_usb_host_init();
|
||||
res = rt_usb_host_init("usbh");
|
||||
RT_ASSERT(res == RT_EOK);
|
||||
|
||||
#if defined(RT_USING_PM)
|
||||
|
|
|
@ -130,7 +130,7 @@ void rt_init_thread_entry(void* parameter)
|
|||
#endif
|
||||
|
||||
#ifdef RT_USING_USB_HOST
|
||||
rt_usb_host_init();
|
||||
rt_usb_host_init("usbh");
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
|
|
|
@ -241,7 +241,7 @@ int stm_usbh_register(void)
|
|||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
rt_usb_host_init();
|
||||
rt_usb_host_init("usbh");
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
|
|
@ -642,6 +642,14 @@ menu "Using USB"
|
|||
string "Udisk mount dir"
|
||||
default "/"
|
||||
endif
|
||||
config RT_USBH_HID
|
||||
bool "Enable HID Drivers"
|
||||
default n
|
||||
if RT_USBH_HID
|
||||
config RT_USBH_HID_MOUSE
|
||||
bool "Enable HID mouse protocol"
|
||||
default n
|
||||
endif
|
||||
endif
|
||||
config RT_USING_USB_DEVICE
|
||||
bool "Using USB device"
|
||||
|
|
|
@ -136,7 +136,8 @@ struct uhcd
|
|||
struct rt_device parent;
|
||||
uhcd_ops_t ops;
|
||||
rt_uint8_t num_ports;
|
||||
uhub_t roothub;
|
||||
uhub_t roothub;
|
||||
struct rt_messagequeue *usb_mq;
|
||||
};
|
||||
typedef struct uhcd* uhcd_t;
|
||||
|
||||
|
@ -163,7 +164,7 @@ struct uhost_msg
|
|||
typedef struct uhost_msg* uhost_msg_t;
|
||||
|
||||
/* usb host system interface */
|
||||
rt_err_t rt_usb_host_init(void);
|
||||
rt_err_t rt_usb_host_init(const char *name);
|
||||
void rt_usbh_hub_init(struct uhcd *hcd);
|
||||
|
||||
/* usb host core interface */
|
||||
|
@ -203,7 +204,7 @@ rt_err_t rt_usbh_hub_clear_port_feature(uhub_t uhub, rt_uint16_t port,
|
|||
rt_err_t rt_usbh_hub_set_port_feature(uhub_t uhub, rt_uint16_t port,
|
||||
rt_uint16_t feature);
|
||||
rt_err_t rt_usbh_hub_reset_port(uhub_t uhub, rt_uint16_t port);
|
||||
rt_err_t rt_usbh_event_signal(struct uhost_msg* msg);
|
||||
rt_err_t rt_usbh_event_signal(uhcd_t uhcd, struct uhost_msg* msg);
|
||||
|
||||
|
||||
void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool_t isHS);
|
||||
|
|
|
@ -26,7 +26,7 @@ static rt_list_t _protocal_list;
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id)
|
||||
rt_err_t rt_usbh_hid_set_idle(struct uhintf* intf, int duration, int report_id)
|
||||
{
|
||||
struct urequest setup;
|
||||
struct uinstance* device;
|
||||
|
@ -40,14 +40,15 @@ rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id)
|
|||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_INTERFACE;
|
||||
setup.request = USB_REQ_SET_IDLE;
|
||||
setup.index = 0;
|
||||
setup.length = 0;
|
||||
setup.value = (duration << 8 )| report_id;
|
||||
setup.bRequest = USB_REQ_SET_IDLE;
|
||||
setup.wIndex = 0;
|
||||
setup.wLength = 0;
|
||||
setup.wValue = (duration << 8 )| report_id;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0,
|
||||
timeout) == 0) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
return RT_EOK;
|
||||
else
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,7 +60,7 @@ rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id)
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type,
|
||||
rt_err_t rt_usbh_hid_get_report(struct uhintf* intf, rt_uint8_t type,
|
||||
rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size)
|
||||
{
|
||||
struct urequest setup;
|
||||
|
@ -74,14 +75,24 @@ rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type,
|
|||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_INTERFACE;
|
||||
setup.request = USB_REQ_GET_REPORT;
|
||||
setup.index = intf->intf_desc->bInterfaceNumber;
|
||||
setup.length = size;
|
||||
setup.value = (type << 8 ) + id;
|
||||
setup.bRequest = USB_REQ_GET_REPORT;
|
||||
setup.wIndex = intf->intf_desc->bInterfaceNumber;
|
||||
setup.wLength = size;
|
||||
setup.wValue = (type << 8 ) + id;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, size,
|
||||
timeout) == size) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, size, timeout) == size)
|
||||
{
|
||||
if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return -RT_FALSE;
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +104,7 @@ rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type,
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_t size)
|
||||
rt_err_t rt_usbh_hid_set_report(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size)
|
||||
{
|
||||
struct urequest setup;
|
||||
struct uinstance* device;
|
||||
|
@ -107,14 +118,15 @@ rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_
|
|||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_INTERFACE;
|
||||
setup.request = USB_REQ_SET_REPORT;
|
||||
setup.index = intf->intf_desc->bInterfaceNumber;
|
||||
setup.length = size;
|
||||
setup.value = 0x02 << 8;
|
||||
setup.bRequest = USB_REQ_SET_REPORT;
|
||||
setup.wIndex = intf->intf_desc->bInterfaceNumber;
|
||||
setup.wLength = size;
|
||||
setup.wValue = 0x02 << 8;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, size,
|
||||
timeout) == size) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
return RT_EOK;
|
||||
else
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,7 +137,7 @@ rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol)
|
||||
rt_err_t rt_usbh_hid_set_protocal(struct uhintf* intf, int protocol)
|
||||
{
|
||||
struct urequest setup;
|
||||
struct uinstance* device;
|
||||
|
@ -139,14 +151,15 @@ rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol)
|
|||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_INTERFACE;
|
||||
setup.request = USB_REQ_SET_PROTOCOL;
|
||||
setup.index = 0;
|
||||
setup.length = 0;
|
||||
setup.value = protocol;
|
||||
setup.bRequest = USB_REQ_SET_PROTOCOL;
|
||||
setup.wIndex = 0;
|
||||
setup.wLength = 0;
|
||||
setup.wValue = protocol;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0,
|
||||
timeout) == 0) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
return RT_EOK;
|
||||
else
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,7 +172,7 @@ rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol)
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hid_get_report_descriptor(struct uintf* intf,
|
||||
rt_err_t rt_usbh_hid_get_report_descriptor(struct uhintf* intf,
|
||||
rt_uint8_t *buffer, rt_size_t size)
|
||||
{
|
||||
struct urequest setup;
|
||||
|
@ -174,14 +187,24 @@ rt_err_t rt_usbh_hid_get_report_descriptor(struct uintf* intf,
|
|||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD|
|
||||
USB_REQ_TYPE_INTERFACE;
|
||||
setup.request = USB_REQ_GET_DESCRIPTOR;
|
||||
setup.index = 0;
|
||||
setup.length = size;
|
||||
setup.value = USB_DESC_TYPE_REPORT << 8;
|
||||
setup.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup.wIndex = 0;
|
||||
setup.wLength = size;
|
||||
setup.wValue = USB_DESC_TYPE_REPORT << 8;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, size,
|
||||
timeout) == size) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, size, timeout) == size)
|
||||
{
|
||||
if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return -RT_FALSE;
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,16 +243,16 @@ static void rt_usbh_hid_callback(void* context)
|
|||
RT_ASSERT(context != RT_NULL);
|
||||
|
||||
pipe = (upipe_t)context;
|
||||
hid = (struct uhid*)pipe->intf->user_data;
|
||||
hid = (struct uhid*)((struct uhintf*)pipe->inst)->user_data;
|
||||
|
||||
/* invoke protocal callback function */
|
||||
hid->protocal->callback((void*)hid);
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(pipe->intf->device->hcd != RT_NULL);
|
||||
RT_ASSERT(((struct uhintf*)pipe->inst)->device->hcd != RT_NULL);
|
||||
|
||||
rt_usb_hcd_int_xfer(pipe->intf->device->hcd, pipe, hid->buffer,
|
||||
pipe->ep.wMaxPacketSize, timeout);
|
||||
rt_usb_hcd_pipe_xfer(((struct uhintf*)pipe->inst)->device->hcd, pipe,
|
||||
hid->buffer, pipe->ep.wMaxPacketSize, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,9 +291,7 @@ static rt_err_t rt_usbh_hid_enable(void* arg)
|
|||
int i = 0, pro_id;
|
||||
uprotocal_t protocal;
|
||||
struct uhid* hid;
|
||||
struct uintf* intf = (struct uintf*)arg;
|
||||
int timeout = USB_TIMEOUT_BASIC;
|
||||
upipe_t pipe;
|
||||
struct uhintf* intf = (struct uhintf*)arg;
|
||||
|
||||
/* parameter check */
|
||||
if(intf == RT_NULL)
|
||||
|
@ -319,19 +340,13 @@ static rt_err_t rt_usbh_hid_enable(void* arg)
|
|||
if(!(ep_desc->bEndpointAddress & USB_DIR_IN)) continue;
|
||||
|
||||
ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &hid->pipe_in,
|
||||
intf, ep_desc, rt_usbh_hid_callback);
|
||||
intf, ep_desc);
|
||||
if(ret != RT_EOK) return ret;
|
||||
}
|
||||
|
||||
/* initialize hid protocal */
|
||||
hid->protocal->init((void*)intf);
|
||||
pipe = hid->pipe_in;
|
||||
hid->protocal->init((void*)intf);
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(pipe->intf->device->hcd != RT_NULL);
|
||||
|
||||
rt_usb_hcd_int_xfer(pipe->intf->device->hcd, hid->pipe_in,
|
||||
hid->buffer, hid->pipe_in->ep.wMaxPacketSize, timeout);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
@ -346,7 +361,7 @@ static rt_err_t rt_usbh_hid_enable(void* arg)
|
|||
static rt_err_t rt_usbh_hid_disable(void* arg)
|
||||
{
|
||||
struct uhid* hid;
|
||||
struct uintf* intf = (struct uintf*)arg;
|
||||
struct uhintf* intf = (struct uhintf*)arg;
|
||||
|
||||
RT_ASSERT(intf != RT_NULL);
|
||||
|
||||
|
@ -364,9 +379,6 @@ static rt_err_t rt_usbh_hid_disable(void* arg)
|
|||
/* free the hid instance */
|
||||
rt_free(hid);
|
||||
}
|
||||
|
||||
/* free the instance */
|
||||
rt_free(intf);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
|
|
@ -31,11 +31,11 @@ typedef struct uhid uhid_t;
|
|||
#define USB_HID_KEYBOARD 1
|
||||
#define USB_HID_MOUSE 2
|
||||
|
||||
rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id);
|
||||
rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type, rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size);
|
||||
rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_t size);
|
||||
rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol);
|
||||
rt_err_t rt_usbh_hid_get_report_descriptor(struct uintf* intf, rt_uint8_t *buffer, rt_size_t size);
|
||||
rt_err_t rt_usbh_hid_set_idle(struct uhintf* intf, int duration, int report_id);
|
||||
rt_err_t rt_usbh_hid_get_report(struct uhintf* intf, rt_uint8_t type, rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size);
|
||||
rt_err_t rt_usbh_hid_set_report(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size);
|
||||
rt_err_t rt_usbh_hid_set_protocal(struct uhintf* intf, int protocol);
|
||||
rt_err_t rt_usbh_hid_get_report_descriptor(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size);
|
||||
rt_err_t rt_usbh_hid_protocal_register(uprotocal_t protocal);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -126,15 +126,36 @@ static rt_err_t rt_usbh_hid_mouse_callback(void* arg)
|
|||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_thread_t mouse_thread;
|
||||
void mouse_task(void* param)
|
||||
{
|
||||
struct uhintf* intf = (struct uhintf*)param;
|
||||
while (1)
|
||||
{
|
||||
if (rt_usb_hcd_pipe_xfer(intf->device->hcd, ((struct uhid*)intf->user_data)->pipe_in,
|
||||
((struct uhid*)intf->user_data)->buffer, ((struct uhid*)intf->user_data)->pipe_in->ep.wMaxPacketSize,
|
||||
USB_TIMEOUT_BASIC) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
rt_usbh_hid_mouse_callback(intf->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static rt_err_t rt_usbh_hid_mouse_init(void* arg)
|
||||
{
|
||||
struct uintf* intf = (struct uintf*)arg;
|
||||
struct uhintf* intf = (struct uhintf*)arg;
|
||||
|
||||
RT_ASSERT(intf != RT_NULL);
|
||||
|
||||
rt_usbh_hid_set_protocal(intf, 0);
|
||||
|
||||
rt_usbh_hid_set_idle(intf, 10, 0);
|
||||
rt_usbh_hid_set_idle(intf, 0, 0);
|
||||
|
||||
mouse_thread = rt_thread_create("mouse0", mouse_task, intf, 500, 8, 100);
|
||||
rt_thread_startup(mouse_thread);
|
||||
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("start usb mouse\n"));
|
||||
#ifdef RT_USING_RTGUI
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <drivers/usb_host.h>
|
||||
|
||||
static rt_list_t _driver_list;
|
||||
static rt_bool_t _driver_list_created = RT_FALSE;
|
||||
|
||||
/**
|
||||
* This function will initilize the usb class driver related data structure,
|
||||
|
@ -22,8 +23,11 @@ static rt_list_t _driver_list;
|
|||
*/
|
||||
rt_err_t rt_usbh_class_driver_init(void)
|
||||
{
|
||||
rt_list_init(&_driver_list);
|
||||
|
||||
if (_driver_list_created == RT_FALSE)
|
||||
{
|
||||
rt_list_init(&_driver_list);
|
||||
_driver_list_created = RT_TRUE;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
@ -39,8 +43,11 @@ rt_err_t rt_usbh_class_driver_register(ucd_t drv)
|
|||
{
|
||||
if (drv == RT_NULL) return -RT_ERROR;
|
||||
|
||||
/* insert class driver into driver list */
|
||||
rt_list_insert_after(&_driver_list, &(drv->list));
|
||||
if (rt_usbh_class_driver_find(drv->class_code, drv->subclass_code) == RT_NULL)
|
||||
{
|
||||
/* insert class driver into driver list */
|
||||
rt_list_insert_after(&_driver_list, &(drv->list));
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
#define USB_THREAD_STACK_SIZE 4096
|
||||
|
||||
static struct rt_messagequeue *usb_mq;
|
||||
// static struct rt_messagequeue *usb_mq;
|
||||
static struct uclass_driver hub_driver;
|
||||
static struct uhub root_hub;
|
||||
// static struct uhub root_hub;
|
||||
|
||||
static rt_err_t root_hub_ctrl(struct uhcd *hcd, rt_uint16_t port, rt_uint8_t cmd, void *args)
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool
|
|||
{
|
||||
hcd->roothub->port_status[port - 1] |= PORT_LSDA;
|
||||
}
|
||||
rt_usbh_event_signal(&msg);
|
||||
rt_usbh_event_signal(hcd, &msg);
|
||||
}
|
||||
|
||||
void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port)
|
||||
|
@ -102,7 +102,7 @@ void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port)
|
|||
msg.content.hub = hcd->roothub;
|
||||
hcd->roothub->port_status[port - 1] |= PORT_CCSC;
|
||||
hcd->roothub->port_status[port - 1] &= ~PORT_CCS;
|
||||
rt_usbh_event_signal(&msg);
|
||||
rt_usbh_event_signal(hcd, &msg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -647,12 +647,13 @@ ucd_t rt_usbh_class_driver_hub(void)
|
|||
*/
|
||||
static void rt_usbh_hub_thread_entry(void* parameter)
|
||||
{
|
||||
uhcd_t hcd = (uhcd_t)parameter;
|
||||
while(1)
|
||||
{
|
||||
struct uhost_msg msg;
|
||||
|
||||
/* receive message */
|
||||
if(rt_mq_recv(usb_mq, &msg, sizeof(struct uhost_msg), RT_WAITING_FOREVER)
|
||||
if(rt_mq_recv(hcd->usb_mq, &msg, sizeof(struct uhost_msg), RT_WAITING_FOREVER)
|
||||
!= RT_EOK ) continue;
|
||||
|
||||
//RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type));
|
||||
|
@ -679,12 +680,12 @@ static void rt_usbh_hub_thread_entry(void* parameter)
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_event_signal(struct uhost_msg* msg)
|
||||
rt_err_t rt_usbh_event_signal(uhcd_t hcd, struct uhost_msg* msg)
|
||||
{
|
||||
RT_ASSERT(msg != RT_NULL);
|
||||
|
||||
/* send message to usb message queue */
|
||||
rt_mq_send(usb_mq, (void*)msg, sizeof(struct uhost_msg));
|
||||
rt_mq_send(hcd->usb_mq, (void*)msg, sizeof(struct uhost_msg));
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
@ -698,16 +699,17 @@ rt_err_t rt_usbh_event_signal(struct uhost_msg* msg)
|
|||
void rt_usbh_hub_init(uhcd_t hcd)
|
||||
{
|
||||
rt_thread_t thread;
|
||||
/* link root hub to hcd */
|
||||
root_hub.is_roothub = RT_TRUE;
|
||||
hcd->roothub = &root_hub;
|
||||
root_hub.hcd = hcd;
|
||||
root_hub.num_ports = hcd->num_ports;
|
||||
/* create root hub for hcd */
|
||||
hcd->roothub = rt_malloc(sizeof(struct uhub));
|
||||
rt_memset(hcd->roothub, 0, sizeof(struct uhub));
|
||||
hcd->roothub->is_roothub = RT_TRUE;
|
||||
hcd->roothub->hcd = hcd;
|
||||
hcd->roothub->num_ports = hcd->num_ports;
|
||||
/* create usb message queue */
|
||||
usb_mq = rt_mq_create("usbh", 32, 16, RT_IPC_FLAG_FIFO);
|
||||
hcd->usb_mq = rt_mq_create(hcd->parent.parent.name, 32, 16, RT_IPC_FLAG_FIFO);
|
||||
|
||||
/* create usb hub thread */
|
||||
thread = rt_thread_create("usbh", rt_usbh_hub_thread_entry, RT_NULL,
|
||||
thread = rt_thread_create(hcd->parent.parent.name, rt_usbh_hub_thread_entry, hcd,
|
||||
USB_THREAD_STACK_SIZE, 8, 20);
|
||||
if(thread != RT_NULL)
|
||||
{
|
||||
|
|
|
@ -22,15 +22,15 @@
|
|||
*
|
||||
* @return none.
|
||||
*/
|
||||
rt_err_t rt_usb_host_init(void)
|
||||
rt_err_t rt_usb_host_init(const char *name)
|
||||
{
|
||||
ucd_t drv;
|
||||
rt_device_t uhc;
|
||||
|
||||
uhc = rt_device_find(USB_HOST_CONTROLLER_NAME);
|
||||
uhc = rt_device_find(name);
|
||||
if(uhc == RT_NULL)
|
||||
{
|
||||
rt_kprintf("can't find usb host controller %s\n", USB_HOST_CONTROLLER_NAME);
|
||||
rt_kprintf("can't find usb host controller %s\n", name);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,16 @@ rt_err_t rt_usb_host_init(void)
|
|||
/* register mass storage class driver */
|
||||
drv = rt_usbh_class_driver_storage();
|
||||
rt_usbh_class_driver_register(drv);
|
||||
#endif
|
||||
#ifdef RT_USBH_HID
|
||||
/* register mass storage class driver */
|
||||
drv = rt_usbh_class_driver_hid();
|
||||
rt_usbh_class_driver_register(drv);
|
||||
#ifdef RT_USBH_HID_MOUSE
|
||||
uprotocal_t protocal;
|
||||
protocal = rt_usbh_hid_protocal_mouse();
|
||||
rt_usbh_hid_protocal_register(protocal);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* register hub class driver */
|
||||
|
|
Loading…
Reference in New Issue