app_handler –> handleHFPMessage –> HFP_INIT_CFM –> InitEarlyUserFeatures –> buttonManagerInit –> ButtonsInit –> ButtonsMessageHandler –> MESSAGE_PIO_CHANGED –> ButtonsCheckDetection
由前面分析HFP的过程可以知道,当HFP_INIT_CFM 这个初始化确认消息过来之后,会进行InitEarlyUserFeatures 这个函数,这里便对按键进行了初始化我们往下看
void InitEarlyUserFeatures ( void )
{
ChargerConfigure(CHARGER_SUPPRESS_LED0, TRUE);
/* Initialise the Button Manager */
buttonManagerInit() ; /*这里对按键初始化1.*/
/* Once system Managers are initialised, load up the configuration */
configManagerInit(TRUE); /*这里对按键的配置进行读取4.*/
/* Init wired before USB or wired audio gets routed before init */
wiredAudioInit();
/* USB init can be done once power lib initialised */
usbInit();
/* initialise the display */
displayInit();
/* initialise DUT */
dutInit();
/*configure the audio Pre amp if enabled */
initPreAmp( AUDIO_CHANNEL_A) ;
initPreAmp( AUDIO_CHANNEL_B) ;
/* Enter the limbo state as we may be ON due to a charger being plugged in */
stateManagerEnterLimboState();
}
void buttonManagerInit ( void )
{
/*put the buttons task and the button patterens in a single memory block*/
int lSize = sizeof(ButtonsTaskData) ;
/*allocate the memory*/
theSink.theButtonsTask = mallocPanic( lSize );/*开辟了按键任务的空间*/
/* initialise structure */
memset(theSink.theButtonsTask, 0, lSize);
theSink.theButtonsTask->client = &theSink.task;/*和app任务关联*/
/*create the array of Button Events that we are going to populate*/
BM_DEBUG(("BM: ButtonEvents block size [%u]\n" , sizeof( ButtonEvents_t ) * BM_EVENTS_PER_CONF_BLOCK ));
theSink.theButtonsTask->gButtonEvents[0] = (ButtonEvents_t * ) ( mallocPanic( sizeof( ButtonEvents_t ) * BM_EVENTS_PER_CONF_BLOCK ) ) ;
theSink.theButtonsTask->gButtonEvents[1]= (ButtonEvents_t * ) ( mallocPanic( sizeof( ButtonEvents_t ) * BM_EVENTS_PER_CONF_BLOCK ) ) ;
/*init the PIO button routines with the Button manager Task data */
ButtonsInit( theSink.theButtonsTask ) ; /*具体的初始化开始*/
}
void ButtonsInit ( ButtonsTaskData *pButtonsTask )
{
#ifdef ENABLE_CAPSENSE
uint8 i;
bool success;
#endif
pButtonsTask->task.handler = ButtonsMessageHandler;/*按键任务的回调函数*/
/*connect the underlying PIO task to this task*/
MessagePioTask(&pButtonsTask->task);/*这个函数在没有蓝牙协议的BUTTON的例子看到过,This task will receive MESSAGE_PIO_CHANGED messages when the pins configured by PioDebounce32()(后面会有提到这个函数) change.,经过这个韩式,当有按键变化时,上面的回调函数就会被执行*/
/*connect the underlying Charger task to this task*/
MessageChargerTask(&pButtonsTask->task);/*这个和充电相关,目前不用考虑*/
#ifdef ENABLE_CAPSENSE/*这个宏定义不打开,所以不用看*/
/* set the update rate, currently a fast update rate to detect short touches */
success = CapsenseConfigure(CAPSENSE_SET_CINT_UPDATE_DIVIDER, 0);
/* set an initial trigger level for the cap sensors, this level will depend
upon hardware and tests will need to be carried out to determine what a particular
implementation requires */
for (i = 0; success && (i < BM_CAP_SENSORS); i++)
success = CapsenseConfigurePad(i, CAPSENSE_SET_TRIGGER_LEVEL, BM_CAP_SENSOR_LOW_SENSITIVITY);
B_DEBUG(("B: capsense %s\n", success ? "OK" : "FAIL: check CONFIG_CAP_SENSE_PRELOAD")) ;
/* initialise task handler for capsense events after a short delay due to spurious events
generated from the firmware during this time */
MessageSendLater(&pButtonsTask->task,B_MESSAGE_CAPSENSE_ENABLE,0,CAPSENSE_INIT_INTERVAL);
#endif
}
/* Read and configure the button translations */
configManagerButtonTranslations( );
/* Read and configure the button durations */
configManagerButtonDurations( );
/* Read the system event configuration and configure the buttons */
configManagerButtons( );
/*configures the pattern button events*/
configManagerButtonPatterns( ) ;
下面重点分析这四个函数
DESCRIPTION
Read the button translation configuration from persistent store and configure
the button input assignments, these could be pio or capacitive touch sensors
RETURNS
void
*/
static void configManagerButtonTranslations( void )
{
/* get current input/button translations from eeprom or const if no eeprom */
ConfigRetrieve(CONFIG_BUTTON_TRANSLATION, &theSink.theButtonsTask->gTranslations, (sizeof(button_translation_type) * BM_NUM_BUTTON_TRANSLATIONS));
}
DESCRIPTION
Read the button configuration from persistent store and configure
the button durations
RETURNS
void
*/
static void configManagerButtonDurations( void )
{
if(ConfigRetrieve(CONFIG_BUTTON, &theSink.conf1->buttons_duration, sizeof(button_config_type)))
{
/*buttonmanager keeps buttons block*/
buttonManagerConfigDurations ( theSink.theButtonsTask , &theSink.conf1->buttons_duration );
}
}
static void configManagerButtons( void )
{
/* Allocate enough memory to hold event configuration */
event_config_type* configA = (event_config_type*) mallocPanic(BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type));
event_config_type* configB = (event_config_type*) mallocPanic(BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type));
event_config_type* configC = (event_config_type*) mallocPanic(BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type));
uint16 n;
uint8 i = 0;
ConfigRetrieve(CONFIG_EVENTS_A, configA, BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)) ;
ConfigRetrieve(CONFIG_EVENTS_B, configB, BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)) ;
ConfigRetrieve(CONFIG_EVENTS_C, configC, BM_EVENTS_PER_PS_BLOCK * sizeof(event_config_type)) ;
/* Now we have the event configuration, map required events to system events */
for(n = 0; n < BM_EVENTS_PER_PS_BLOCK; n++)
{
CONF_DEBUG(("Co : AddMap indexes [%u,%u] Ev[%x][%x][%x]\n", n, i, configA[n].event , configB[n].event, configC[n].event )) ;
/* check to see if a valid pio mask is present, this includes the upper 2 bits of the state
info as these are being used for bc5 as vreg enable and charger detect */
if ( (configA[n].pio_mask)||(configA[n].state_mask & 0xC000))
buttonManagerAddMapping ( &configA[n], i++ );
if ( (configB[n].pio_mask)||(configB[n].state_mask & 0xC000))
buttonManagerAddMapping ( &configB[n], i++ );
if ( (configC[n].pio_mask)||(configC[n].state_mask & 0xC000))
buttonManagerAddMapping ( &configC[n], i++ );
}
freePanic(configA) ;
freePanic(configB) ;
freePanic(configC) ;
/* perform an initial pio check to see if any pio changes need processing following the completion
of the configuration ps key reading */
BMCheckButtonsAfterReadingConfig();
}
static void configManagerButtonPatterns( void )
{
/* Allocate enough memory to hold event configuration */
button_pattern_config_type* config = (button_pattern_config_type*) mallocPanic(BM_NUM_BUTTON_MATCH_PATTERNS * sizeof(button_pattern_config_type));
CONF_DEBUG(("Co: No Button Patterns - %d\n", BM_NUM_BUTTON_MATCH_PATTERNS));
/* Now read in event configuration */
if(config)
{
if(ConfigRetrieve(CONFIG_BUTTON_PATTERN_CONFIG, config, BM_NUM_BUTTON_MATCH_PATTERNS * sizeof(button_pattern_config_type)))
{
uint16 n;
/* Now we have the event configuration, map required events to system events */
for(n = 0; n < BM_NUM_BUTTON_MATCH_PATTERNS ; n++)
{
CONF_DEBUG(("Co : AddPattern Ev[%x]\n", config[n].event )) ;
/* Map PIO button event to system events in specified states */
buttonManagerAddPatternMapping ( theSink.theButtonsTask , config[n].event , config[n].pattern, n ) ;
}
}
else
{
CONF_DEBUG(("Co: !EvLen\n")) ;
}
freePanic(config) ;
}
}
———————————————————-华丽丽的分割线—————–
分析按键,必须和sink configuration配合使用,接下来分析sink configuration的使用..
转载:http://blog.csdn.net/code_warry/article/details/50538217