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

📄 av_headset_controls.c

📁 csr 蓝牙芯片 无线蓝牙耳机的嵌入式程序
💻 C
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004

FILE NAME
    av_headset_controls.c        

DESCRIPTION
    
NOTES

*/


/****************************************************************************
    Header files
*/
#include "av_headset_private.h"
#include "av_headset_controls.h"

#include <stdlib.h>
#include <string.h>
#include <panic.h>
#include <pio.h>
#include <codec.h>
#include <pcm.h>


static void controls_handler(Task task, MessageId id, Message message);


/* 
    Send remote control command to remote device 
*/
static void sendAVRCP(avTaskData* theAvApp, avc_operation_id op_id, uint8 state)
{
    theAvApp->avrcp_pending = TRUE;
    
    /* Send a key press */
    AvrcpPassthrough(theAvApp->avrcp, subunit_panel, 0, state, op_id, 0, 0);
}


/*************************************************************************
NAME    
     avHeadsetInitialiseControls
    
DESCRIPTION
     Initialises power and button control
RETURNS
     
*/
void avHeadsetInitialiseControls(avTaskData* theAvApp)
{
    /* hold power on so user can release the button */
    PioSet(POWER_HOLD,POWER_HOLD);
    PioSetDir(POWER_HOLD,POWER_HOLD);

    /* set the input gain to a reasonable value */
    theAvApp->output_gain = CodecOutputGainRange()/2;
    CodecSetOutputGainA(theAvApp->output_gain);
    CodecSetOutputGainB(theAvApp->output_gain);
    
    /* initial the handler task */
    theAvApp->controls_task.handler = controls_handler;
}

/*************************************************************************
NAME    
     avHeadsetStartPowerDown
    
DESCRIPTION
     Start to power down the headset gracefully
     
RETURNS
     
*/
void avHeadsetStartPowerDown(avTaskData* theAvApp)
{
	if (theAvApp->powering_down)
		return;
	
    theAvApp->powering_down = TRUE;
    
    /* Close down any active AV link */
    if ((theAvApp->a2dp_state == avHeadsetA2dpConnected) || (theAvApp->a2dp_state == avHeadsetA2dpStreaming))
    {
		/* Update the local state */
        avHeadsetSetA2dpState(avHeadsetA2dpConnected);

		/* Close the AV stream */
        A2dpClose(theAvApp->a2dp, theAvApp->media_sink);
    }
    /* Close down any active AVRCP link */
    if (theAvApp->avrcp_state == avHeadsetAvrcpConnected)
    {
        avHeadsetSetAvrcpState(avHeadsetAvrcpDisconnecting);
        AvrcpDisconnect(theAvApp->avrcp);
    }
    
    MessageSendLater(getAppTask(), POWER_OFF, 0, (uint32) 5000);
    
    avHeadsetCheckPowerDownStatus(theAvApp);
        
}

/*************************************************************************
NAME    
     avHeadsetCheckPowerDownStatus
    
DESCRIPTION
     Checks if connections have been successfully dropped and we have
     initiated power down. We can then power off.
     
RETURNS
     
*/
void avHeadsetCheckPowerDownStatus(const avTaskData *theAvApp)
{
    if (!theAvApp->powering_down)
        return;
    
    if ((theAvApp->a2dp_state == avHeadsetA2dpReady) && (theAvApp->avrcp_state == avHeadsetAvrcpReady))
    {
        DEBUG(("OK! We can power down early\n"));

        (void) MessageCancelAll(getAppTask(), POWER_OFF);
        MessageSend(getAppTask(), POWER_OFF, 0);
    }
}

/*************************************************************************
NAME    
     avHeadsetPowerDown
    
DESCRIPTION
     Power down the headset
     
RETURNS
     
*/
void avHeadsetPowerDown(void)
{
    DEBUG(("PowerDown and Panic\n"));
    
    /* disable power hold and LED */
    PioSetDir(POWER_HOLD | LED, 0);
    PioSet(POWER_HOLD | LED,0);

    /* in case the interface board is attached
       and keeping us alive we also halt the program. */
    Panic();
}

/*************************************************************************
NAME    
     avHeadsetHandleVolUp
    
DESCRIPTION
     Handle volume up
     
RETURNS
     
*/
void avHeadsetHandleVolUp(avTaskData* theAvApp)
{
    /* if gain is not at max, increase */
    if (theAvApp->output_gain < CodecOutputGainRange())
    {
        theAvApp->output_gain++;

        CodecSetOutputGainA(theAvApp->output_gain);
        CodecSetOutputGainB(theAvApp->output_gain);
    }
}


/*************************************************************************
NAME    
     avHeadsetHandleVolDown
    
DESCRIPTION
     Handle volume down
     
RETURNS
     
*/
void avHeadsetHandleVolDown(avTaskData* theAvApp)
{
    /* if gain is not at min, decrease */
    if (theAvApp->output_gain > 0)
    {
        theAvApp->output_gain--;

        CodecSetOutputGainA(theAvApp->output_gain);
        CodecSetOutputGainB(theAvApp->output_gain);
    }
}


enum
{
    PAUSE_PRESS,
    PAUSE_RELEASE,
    PLAY_PRESS,
    PLAY_RELEASE,
    FORWARD_PRESS,
    FORWARD_RELEASE,
    BACKWARD_PRESS,
    BACKWARD_RELEASE,
    STOP_PRESS,
    STOP_RELEASE
};

/*************************************************************************
NAME    
     controls_handler
    
DESCRIPTION
     Called when a button state change is pending which can now be sent.

     Messages will only be delivered when avrcp_pending is FALSE and
     hence when we are clear to send the message.
     
RETURNS
     
*/
static void controls_handler(Task task, MessageId id, Message message)
{
	task = task;
	message = message;

    switch (id)
    {
        case PAUSE_PRESS:
            DEBUG(("Sending Pause Pressed\n"));
            sendAVRCP(getApp(), opid_pause, 0);
            break;

        case PAUSE_RELEASE:
            DEBUG(("Sending Pause Released\n"));
            sendAVRCP(getApp(), opid_pause, 1);
            break;

        case PLAY_PRESS:
            DEBUG(("Sending Play Pressed\n"));
            sendAVRCP(getApp(), opid_play, 0);
            break;

        case PLAY_RELEASE:
            DEBUG(("Sending Play Released\n"));
            sendAVRCP(getApp(), opid_play, 1);
            break;

        case FORWARD_PRESS:
            DEBUG(("Sending Forward Pressed\n"));
            sendAVRCP(getApp(), opid_forward, 0);
            break;

        case FORWARD_RELEASE:
            DEBUG(("Sending Forward Released\n"));
            sendAVRCP(getApp(), opid_forward, 1);
            break;

        case BACKWARD_PRESS:
            DEBUG(("Sending Backward Pressed\n"));
            sendAVRCP(getApp(), opid_backward, 0);
            break;

        case BACKWARD_RELEASE:
            DEBUG(("Sending Backward Released\n"));
            sendAVRCP(getApp(), opid_backward, 1);
            break;

        case STOP_PRESS:
            DEBUG(("Sending Stop Pressed\n"));
            sendAVRCP(getApp(), opid_stop, 0);
            break;

        case STOP_RELEASE:
            DEBUG(("Sending Stop Released\n"));
            sendAVRCP(getApp(), opid_stop, 1);
            break;

		default:
			break;
    }
}


/*************************************************************************
NAME    
     avHeadsetPausePress
    
DESCRIPTION
     Signal that pause has been pressed.
     Note that the AV Control specification states that the pause
     button will toggle between playing/paused.
     
RETURNS
     
*/
void avHeadsetPausePress(avTaskData* theAvApp)
{
    /* see controls_handler description */
    MessageSendConditionally(&theAvApp->controls_task, PAUSE_PRESS, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetPauseRelease
    
DESCRIPTION
     Signal that pause has been released
     
RETURNS
     
*/
void avHeadsetPauseRelease(avTaskData* theAvApp)
{
    /* see button_handler message queue description */
    MessageSendConditionally(&theAvApp->controls_task, PAUSE_RELEASE, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetPlayPress
    
DESCRIPTION
     Signal that play has been pressed
     
RETURNS
     
*/
void avHeadsetPlayPress(avTaskData* theAvApp)
{
    /* see controls_handler description */
    MessageSendConditionally(&theAvApp->controls_task, PLAY_PRESS, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetPlayRelease
    
DESCRIPTION
     Signal that play has been released
     
RETURNS
     
*/
void avHeadsetPlayRelease(avTaskData* theAvApp)
{
    /* see button_handler message queue description */
    MessageSendConditionally(&theAvApp->controls_task, PLAY_RELEASE, NULL, &theAvApp->avrcp_pending);
}


/*************************************************************************
NAME    
     avHeadsetForwardPress
    
DESCRIPTION
     Signal that Forward has been pressed
     
RETURNS
     
*/
void avHeadsetForwardPress(avTaskData* theAvApp)
{
    /* see controls_handler description */
    MessageSendConditionally(&theAvApp->controls_task, FORWARD_PRESS, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetForwardRelease
    
DESCRIPTION
     Signal that Forward has been released
     
RETURNS
     
*/
void avHeadsetForwardRelease(avTaskData* theAvApp)
{
    /* see button_handler message queue description */
    MessageSendConditionally(&theAvApp->controls_task, FORWARD_RELEASE, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetBackwardPress
    
DESCRIPTION
     Signal that Backward has been pressed
     
RETURNS
     
*/
void avHeadsetBackwardPress(avTaskData* theAvApp)
{
    /* see controls_handler description */
    MessageSendConditionally(&theAvApp->controls_task, BACKWARD_PRESS, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetBackwardRelease
    
DESCRIPTION
     Signal that Backward has been released
     
RETURNS
     
*/
void avHeadsetBackwardRelease(avTaskData* theAvApp)
{
    /* see button_handler message queue description */
    MessageSendConditionally(&theAvApp->controls_task, BACKWARD_RELEASE, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetStopPress
    
DESCRIPTION
     Signal that Stop has been pressed
     
RETURNS
     
*/
void avHeadsetStopPress(avTaskData* theAvApp)
{
    /* see controls_handler description */
    MessageSendConditionally(&theAvApp->controls_task, STOP_PRESS, NULL, &theAvApp->avrcp_pending);
}

/*************************************************************************
NAME    
     avHeadsetStopRelease
    
DESCRIPTION
     Signal that Stop has been released
     
RETURNS
     
*/
void avHeadsetStopRelease(avTaskData* theAvApp)
{
    /* see button_handler message queue description */
    MessageSendConditionally(&theAvApp->controls_task, STOP_RELEASE, NULL, &theAvApp->avrcp_pending);
}


⌨️ 快捷键说明

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