⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auddfunctiondriver.c

📁 本代bootloader通过usb下载代码首先存放在sdram中
💻 C
字号:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
 * ----------------------------------------------------------------------------
 */

#if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)

//-----------------------------------------------------------------------------
//      Headers
//-----------------------------------------------------------------------------

// GENERAL
#include <utility/trace.h>
#include <utility/assert.h>
#include <utility/led.h>
// USB
#include <usb/device/core/USBD.h>
// AUDIO
#include <usb/common/audio/AUDGenericRequest.h>
#include <usb/common/audio/AUDFeatureUnitRequest.h>

#include "AUDDFunctionDriver.h"
#include "AUDDFunctionDriverDescriptors.h"

//-----------------------------------------------------------------------------
//         Internal variables
//-----------------------------------------------------------------------------

/// USB audio speaker driver instance.
static AUDDSpeakerChannel auddSpeakerChannels[AUDD_NUMCHANNELS+1];
/// Intermediate storage variable for the mute status of a channel.
static unsigned char muted;

//-----------------------------------------------------------------------------
//         Internal functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/// Changes the mute status of the given channel accordingly.
/// \param channel Number of the channel whose mute status has changed.
//-----------------------------------------------------------------------------
static void AUDD_MuteReceived(unsigned char channel)
{
    AUDDSpeakerChannel *pChannel = &auddSpeakerChannels[channel];
    if (muted) {
    
        if (!pChannel->muted) {

            pChannel->muted = 1;
            AUDDSpeakerChannel_MuteChanged(pChannel, 1);
        }
    }
    else {

        if (pChannel->muted) {
            
            pChannel->muted = 0;
            AUDDSpeakerChannel_MuteChanged(pChannel, 0);
        }
    }

    USBD_Write(0, 0, 0, 0, 0);
}

//-----------------------------------------------------------------------------
/// Sets the current value of a particular Feature control of a channel.
/// \param channel Number of the channel whose feature will change.
/// \param control The feature control that will change.
/// \param length The feature data size.
//-----------------------------------------------------------------------------
static void AUDD_SetFeatureCurrentValue(unsigned char channel,
                                        unsigned char control,
                                        unsigned short length)
{
    TRACE_INFO_WP("sFeature ");
    TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length);

    // Check the the requested control is supported
    // Mute control on master channel
    if ((control == AUDFeatureUnitRequest_MUTE)
        && (channel < (AUDD_NUMCHANNELS+1))
        && (length == 1)) {

        unsigned int argument = channel; // Avoids compiler warning
        USBD_Read(0, // Endpoint #0
                  &muted,
                  sizeof(muted),
                  (TransferCallback) AUDD_MuteReceived,
                  (void *) argument);
    }
    // Control/channel combination not supported
    else {

        USBD_Stall(0);
    }
}

//-----------------------------------------------------------------------------
/// Sends the current value of a particular channel Feature to the USB host.
/// \param channel Number of the channel whose feature will be sent.
/// \param control The feature control that will be sent.
/// \param length The feature data size.
//-----------------------------------------------------------------------------
static void AUDD_GetFeatureCurrentValue(unsigned char channel,
                                        unsigned char control,
                                        unsigned char length)
{
    TRACE_INFO_WP("gFeature ");
    TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length);

    // Check that the requested control is supported
    // Master channel mute control
    if ((control == AUDFeatureUnitRequest_MUTE)
        && (channel < (AUDD_NUMCHANNELS+1))
        && (length == 1)) {

        muted = auddSpeakerChannels[channel].muted;
        USBD_Write(0, &muted, sizeof(muted), 0, 0);
    }
    else {

        USBD_Stall(0);
    }
}

//-----------------------------------------------------------------------------
//         Exported functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/// Initializes an USB audio speaker function driver
//-----------------------------------------------------------------------------
void AUDDFunctionDriver_Initialize()
{
    auddSpeakerChannels[0].muted = 0;
    auddSpeakerChannels[0].number = AUDD_MASTERCHANNEL;
    auddSpeakerChannels[1].muted = 0;
    auddSpeakerChannels[1].number = AUDD_LEFTCHANNEL;
    auddSpeakerChannels[2].muted = 0;
    auddSpeakerChannels[2].number = AUDD_RIGHTCHANNEL;

    // Initialize the third LED to indicate when the audio interface is active
    LED_Configure(USBD_LEDOTHER);
}

//-----------------------------------------------------------------------------
/// Handles AUDIO-specific USB requests sent by the host
/// \param request Pointer to a USBGenericRequest instance.
/// \return 0 if the request is Unsupported, 1 if the request handled.
//-----------------------------------------------------------------------------
unsigned char AUDDFunctionDriver_RequestHandler(
    const USBGenericRequest *request)
{
    unsigned char entity;
    unsigned char interface;

    // Check if the request is supported
    switch (USBGenericRequest_GetRequest(request)) {

        case AUDGenericRequest_SETCUR:
            TRACE_INFO_WP(
                      "sCur(0x%04X) ",
                      USBGenericRequest_GetIndex(request));

            // Check the target interface and entity
            entity = AUDGenericRequest_GetEntity(request);
            interface = AUDGenericRequest_GetInterface(request);
            if ((entity == AUDD_Descriptors_FEATUREUNIT)
                && (interface == AUDD_Descriptors_CONTROL)) {

                AUDD_SetFeatureCurrentValue(
                    AUDFeatureUnitRequest_GetChannel(request),
                    AUDFeatureUnitRequest_GetControl(request),
                    USBGenericRequest_GetLength(request));
            }
            else {

                TRACE_WARNING(
                          "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
                          USBGenericRequest_GetIndex(request));
                USBD_Stall(0);
            }
            break;

        case AUDGenericRequest_GETCUR:
            TRACE_INFO_WP(
                      "gCur(0x%04X) ",
                      USBGenericRequest_GetIndex(request));

            // Check the target interface and entity
            entity = AUDGenericRequest_GetEntity(request);
            interface = AUDGenericRequest_GetInterface(request);
            if ((entity == AUDD_Descriptors_FEATUREUNIT)
                && (interface == AUDD_Descriptors_CONTROL)) {

                AUDD_GetFeatureCurrentValue(
                    AUDFeatureUnitRequest_GetChannel(request),
                    AUDFeatureUnitRequest_GetControl(request),
                    USBGenericRequest_GetLength(request));
            }
            else {

                TRACE_WARNING(
                          "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
                          USBGenericRequest_GetIndex(request));
                USBD_Stall(0);
            }
            break;

        default:
            return 0;
    }
    return 1;
}

//-----------------------------------------------------------------------------
/// Invoked whenever the active setting of an interface is changed by the
/// host. Changes the status of the third LED accordingly.
/// \param interface Interface number.
/// \param setting Newly active setting.
//-----------------------------------------------------------------------------
void AUDDFunctionCallbacks_InterfaceSettingChanged(unsigned char interface,
                                                   unsigned char setting)
{
    if ((interface == AUDD_Descriptors_STREAMING) && (setting == 0)) {

        LED_Clear(USBD_LEDOTHER);
    }
    else {

        LED_Set(USBD_LEDOTHER);
    }
}

//-----------------------------------------------------------------------------
/// Reads incoming audio data sent by the USB host into the provided buffer.
/// When the transfer is complete, an optional callback function is invoked.
/// \param buffer Pointer to the data storage buffer.
/// \param length Size of the buffer in bytes.
/// \param callback Optional callback function.
/// \param argument Optional argument to the callback function.
/// \return <USBD_STATUS_SUCCESS> if the transfer is started successfully;
///         otherwise an error code.
//-----------------------------------------------------------------------------
unsigned char AUDDSpeakerDriver_Read(void *buffer,
                                     unsigned int length,
                                     TransferCallback callback,
                                     void *argument)
{
    return USBD_Read(AUDD_Descriptors_DATAOUT,
                     buffer,
                     length,
                     callback,
                     argument);
}

#endif // (AUDIO defined)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -