/**************************************************************************** NAME usbInit DESCRIPTION Initialisation done once the main loop is up and running. Determines USB attach status etc. RETURNS void */ void usbInit(void) { USB_DEBUG(("USB: Init\n")); /* Abort if no device classes supported */ if(!theSink.usb.config.device_class) return; /* If battery charging enabled set the charge current */ usbUpdateChargeCurrent(); #ifdef ENABLE_USB_AUDIO /* Pass NULL USB mic Sink until the plugin handles USB mic */ theSink.a2dp_link_data->a2dp_audio_connect_params.usb_params = NULL; #endif /* Schedule reset to low power mode if attached */ usbSetLowPowerMode(theSink.usb.config.attach_timeout); /* Check for audio */ theSink.usb.ready = TRUE; audioHandleRouting(audio_source_none); PioSetPio(theSink.conf1->PIOIO.pio_outputs.PowerOnPIO, pio_drive, TRUE); }
/**************************************************************************** NAME TonesPlayEvent DESCRIPTION function to indaicate an event by playing its associated tone uses underlying tones playback RETURNS void */ void TonesPlayEvent ( sinkEvents_t pEvent ) { uint16 lEvent = pEvent; int i = 0 ; /* Don't play tone for Mute Toggle, this event is auto-converted to either EventUsrMuteOn or EventUsrMuteOff */ if (pEvent == EventUsrMuteToggle) return; #ifdef ENABLE_SOUNDBAR /* In Limbo for sound bar build, playing tones may cause panic if I2S amplifier is powered down by PIO */ if(stateManagerGetState() == deviceLimbo) { /* If sound bar I2S amplifier shut down is managed by PIO, first check the logic state of amplifier power pin */ if((theSink.conf2->audio_routing_data.PluginFeatures.audio_output_type == OUTPUT_INTERFACE_TYPE_I2S) &&(theSink.features.AmplifierShutDownByPIO)) { /* Check configuration for AMP pio drive */ if(theSink.conf1->PIOIO.pio_outputs.PowerOnPIO != NO_PIO) { /* Do not attempt to play tones through I2S if amplifier is shut down already, otherwise, I2C comms will fail and cause panic */ if(theSink.audioAmpPowerPin != TRUE) return; } } } #endif /* ensure sink is not in muted state or trying to play the mute reminder */ if((theSink.sink_enable_present != TRUE)||(pEvent == EventSysMuteReminder)||(pEvent == EventUsrMuteOn)) { /* If Audio Prompts are disabled go straight to tones. Otherwise if Audio Prompt is assigned to this event tone playback would be skipped.*/ if(theSink.audio_prompts_enabled) { /* If there's a valid Audio Prompt event to play don't play any tones */ if(AudioPromptPlayEvent( pEvent )) return; } /* scan available tones list, list end is signified by NOT_DEFINED */ while ( theSink.conf2->gEventTones [i].tone != TONE_NOT_DEFINED ) { /* if an event matche is found then play tone */ if (theSink.conf2->gEventTones [i].event == lEvent ) { /* turn on audio amp */ PioSetPio ( theSink.conf1->PIOIO.pio_outputs.DeviceAudioActivePIO , pio_drive, TRUE) ; /* start check to turn amp off again if required */ MessageSendLater(&theSink.task , EventSysCheckAudioAmpDrive, 0, 1000); /* check event as tone queueing not allowed on mute and ring tones */ switch(pEvent) { case EventSysMuteReminder: case EventSysRingtone1: case EventSysRingtone2: /* check whether to play mute reminder tone at default volume level, never queue mute reminders to protect against the case that the tone is longer than the mute reminder timer */ TonesPlayTone (theSink.conf2->gEventTones [ i ].tone ,FALSE, (theSink.features.MuteToneFixedVolume)) ; break; /* for all other events use the QueueEventTones feature bit setting */ default: /* play tone */ TonesPlayTone (theSink.conf2->gEventTones [ i ].tone ,theSink.features.QueueEventTones, FALSE ) ; break; } } i++ ; } } }
/**************************************************************************** NAME PioSetLed DESCRIPTION Internal fn to change set an LED attached to a PIO or a special LED pin RETURNS void */ static void PioSetLed ( uint16 pPIO , bool pOnOrOff ) { LEDActivity_t * gActiveLED = &theSink.theLEDTask->gActiveLEDS[pPIO]; /* LED pins are special cases*/ if ( pPIO == 14) { if ( gActiveLED->DimTime > 0 ) /*if this is a dimming led / pattern*/ { if (theSink.theLEDTask->gLED_0_STATE != pOnOrOff) /*if the request is to do the same as what we are doing then ignore*/ { /*set led to max or min depending on whether we think the led is on or off*/ gActiveLED->DimState = (DIM_NUM_STEPS * !pOnOrOff) ; gActiveLED->DimDir = pOnOrOff ; /*1=go up , 0 = go down**/ #ifndef NO_LED2 LedConfigure(LED_0, LED_DUTY_CYCLE, (gActiveLED->DimState * (DIM_STEP_SIZE))); LedConfigure(LED_0, LED_PERIOD, DIM_PERIOD ); DIM_DEBUG(("DIM: Set LED [%d][%x][%d]\n" ,pPIO ,gActiveLED->DimState ,gActiveLED->DimDir )) ; LedConfigure(LED_0, LED_ENABLE, TRUE); #endif /*send the first message*/ MessageCancelAll ( &theSink.theLEDTask->task, (DIM_MSG_BASE + pPIO) ) ; MessageSendLater ( &theSink.theLEDTask->task, (DIM_MSG_BASE + pPIO) ,0 ,gActiveLED->DimTime ) ; theSink.theLEDTask->gLED_0_STATE = pOnOrOff ; } } else { #ifndef NO_LED2 DIM_DEBUG(("DIM 0 N:[%d]\n" , pOnOrOff)) ; LedConfigure(LED_0, LED_ENABLE, pOnOrOff ) ; LedConfigure(LED_0, LED_DUTY_CYCLE, (0xfff)); LedConfigure(LED_0, LED_PERIOD, DIM_PERIOD ); #endif theSink.theLEDTask->gLED_0_STATE = pOnOrOff ; } } else if (pPIO == 15 ) { if ( gActiveLED->DimTime > 0 ) /*if this is a dimming led / pattern*/ { if (theSink.theLEDTask->gLED_1_STATE != pOnOrOff) /*if the request is to do the same as what we are doing then ignore*/ { /*set led to max or min depending on whether we think the led is on or off*/ gActiveLED->DimState = (DIM_NUM_STEPS * !pOnOrOff) ; gActiveLED->DimDir = pOnOrOff ; /*1=go up , 0 = go down**/ #ifndef NO_LED2 LedConfigure(LED_1, LED_DUTY_CYCLE, (gActiveLED->DimState * (DIM_STEP_SIZE))); LedConfigure(LED_1, LED_PERIOD, DIM_PERIOD ); DIM_DEBUG(("DIM: Set LED [%d][%x][%d]\n" ,pPIO ,gActiveLED->DimState , gActiveLED->DimDir )) ; LedConfigure(LED_1, LED_ENABLE, TRUE); #endif /*send the first message*/ MessageCancelAll ( &theSink.theLEDTask->task, (DIM_MSG_BASE + pPIO) ) ; MessageSendLater ( &theSink.theLEDTask->task, (DIM_MSG_BASE + pPIO) ,0 ,gActiveLED->DimTime ) ; theSink.theLEDTask->gLED_1_STATE = pOnOrOff ; } } else { #ifndef NO_LED2 DIM_DEBUG(("DIM 1 N:[%d]\n" , pOnOrOff)) ; LedConfigure(LED_1, LED_ENABLE, pOnOrOff ) ; LedConfigure(LED_1, LED_DUTY_CYCLE, (0xfff)); LedConfigure(LED_1, LED_PERIOD, DIM_PERIOD ); #endif theSink.theLEDTask->gLED_1_STATE = pOnOrOff ; } } else if (pPIO == 10 ) { if ( gActiveLED->DimTime > 0 ) /*if this is a dimming led / pattern*/ { if (theSink.theLEDTask->gLED_2_STATE != pOnOrOff) /*if the request is to do the same as what we are doing then ignore*/ { /*set led to max or min depending on whether we think the led is on or off*/ gActiveLED->DimState = (DIM_NUM_STEPS * !pOnOrOff) ; gActiveLED->DimDir = pOnOrOff ; /*1=go up , 0 = go down**/ #ifndef NO_LED2 LedConfigure(LED_2, LED_DUTY_CYCLE, (gActiveLED->DimState * (DIM_STEP_SIZE))); LedConfigure(LED_2, LED_PERIOD, DIM_PERIOD ); DIM_DEBUG(("DIM: Set LED [%d][%x][%d]\n" ,pPIO ,gActiveLED->DimState , gActiveLED->DimDir )) ; LedConfigure(LED_2, LED_ENABLE, TRUE); #endif /*send the first message*/ MessageCancelAll ( &theSink.theLEDTask->task, (DIM_MSG_BASE + pPIO) ) ; MessageSendLater ( &theSink.theLEDTask->task, (DIM_MSG_BASE + pPIO) ,0 ,gActiveLED->DimTime ) ; theSink.theLEDTask->gLED_2_STATE = pOnOrOff ; } } else { #ifndef NO_LED2 DIM_DEBUG(("DIM 2 N:[%d]\n" , pOnOrOff)) ; LedConfigure(LED_2, LED_ENABLE, pOnOrOff ) ; LedConfigure(LED_2, LED_DUTY_CYCLE, (0xfff)); LedConfigure(LED_2, LED_PERIOD, DIM_PERIOD ); #endif theSink.theLEDTask->gLED_2_STATE = pOnOrOff ; } } else { PioSetPio (pPIO , pio_drive, pOnOrOff) ; } }