📄 main.c
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004-2006
Part of BlueLab 3.5.2-release
FILE NAME
main.c
DESCRIPTION
AV source USB dongle app.
NOTES
***** Project property options *****
Audio mode (USB/Analogue) : Determines if the application will be built as a USB or
analogue input source dongle (default - USB).
***** User information *****
Using the avcontrol.exe included with Bluelab complements this application code when
operating as a USB device. It can be used to monitor the status of the application and
has a user interface that will allow the source dongle to discover a new AV sink bluetooth
device as well as entering DFU mode. PIO3 on a development board has the same functionality
as pressing the avcontrol 'Discover New Headphones' button.
Once a suitable device has been discovered, this application will try and pair, connect then
stream audio.
Note: The pin for this application is stored in the PS Key FIXED_PIN.
****************************************************************************
Header files
*/
#include "a2dp_sd_private.h"
#include "a2dp_sd_avrcp.h"
#include "a2dp_sd_button.h"
#include "a2dp_sd_close.h"
#include "a2dp_sd_discover.h"
#include "a2dp_sd_init.h"
#include "a2dp_sd_initiate.h"
#include "a2dp_sd_open.h"
#include "a2dp_sd_led.h"
#include "a2dp_sd_scan.h"
#include "a2dp_sd_security.h"
#include "a2dp_sd_start.h"
#include "a2dp_sd_stream.h"
#include "a2dp_sd_suspend.h"
#include "a2dp_sd_interface.h"
#include <a2dp.h>
#include <avrcp.h>
#include <connection.h>
#include <panic.h>
#include <codec.h>
extern void _init(void);
/* Function prototypes */
static void app_handler(Task task, MessageId id, Message message);
/* This is the task data associated with the app. */
static a2dpSourceDongleTaskData theApp;
/* Unhandled state in the message handler */
static void unhandledState(MessageId id)
{
id = id;
/* printf("app PANIC: current state a2dp %d avrcp %d message id 0x%x\n",
theApp.a2dpState, theApp.avrcpState, id); */
Panic();
}
/****************************************************************************
NAME
getTheAppTask
DESCRIPTION
Returns the app's main task.
RETURNS
Task
*/
Task getTheAppTask(void)
{
return &theApp.task;
}
/*****************************************************************************/
void resetConnectTimeoutFlag(void)
{
theApp.connect_timer_expired = 0;
}
/****************************************************************************
NAME
avSourceDongleUpdateA2dpState
DESCRIPTION
Updates the local A2DP state.
RETURNS
Task
*/
void avSourceDongleUpdateA2dpState(a2dp_state new_state)
{
theApp.a2dpState = new_state;
if (theApp.a2dpState == a2dp_state_accepting)
{
/* When we're in accepting state enable page/ inquiry scan */
a2dpSdEnableConnectable(&theApp);
a2dpSdEnableDiscoverable(&theApp);
}
else if ((theApp.a2dpState == a2dp_state_discovering) ||
(theApp.a2dpState == a2dp_state_initiating))
{
/* Disable scanning, we're looking for devices or initiating a connection */
a2dpSdDisableConnectable(&theApp);
a2dpSdDisableDiscoverable(&theApp);
}
else if (theApp.a2dpState == a2dp_state_connected)
{
/* We're connected so enable page scan so the remote end can connect RCP */
a2dpSdEnableConnectable(&theApp);
a2dpSdDisableDiscoverable(&theApp);
}
/*
else in the states below don't change our scanning
a2dp_state_streaming,
a2dp_state_disconnecting
a2dp_state_initialising,
*/
}
/****************************************************************************
NAME
avSourceDongleRetrieveA2dpState
DESCRIPTION
Retrieve local A2DP state.
RETURNS
Task
*/
a2dp_state avSourceDongleRetrieveA2dpState(void)
{
return theApp.a2dpState;
}
/****************************************************************************
NAME
avSourceDongleUpdateAvrcpState
DESCRIPTION
Updates the local AV RCP state.
RETURNS
Task
*/
void avSourceDongleUpdateAvrcpState(avrcp_state new_state)
{
theApp.avrcpState = new_state;
if (theApp.avrcpState == avrcp_state_accepting)
{
/* If accepting enable page scan */
a2dpSdEnableConnectable(&theApp);
}
else if (theApp.avrcpState == avrcp_state_connected)
{
/* We're connected so disable all scanning */
a2dpSdDisableConnectable(&theApp);
a2dpSdDisableDiscoverable(&theApp);
}
/*
else in the states below don't change our scanning
avrcp_state_disconnecting,
avrcp_state_initialising
*/
}
/* Extra initialisation for time critical functionality */
void _init(void)
{
initInterfaceTimeCritical();
}
/* Entry point */
int main(void)
{
/* Initialise the Interface continued. */
a2dpSdInitInterface(&theApp);
/* Set up the application task handler */
theApp.task.handler = app_handler;
/* Init the local state */
a2dpSdInitLocalState(&theApp);
/* Init the Codec library if not a USB dongle */
#ifdef WOLFSON_CODEC
CodecInitWolfson(&theApp.task, 0);
#else
#ifdef USB_AUDIO_MODE
ConnectionInit(&theApp.task);
#else
CodecInitCsrInternal(&theApp.task);
#endif
#endif
/* Initialise the buttons */
pioInit(&theApp.pio_state, &theApp.task);
/* Initialise the LED flashing */
a2dpSdInitLed();
/* Start the message scheduler loop */
MessageLoop();
/* Never get here! */
return 0;
}
static void app_handler(Task task, MessageId id, Message message)
{
a2dp_state state_a2dp = theApp.a2dpState;
avrcp_state state_avrcp = theApp.avrcpState;
/* Keep the compiler happy */
task = task;
switch(id)
{
case CODEC_INIT_CFM:
if(((CODEC_INIT_CFM_T*)message)->status == codec_success)
{
/* Initialise the Connection Library */
theApp.codec_task = ((CODEC_INIT_CFM_T*)message)->codecTask;
ConnectionInit(&theApp.task);
}
else
Panic();
break;
case CODEC_CONFIGURE_CFM:
if(((CODEC_CONFIGURE_CFM_T*)message)->status == codec_success)
{
#ifdef WOLFSON_CODEC
CodecSetInputGain(theApp.codec_task, 0x1f, left_and_right_ch);
#endif
CodecEnable(theApp.codec_task);
}
else
Panic();
break;
case APP_INIT_CFM:
/* Check the current state */
switch (state_a2dp)
{
case a2dp_state_accepting:
/* Application init has completed */
MessageSend(getTheAppTask(), APP_KICK_PROFILE_REQ, 0);
break;
case a2dp_state_initialising:
case a2dp_state_discovering:
case a2dp_state_initiating:
case a2dp_state_connected:
case a2dp_state_streaming:
case a2dp_state_disconnecting:
default:
unhandledState(id);
break;
}
break;
case APP_DISCOVER_REQ:
/* Check the current state */
switch (state_a2dp)
{
case a2dp_state_accepting:
case a2dp_state_disconnecting:
/* Kick off a discovery process. */
a2dpSdDiscover(&theApp);
break;
case a2dp_state_connected:
case a2dp_state_streaming:
/* Force a disconnect */
MessageSend(&theApp.task, APP_CLOSE_REQ, 0);
/* Initiate a discovery after the disconnect */
theApp.discover_pending = 1;
break;
case a2dp_state_initiating:
/* Stop any further connect attempts. */
theApp.connect_timer_expired = 1;
/* Initiate a discovery after the connection completes */
theApp.discover_pending = 1;
break;
case a2dp_state_discovering:
/* Ignore we're already performing a discovery */
break;
case a2dp_state_initialising:
default:
unhandledState(id);
break;
}
break;
case APP_INITIATE_REQ:
/* Check the current state */
switch (state_a2dp)
{
case a2dp_state_accepting:
/* Initiate a connection to the remote device */
a2dpSdInitiateConnectionRequest(&theApp, (APP_INITIATE_REQ_T *) message);
break;
case a2dp_state_disconnecting:
case a2dp_state_connected:
case a2dp_state_streaming:
case a2dp_state_initiating:
case a2dp_state_discovering:
case a2dp_state_initialising:
default:
unhandledState(id);
break;
}
break;
case APP_CLOSE_REQ:
/* Check the current state */
switch (state_a2dp)
{
case a2dp_state_connected:
case a2dp_state_streaming:
/* Initiate the release of the A2DP connection */
a2dpSdCloseConnectionRequest(&theApp);
break;
case a2dp_state_disconnecting:
/* Ignore this we're already disconnecting */
break;
case a2dp_state_accepting:
case a2dp_state_initiating:
case a2dp_state_discovering:
case a2dp_state_initialising:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -