Пример #1
0
static uint8_t audio_get_control_interface_number(app_usbd_class_inst_t const * p_inst)
{
    app_usbd_class_iface_conf_t const * ifce = 0;

    ifce = app_usbd_class_iface_get(p_inst, 0);
    return app_usbd_class_iface_number_get(ifce);
}
Пример #2
0
/**
 * @brief Auxiliary function to access CDC ACM DATA OUT endpoint address.
 *
 * @param[in] p_inst Class instance data.
 *
 * @return OUT endpoint address.
 */
static inline nrf_drv_usbd_ep_t data_ep_out_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_CDC_ACM_DATA_IFACE_IDX);

    app_usbd_class_ep_conf_t const * ep_cfg;
    ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX);

    return app_usbd_class_ep_address_get(ep_cfg);
}
Пример #3
0
/**
 * @brief Auxiliary function to access CDC ACM COMM IN endpoint address.
 *
 * @param[in] p_inst Class instance data.
 *
 * @return IN endpoint address.
 */
static inline nrf_drv_usbd_ep_t comm_ep_in_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_CDC_ACM_COMM_IFACE_IDX);

    app_usbd_class_ep_conf_t const * ep_cfg;
    ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX);

    return app_usbd_class_ep_address_get(ep_cfg);
}
Пример #4
0
/**
 * @brief Auxiliary function to access isochronous endpoint address.
 *
 * @param[in] p_inst Class instance data.
 *
 * @return ISO endpoint address.
 */
static inline nrf_drv_usbd_ep_t ep_iso_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_AUDIO_STREAMING_IFACE_IDX);

    app_usbd_class_ep_conf_t const * ep_cfg;
    ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_AUDIO_STREAMING_EP_IDX);

    return app_usbd_class_ep_address_get(ep_cfg);
}
Пример #5
0
static void iface_deselect(
    app_usbd_class_inst_t const * const p_inst,
    uint8_t                             iface_idx)
{
    app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);

    /* Simple check if this is data interface */
    if (p_iface->ep_cnt > 0)
    {
        app_usbd_audio_t const * p_audio     = audio_get(p_inst);
        app_usbd_audio_ctx_t   * p_audio_ctx = audio_ctx_get(p_audio);
        p_audio_ctx->streaming = false;
    }
    /* Note that all the interface endpoints would be disabled automatically after this function */
}
Пример #6
0
static uint8_t iface_selection_get(
    app_usbd_class_inst_t const * const p_inst,
    uint8_t                             iface_idx)
{
    app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
    /* Simple check if this is data interface */
    uint8_t const ep_count = app_usbd_class_iface_ep_count_get(p_iface);

    if (ep_count > 0)
    {
        app_usbd_audio_t const * p_audio     = audio_get(p_inst);
        app_usbd_audio_ctx_t   * p_audio_ctx = audio_ctx_get(p_audio);
        return (p_audio_ctx->streaming) ? 1 : 0;
    }
    return 0;
}
Пример #7
0
/**
 * @brief Select interface.
 *
 * @param[in,out] p_inst    Instance of the class.
 * @param[in]     iface_idx Index of the interface inside class structure.
 * @param[in]     alternate Alternate setting that should be selected.
 */
static ret_code_t iface_select(
    app_usbd_class_inst_t const * const p_inst,
    uint8_t                             iface_idx,
    uint8_t                             alternate)
{
    app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
    /* Simple check if this is data interface */
    uint8_t const ep_count = app_usbd_class_iface_ep_count_get(p_iface);

    if (ep_count > 0)
    {
        if (alternate > 1)
        {
            return NRF_ERROR_INVALID_PARAM;
        }
        app_usbd_audio_t const * p_audio     = audio_get(p_inst);
        app_usbd_audio_ctx_t   * p_audio_ctx = audio_ctx_get(p_audio);
        p_audio_ctx->streaming = (alternate != 0);

        uint8_t i;

        for (i = 0; i < ep_count; ++i)
        {
            nrf_drv_usbd_ep_t ep_addr =
                app_usbd_class_ep_address_get(app_usbd_class_iface_ep_get(p_iface, i));
            if (alternate)
            {
                app_usbd_ep_enable(ep_addr);
            }
            else
            {
                app_usbd_ep_disable(ep_addr);
            }
        }
        return NRF_SUCCESS;
    }
    return NRF_ERROR_NOT_SUPPORTED;
}
Пример #8
0
/** @brief @ref app_usbd_class_methods_t::feed_descriptors */
static bool dummy_class_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
                                         app_usbd_class_inst_t const     * p_inst,
                                         uint8_t                         * p_buff,
                                         size_t                            max_size)
{
    static app_usbd_class_iface_conf_t const * p_cur_iface = 0;
    p_cur_iface = app_usbd_class_iface_get(p_inst, 0);

    APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size)

    /* INTERFACE DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_descriptor_iface_t)); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType
    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0); // bNumEndpoints
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_CLASS); // bInterfaceClass
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_SUBCLASS); // bInterfaceSubClass
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_PROTOCOL); // bInterfaceProtocol
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface

    APP_USBD_CLASS_DESCRIPTOR_END();
}
Пример #9
0
/**
 * @brief @ref app_usbd_class_methods_t::feed_descriptors
 */
static bool nrf_dfu_trigger_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
                                             app_usbd_class_inst_t const     * p_inst,
                                             uint8_t                         * p_buff,
                                             size_t                            max_size)
{
    static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
    p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
    app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);

    APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size)

    /* INTERFACE DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_descriptor_iface_t)); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType
    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0); // bNumEndpoints
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_CLASS); // bInterfaceClass
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_SUBCLASS); // bInterfaceSubClass
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME); // bInterfaceProtocol
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface

    /* FUNCTIONAL DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_nrf_dfu_trigger_desc_func_t)); // bFunctionLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_CS_FUNCTIONAL); // bDescriptorType
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_BIT_CAN_DNLOAD |
                                    APP_USBD_NRF_DFU_TRIGGER_BIT_WILL_DETACH); // bmAttribute
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.detach_timeout)); // wDetachTimeOut LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.detach_timeout)); // wDetachTimeOut MSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.transfer_size)); // wTransferSize LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.transfer_size)); // wTransferSize MSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.bcd_dfu)); // bcdDFUVersion LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.bcd_dfu)); // bcdDFUVersion MSB

    APP_USBD_CLASS_DESCRIPTOR_END();
}
Пример #10
0
static bool audio_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
                                   app_usbd_class_inst_t const     * p_inst,
                                   uint8_t                         * p_buff,
                                   size_t                            max_size)
{
    static uint8_t ifaces   = 0;
    ifaces = app_usbd_class_iface_count_get(p_inst);
    ASSERT(ifaces == 2);
    app_usbd_audio_t const * p_audio = audio_get(p_inst);

    APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);

    /* CONTROL INTERFACE DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface

    static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
    p_cur_iface = app_usbd_class_iface_get(p_inst, 0);

    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL); // bInterfaceSubclass (Audio Control)
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface

    /* HEADER INTERFACE */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_INTERFACE); // bDescriptorType = Audio Interfaces
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER); // bDescriptorSubtype = Header
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(0x0100)); // bcdADC LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(0x0100)); // bcdADC MSB

    static uint16_t header_desc_len = 0;
    header_desc_len = 9 + audio_get_feature_descriptor_size(p_inst) +
                      audio_get_input_descriptor_size(p_inst) + audio_get_output_descriptor_size(
        p_inst);
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(header_desc_len)); // wTotalLength LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(header_desc_len)); // wTotalLength MSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01);                    // bInCollection
    APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // baInterfaceNr(1)

    /* INPUT TERMINAL DESCRIPTOR */
    static uint32_t cur_byte        = 0;
    static size_t   input_desc_size = 0;
    input_desc_size = audio_get_input_descriptor_size(p_inst);

    for (cur_byte = 0; cur_byte < input_desc_size; cur_byte++)
    {
        APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_input_descriptor_data(p_inst, cur_byte));
    }

    /* FEATURE UNIT DESCRIPTOR */
    static size_t feature_desc_size = 0;
    feature_desc_size = audio_get_feature_descriptor_size(p_inst);

    for (cur_byte = 0; cur_byte < feature_desc_size; cur_byte++)
    {
        APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_feature_descriptor_data(p_inst, cur_byte));
    }

    /* OUTPUT TERMINAL DESCRIPTOR */
    static size_t output_desc_size = 0;
    output_desc_size = audio_get_output_descriptor_size(p_inst);

    for (cur_byte = 0; cur_byte < output_desc_size; cur_byte++)
    {
        APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_output_descriptor_data(p_inst, cur_byte));
    }

    p_cur_iface++;

    /* STREAM INTERFACE DESCRIPTOR ALT 0 */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
    APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bInterfaceNumber
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bNumEndpoints
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
    APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.type_streaming); // bInterfaceSubclass (Audio Control)
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface

    /* STREAM INTERFACE DESCRIPTOR ALT 1 */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
    APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bInterfaceNumber
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bAlternateSetting
    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
    APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.type_streaming); // bInterfaceSubclass (Audio Control)
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface

    /* AudioStreaming GENERAL DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_INTERFACE); // bDescriptorType = Audio Interface
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL); // bDescriptorSubtype = General
    APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bTerminalLink
    APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.delay); // bDelay
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_audio->specific.inst.format)); // wFormatTag LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_audio->specific.inst.format)); // wFormatTag MSB

    /* FORMAT DESCRIPTOR */
    static size_t format_desc_size = 0;
    format_desc_size = audio_get_format_descriptor_size(p_inst);

    for (cur_byte = 0; cur_byte < format_desc_size; cur_byte++)
    {
        APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_format_descriptor_data(p_inst, cur_byte));
    }

    /* ENDPOINT GENERAL DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT); // bDescriptorType = Audio Descriptor
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_EP_SUBTYPE_GENERAL);  // bDescriptorSubtype = EP General
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bmAttributes
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bLockDelayUnits
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(0x0000)); // wLockDelay LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(0x0000)); // wLockDelay MSB

    /* ENDPOINT ISO DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint

    static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
    p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, 0);
    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS); // bmAttributes
    APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_audio->specific.inst.ep_size)); // wMaxPacketSize LSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_audio->specific.inst.ep_size)); // wMaxPacketSize MSB
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bRefresh
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bSynchAddress

    APP_USBD_CLASS_DESCRIPTOR_END();
}