608 lines
22 KiB
C
608 lines
22 KiB
C
|
/**
|
||
|
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||
|
*
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||
|
* are permitted provided that the following conditions are met:
|
||
|
*
|
||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||
|
* list of conditions and the following disclaimer.
|
||
|
*
|
||
|
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||
|
* Semiconductor ASA integrated circuit in a product or a software update for
|
||
|
* such product, 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.
|
||
|
*
|
||
|
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||
|
* contributors may be used to endorse or promote products derived from this
|
||
|
* software without specific prior written permission.
|
||
|
*
|
||
|
* 4. This software, with or without modification, must only be used with a
|
||
|
* Nordic Semiconductor ASA integrated circuit.
|
||
|
*
|
||
|
* 5. Any software provided in binary form under this license must not be reverse
|
||
|
* engineered, decompiled, modified and/or disassembled.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||
|
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
*/
|
||
|
#ifndef APP_USBD_HID_H__
|
||
|
#define APP_USBD_HID_H__
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <stdbool.h>
|
||
|
|
||
|
#include "sdk_common.h"
|
||
|
#include "nrf_atomic.h"
|
||
|
#include "app_usbd_hid_types.h"
|
||
|
#include "app_usbd.h"
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @defgroup app_usbd_hid USB HID class
|
||
|
* @ingroup app_usbd
|
||
|
*
|
||
|
* @brief @tagAPI52840 Module with generic HID event data processing.
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
#define APP_USBD_HID_IFACE_IDX 0 /**< @brief HID instance interface index. */
|
||
|
#define APP_USBD_HID_EPIN_IDX 0 /**< @brief HID instance endpoint IN index. */
|
||
|
#define APP_USBD_HID_EPOUT_IDX 1 /**< @brief HID instance endpoint OUT index.*/
|
||
|
|
||
|
/**
|
||
|
* @brief HID context state flags.
|
||
|
*
|
||
|
* Bit numbers in @ref app_usbd_hid_ctx_t::state_flags.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
APP_USBD_HID_STATE_FLAG_APPENDED = 0, /**< State flag APPENDED. */
|
||
|
APP_USBD_HID_STATE_FLAG_STARTED = 1, /**< State flag STARTED. */
|
||
|
APP_USBD_HID_STATE_FLAG_SUSPENDED = 2, /**< State flag SUSPENDED. */
|
||
|
APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS = 3, /**< State flag TRANS_IN_PROGRESS. */
|
||
|
} app_usbd_hid_state_flag_t;
|
||
|
|
||
|
/**
|
||
|
* @brief Events passed to user event handler.
|
||
|
*
|
||
|
* @note Example prototype of user event handler:
|
||
|
@code
|
||
|
void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
||
|
app_usbd_hid_mouse_user_event_t event);
|
||
|
@endcode
|
||
|
*/
|
||
|
typedef enum {
|
||
|
APP_USBD_HID_USER_EVT_SET_BOOT_PROTO, /**< Event SET_BOOT_PROTOCOL. */
|
||
|
APP_USBD_HID_USER_EVT_SET_REPORT_PROTO, /**< Event SET_REPORT_PROTOCOL. */
|
||
|
APP_USBD_HID_USER_EVT_OUT_REPORT_READY, /**< Event OUT_REPORT_READY. */
|
||
|
APP_USBD_HID_USER_EVT_IN_REPORT_DONE, /**< Event IN_REPORT_DONE. */
|
||
|
APP_USBD_HID_USER_EVT_FEATURE_REPORT_READY, /**< Event FEATURE_REPORT_READY. */
|
||
|
} app_usbd_hid_user_event_t;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief User event handler.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
* @param[in] event User event.
|
||
|
*/
|
||
|
typedef void (*app_usbd_hid_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
|
||
|
app_usbd_hid_user_event_t event);
|
||
|
|
||
|
/**
|
||
|
* @brief Idle report handler.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
* @param[in] report_id Number of report ID that needs idle transfer.
|
||
|
*/
|
||
|
typedef ret_code_t (*app_usbd_hid_idle_handler_t)(app_usbd_class_inst_t const * p_inst,
|
||
|
uint8_t report_id);
|
||
|
|
||
|
/**
|
||
|
* @brief HID unified interface
|
||
|
* */
|
||
|
typedef struct {
|
||
|
|
||
|
/**
|
||
|
* @brief Function called on HID specific, GetReport request.
|
||
|
*
|
||
|
* This function should trigger data write to control pipe.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
* @param[in] p_setup_ev Setup event.
|
||
|
*
|
||
|
* @return Standard error code.
|
||
|
*/
|
||
|
ret_code_t (*on_get_report)(app_usbd_class_inst_t const * p_inst,
|
||
|
app_usbd_setup_evt_t const * p_setup_ev);
|
||
|
|
||
|
/**
|
||
|
* @brief Function called on HID specific, SetReport request.
|
||
|
*
|
||
|
* This function should trigger data read from control pipe. This function is not required and
|
||
|
* NULL could be pinned to this handler when output report is not defined in report descriptor.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
* @param[in] p_setup_ev Setup event.
|
||
|
*
|
||
|
* @return Standard error code.
|
||
|
*/
|
||
|
ret_code_t (*on_set_report)(app_usbd_class_inst_t const * p_inst,
|
||
|
app_usbd_setup_evt_t const * p_setup_ev);
|
||
|
|
||
|
/**
|
||
|
* @brief Function called on IN endpoint transfer.
|
||
|
*
|
||
|
* This function should trigger next endpoint IN transfer if required.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
*
|
||
|
* @return Standard error code.
|
||
|
*/
|
||
|
ret_code_t (*ep_transfer_in)(app_usbd_class_inst_t const * p_inst);
|
||
|
|
||
|
/**
|
||
|
* @brief Function called on OUT endpoint transfer.
|
||
|
*
|
||
|
* This function should should read data from OUT endpoint. This function is not required and
|
||
|
* NULL could be pinned to this handler when class doesn't have OUT endpoint.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
*
|
||
|
* @return Standard error code.
|
||
|
*/
|
||
|
ret_code_t (*ep_transfer_out)(app_usbd_class_inst_t const * p_inst);
|
||
|
|
||
|
/**
|
||
|
* @brief Function returns subclass descriptor count.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
*
|
||
|
* @return Count of descriptors
|
||
|
*/
|
||
|
uint8_t (*subclass_count)(app_usbd_class_inst_t const * p_inst);
|
||
|
|
||
|
/**
|
||
|
* @brief Function returns subclass descriptor size.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
* @param[in] desc_num Index of the subclass descriptor
|
||
|
*
|
||
|
* @return Size of descriptor
|
||
|
*/
|
||
|
size_t (*subclass_length)(app_usbd_class_inst_t const * p_inst,
|
||
|
uint8_t desc_num);
|
||
|
|
||
|
/**
|
||
|
* @brief Function returns pointer to subclass descriptor data.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance.
|
||
|
* @param[in] desc_num Index of the subclass descriptor
|
||
|
* @param[in] cur_byte Index of required byte
|
||
|
*
|
||
|
* @return Pointer to requested byte in subclass descriptor
|
||
|
*/
|
||
|
const uint8_t * (*subclass_data)(app_usbd_class_inst_t const * p_inst,
|
||
|
uint8_t desc_num,
|
||
|
uint32_t cur_byte);
|
||
|
|
||
|
/**
|
||
|
* @brief Function called on idle transfer
|
||
|
*
|
||
|
* This function should trigger next idle transfer.
|
||
|
*
|
||
|
* @param[in,out] p_inst Instance of the class.
|
||
|
* @param[in] report_id Number of report ID that needs idle transfer.
|
||
|
*
|
||
|
* @return Standard error code.
|
||
|
*/
|
||
|
ret_code_t (*on_idle)(app_usbd_class_inst_t const * p_inst, uint8_t report_id);
|
||
|
|
||
|
ret_code_t (*set_idle_handler)(app_usbd_class_inst_t const * p_inst,
|
||
|
app_usbd_hid_idle_handler_t handler);
|
||
|
} app_usbd_hid_methods_t;
|
||
|
|
||
|
/**
|
||
|
* @brief HID report buffers.
|
||
|
*/
|
||
|
typedef struct {
|
||
|
uint8_t * p_buff;
|
||
|
size_t size;
|
||
|
} app_usbd_hid_report_buffer_t;
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Define OUT report buffer structure @ref app_usbd_hid_report_buffer_t.
|
||
|
*
|
||
|
* @param name Instance name.
|
||
|
* @param rep_size Output report size.
|
||
|
*/
|
||
|
#define APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(name, rep_size) \
|
||
|
static uint8_t CONCAT_2(name, _buf)[(rep_size)]; \
|
||
|
const app_usbd_hid_report_buffer_t name = { \
|
||
|
.p_buff = CONCAT_2(name, _buf), \
|
||
|
.size = sizeof(CONCAT_2(name, _buf)), \
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Define FEATURE report buffer structure @ref app_usbd_hid_report_buffer_t.
|
||
|
*
|
||
|
* @param name Instance name.
|
||
|
* @param rep_size Feature report size.
|
||
|
*/
|
||
|
#define APP_USBD_HID_GENERIC_GLOBAL_FEATURE_REP_DEF(name, rep_size) \
|
||
|
static uint8_t CONCAT_2(name, _feature_buf)[(rep_size)]; \
|
||
|
const app_usbd_hid_report_buffer_t name = { \
|
||
|
.p_buff = CONCAT_2(name, _feature_buf), \
|
||
|
.size = sizeof(CONCAT_2(name, _feature_buf)), \
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief HID subclass descriptor.
|
||
|
*/
|
||
|
|
||
|
typedef struct {
|
||
|
size_t size;
|
||
|
app_usbd_descriptor_t type;
|
||
|
uint8_t const * const p_data;
|
||
|
} app_usbd_hid_subclass_desc_t;
|
||
|
|
||
|
/**
|
||
|
* @brief Initializer of HID report descriptor
|
||
|
*
|
||
|
* @param name Report descriptor name
|
||
|
* @param ... Report descriptor data
|
||
|
*/
|
||
|
|
||
|
#define APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(name, ...) \
|
||
|
static uint8_t const CONCAT_2(name, _data)[] = \
|
||
|
__VA_ARGS__ \
|
||
|
; \
|
||
|
static const app_usbd_hid_subclass_desc_t name = \
|
||
|
{ \
|
||
|
sizeof(CONCAT_2(name, _data)), \
|
||
|
APP_USBD_DESCRIPTOR_REPORT, \
|
||
|
CONCAT_2(name,_data) \
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Initializer of HID physical descriptor
|
||
|
*
|
||
|
* @param name Physical descriptor name
|
||
|
* @param ... Physical descriptor data
|
||
|
*/
|
||
|
|
||
|
#define APP_USBD_HID_GENERIC_SUBCLASS_PHYSICAL_DESC(name, ...) \
|
||
|
static uint8_t const CONCAT_2(name, _data)[] = \
|
||
|
__VA_ARGS__ \
|
||
|
; \
|
||
|
static const app_usbd_hid_subclass_desc_t name = \
|
||
|
{ \
|
||
|
sizeof(CONCAT_2(name, _data)), \
|
||
|
APP_USBD_DESCRIPTOR_PHYSICAL, \
|
||
|
CONCAT_2(name,_data) \
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief USB HID instance.
|
||
|
*/
|
||
|
typedef struct {
|
||
|
app_usbd_hid_subclass_desc_t const ** const p_subclass_desc; //!< HID subclass descriptors array.
|
||
|
size_t subclass_desc_count; //!< HID subclass descriptors count.
|
||
|
|
||
|
app_usbd_hid_subclass_t subclass_boot; //!< Boot device (see HID definition).
|
||
|
app_usbd_hid_protocol_t protocol; //!< HID protocol (see HID definition).
|
||
|
|
||
|
app_usbd_hid_report_buffer_t * p_rep_buffer_in; //!< Report buffer IN.
|
||
|
app_usbd_hid_report_buffer_t const * p_rep_buffer_out; //!< Report buffer OUT (only one instance).
|
||
|
app_usbd_hid_report_buffer_t const * p_rep_buffer_feature; //!< Report buffer FEATURE.
|
||
|
app_usbd_hid_methods_t const * p_hid_methods; //!< Hid interface methods.
|
||
|
app_usbd_hid_user_ev_handler_t user_event_handler; //!< User event handler.
|
||
|
|
||
|
uint8_t * p_ep_interval; //!< Endpoint intervals.
|
||
|
} app_usbd_hid_inst_t;
|
||
|
|
||
|
/**
|
||
|
* @brief USB HID instance initializer @ref app_usbd_hid_inst_t.
|
||
|
*
|
||
|
* @param subclass_dsc HID subclass descriptors.
|
||
|
* @param sub_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
|
||
|
* @param protocl HID protocol. (@ref app_usbd_hid_protocol_t)
|
||
|
* @param report_buff_in Input report buffer list.
|
||
|
* @param report_buff_out Output report buffer.
|
||
|
* @param report_buff_feature Feature report buffer.
|
||
|
* @param user_ev_handler @ref app_usbd_hid_user_ev_handler_t.
|
||
|
* @param hid_methods @ref app_usbd_hid_methods_t.
|
||
|
* @param ep_list List of endpoints and intervals
|
||
|
* */
|
||
|
|
||
|
#define APP_USBD_HID_INST_CONFIG(subclass_dsc, \
|
||
|
sub_boot, \
|
||
|
protocl, \
|
||
|
report_buff_in, \
|
||
|
report_buff_out, \
|
||
|
report_buff_feature, \
|
||
|
user_ev_handler, \
|
||
|
hid_methods, \
|
||
|
ep_list) \
|
||
|
{ \
|
||
|
.p_subclass_desc = subclass_dsc, \
|
||
|
.subclass_desc_count = ARRAY_SIZE(subclass_dsc), \
|
||
|
.p_rep_buffer_in = report_buff_in, \
|
||
|
.p_rep_buffer_out = report_buff_out, \
|
||
|
.p_rep_buffer_feature = report_buff_feature, \
|
||
|
.user_event_handler = user_ev_handler, \
|
||
|
.p_hid_methods = hid_methods, \
|
||
|
.subclass_boot = sub_boot, \
|
||
|
.protocol = protocl, \
|
||
|
.p_ep_interval = ep_list \
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief HID internal context.
|
||
|
* */
|
||
|
typedef struct {
|
||
|
nrf_atomic_u32_t state_flags; //!< HID state flags @ref app_usbd_hid_state_flag_t.
|
||
|
nrf_atomic_flag_t access_lock; //!< Lock flag to internal data.
|
||
|
uint8_t idle_rate[APP_USBD_HID_REPORT_IDLE_TABLE_SIZE]; //!< HID idle rate (4ms units).
|
||
|
app_usbd_hid_protocol_select_t selected_protocol; //!< Currently selected HID protocol.
|
||
|
app_usbd_hid_idle_handler_t idle_handler; //!< Idle report handler.
|
||
|
uint32_t first_idle[APP_USBD_HID_REPORT_IDLE_TABLE_SIZE]; //!< Number of frame at first idle transaction.
|
||
|
bool lock_idle[APP_USBD_HID_REPORT_IDLE_TABLE_SIZE]; //!< Lock flag to idle transactions.
|
||
|
bool idle_on; //!< Idle transactions flag.
|
||
|
bool idle_id_report; //!< Idle transactions with nonzero report id flag.
|
||
|
} app_usbd_hid_ctx_t;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Locks internal hid context.
|
||
|
*
|
||
|
* Simple semaphore functionality to prevent concurrent access from application and
|
||
|
* interrupt to internal mouse data.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal hid context
|
||
|
*/
|
||
|
static inline void app_usbd_hid_access_lock(app_usbd_hid_ctx_t * p_hid_ctx)
|
||
|
{
|
||
|
UNUSED_RETURN_VALUE(nrf_atomic_flag_set(&p_hid_ctx->access_lock));
|
||
|
__DSB();
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Unlocks internal hid context.
|
||
|
*
|
||
|
* Simple semaphore functionality to prevent concurrent access from application and
|
||
|
* interrupt to internal mouse data.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal hid context.
|
||
|
*/
|
||
|
static inline void app_usbd_hid_access_unlock(app_usbd_hid_ctx_t * p_hid_ctx)
|
||
|
{
|
||
|
UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_hid_ctx->access_lock));
|
||
|
__DSB();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Tests whether internal lock is acquired.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal HID context.
|
||
|
*
|
||
|
* @retval true Locked.
|
||
|
* @retval false Unlocked.
|
||
|
*/
|
||
|
static inline bool app_usbd_hid_access_lock_test(app_usbd_hid_ctx_t * p_hid_ctx)
|
||
|
{
|
||
|
return p_hid_ctx->access_lock != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Set one of the HID internal state flags.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal HID context.
|
||
|
* @param[in] flag Flag to set.
|
||
|
*/
|
||
|
static inline void app_usbd_hid_state_flag_set(app_usbd_hid_ctx_t * p_hid_ctx,
|
||
|
app_usbd_hid_state_flag_t flag)
|
||
|
{
|
||
|
UNUSED_RETURN_VALUE(nrf_atomic_u32_or(&p_hid_ctx->state_flags, 1u << flag));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Clear one of the HID internal state flags.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal HID context.
|
||
|
* @param[in] flag Flag to clear.
|
||
|
*/
|
||
|
static inline void app_usbd_hid_state_flag_clr(app_usbd_hid_ctx_t * p_hid_ctx,
|
||
|
app_usbd_hid_state_flag_t flag)
|
||
|
{
|
||
|
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&p_hid_ctx->state_flags, ~(1u << flag)));
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Test one of the HID internal state flags.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal HID context.
|
||
|
* @param[in] flag Flag to test.
|
||
|
*
|
||
|
* @retval true Flag is set.
|
||
|
* @retval false Flag is not set.
|
||
|
*/
|
||
|
static inline bool app_usbd_hid_state_flag_test(app_usbd_hid_ctx_t * p_hid_ctx,
|
||
|
app_usbd_hid_state_flag_t flag)
|
||
|
{
|
||
|
return ((p_hid_ctx->state_flags >> flag) & 1) == 1;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Checks whether HID endpoint transfer required.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal HID context.
|
||
|
*
|
||
|
* @retval true Input endpoint transfer required.
|
||
|
* @retval false Transfer in progress or not allowed.
|
||
|
*/
|
||
|
static inline bool app_usbd_hid_trans_required(app_usbd_hid_ctx_t * p_hid_ctx)
|
||
|
{
|
||
|
if (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED) != 0)
|
||
|
{
|
||
|
UNUSED_RETURN_VALUE(app_usbd_wakeup_req());
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS) == 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Validates internal hid state.
|
||
|
*
|
||
|
* HID Mouse has to receive some USBD events before functions from this module could be used.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx Internal hid context.
|
||
|
*
|
||
|
* @retval true State is valid.
|
||
|
* @retval false State is invalid.
|
||
|
*/
|
||
|
static inline bool app_usbd_hid_state_valid(app_usbd_hid_ctx_t * p_hid_ctx)
|
||
|
{
|
||
|
/*Check whether internal flags allow to enable mouse*/
|
||
|
if ((app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED) == 0) ||
|
||
|
(app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED) == 0))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief HID generic event handler.
|
||
|
*
|
||
|
* This handler should process every class event after specific class handler.
|
||
|
* This approach allow to handle some events in the same way in all HID sub-classes.
|
||
|
*
|
||
|
* @param[in] p_inst Generic class instance.
|
||
|
* @param[in] p_hinst HID class instance.
|
||
|
* @param[in] p_hid_ctx HID context.
|
||
|
* @param[in] p_event Complex event structure.
|
||
|
*
|
||
|
* @return Standard error code.
|
||
|
*/
|
||
|
ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst,
|
||
|
app_usbd_hid_inst_t const * p_hinst,
|
||
|
app_usbd_hid_ctx_t * p_hid_ctx,
|
||
|
app_usbd_complex_evt_t const * p_event);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Returns IN report buffer.
|
||
|
*
|
||
|
* @param[in] p_hinst HID class instance.
|
||
|
*
|
||
|
* @return Report buffer handle or NULL if report doesn't exist.
|
||
|
*/
|
||
|
app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst);
|
||
|
|
||
|
/**
|
||
|
* @brief Returns OUT report buffer.
|
||
|
*
|
||
|
* Output reports are handled in interrupt handler so only one buffer is required. Buffer returned by
|
||
|
* this function has predefined size, which should be equal (maximum OUTPUT report size + 1). To receive
|
||
|
* OUT report this function should be called on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event.
|
||
|
*
|
||
|
* @param[in] p_hinst HID class instance.
|
||
|
*
|
||
|
* @return Report buffer handle or NULL if report doesn't exist.
|
||
|
*/
|
||
|
static inline app_usbd_hid_report_buffer_t const *
|
||
|
app_usbd_hid_rep_buff_out_get(app_usbd_hid_inst_t const * p_hinst)
|
||
|
{
|
||
|
ASSERT(p_hinst);
|
||
|
return p_hinst->p_rep_buffer_out;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Returns FEATURE report buffer.
|
||
|
*
|
||
|
* @param[in] p_hinst HID class instance.
|
||
|
*
|
||
|
* @return Report buffer handle or NULL if report doesn't exist.
|
||
|
*/
|
||
|
app_usbd_hid_report_buffer_t const * app_usbd_hid_rep_buff_feature_get(app_usbd_hid_inst_t const * p_hinst);
|
||
|
|
||
|
/**
|
||
|
* @brief Returns HID selected protocol.
|
||
|
*
|
||
|
* @param[in] p_hid_ctx HID context.
|
||
|
*
|
||
|
* @return Currently selected protocol (@ref app_usbd_hid_protocol_select_t).
|
||
|
*/
|
||
|
static inline app_usbd_hid_protocol_select_t app_usbd_hid_selected_protocol_get(app_usbd_hid_ctx_t * p_hid_ctx)
|
||
|
{
|
||
|
ASSERT(p_hid_ctx);
|
||
|
return p_hid_ctx->selected_protocol;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Auxiliary function to access to HID IN endpoint address.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance data.
|
||
|
*
|
||
|
* @return IN endpoint address.
|
||
|
*/
|
||
|
static inline nrf_drv_usbd_ep_t app_usbd_hid_epin_addr_get(app_usbd_class_inst_t const * p_inst)
|
||
|
{
|
||
|
app_usbd_class_iface_conf_t const * class_iface;
|
||
|
class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX);
|
||
|
|
||
|
app_usbd_class_ep_conf_t const * ep_cfg;
|
||
|
ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPIN_IDX);
|
||
|
|
||
|
return app_usbd_class_ep_address_get(ep_cfg);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Auxiliary function to access to HID generic OUT endpoint address.
|
||
|
*
|
||
|
* @param[in] p_inst Class instance data.
|
||
|
*
|
||
|
* @return OUT endpoint address.
|
||
|
*/
|
||
|
static inline nrf_drv_usbd_ep_t app_usbd_hid_epout_addr_get(app_usbd_class_inst_t const * p_inst)
|
||
|
{
|
||
|
app_usbd_class_iface_conf_t const * class_iface;
|
||
|
class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX);
|
||
|
|
||
|
app_usbd_class_ep_conf_t const * ep_cfg;
|
||
|
ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPOUT_IDX);
|
||
|
|
||
|
return app_usbd_class_ep_address_get(ep_cfg);
|
||
|
}
|
||
|
|
||
|
/** @} */
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* APP_USBD_HID_H__ */
|