static const char *gyro_output_cb(guiObject_t *obj, int dir, void *data) { (void)obj; (void)data; u8 changed = 1; gyro_output = GUI_TextSelectHelper(gyro_output, GYROOUTPUT_GEAR , GYROOUTPUT_AUX2, dir, 2, 2, &changed); if (changed) { // switch gyro output between the gear and the aux2 // firstly: dynamically create mixes for target gyro channel int i; for (i = 0; i < GYROMIXER_COUNT; i ++) { if(! mp->mixer_ptr[i]) break; mp->mixer[i] = *mp->mixer_ptr[i]; mp->mixer[i].dest = gyro_output; } MIXER_SetTemplate(gyro_output, MIXERTEMPLATE_EXPO_DR); // secondly: clear mix for original gyro channel MIXER_SetTemplate(gyro_output == GYROOUTPUT_GEAR ? GYROOUTPUT_AUX2 : GYROOUTPUT_GEAR, MIXERTEMPLATE_NONE); // save mixers MIXER_SetMixers(mp->mixer, i); // reload mixers because order may change int count = STDMIX_GetMixers(mp->mixer_ptr, gyro_output, GYROMIXER_COUNT); convert_output_to_percentile(); for (i = 0; i < count; i ++) { GUI_Redraw(&gui->gyro[i]); } } if (gyro_output == GYROOUTPUT_GEAR) snprintf(tempstring, sizeof(tempstring), "%s/%s5", _tr("GEAR"), _tr("Ch")); else snprintf(tempstring, sizeof(tempstring), "%s/%s7", _tr("AUX2"), _tr("Ch")); return tempstring; }
void STDMIXER_SetChannelOrderByProtocol() { const u8 *ch_map = CurrentProtocolChannelMap; if (! ch_map) { // for none protocol, assign any channel to thr is fine ch_map = EATRG0; } CLOCK_ResetWatchdog();// this function might be invoked after loading from template/model file, so feeding the dog in the middle unsigned safetysw = 0; s8 safetyval = 0; for (unsigned ch = 0; ch < 3; ch++) { // only the first 3 channels need to check if (Model.limits[ch].safetysw) { safetysw = Model.limits[ch].safetysw; safetyval = Model.limits[ch].safetyval; } if (ch_map[ch] == INP_THROTTLE) mapped_std_channels.throttle = ch; else if (ch_map[ch] == INP_AILERON) mapped_std_channels.actual_aile = mapped_std_channels.aile = ch; else if (ch_map[ch] == INP_ELEVATOR) mapped_std_channels.actual_elev = mapped_std_channels.elev = ch; } Model.limits[mapped_std_channels.throttle].safetysw = safetysw; Model.limits[mapped_std_channels.throttle].safetyval = safetyval; Model.limits[mapped_std_channels.aile].safetysw = 0; Model.limits[mapped_std_channels.elev].safetysw = 0; Model.limits[mapped_std_channels.aile].safetyval = 0; Model.limits[mapped_std_channels.elev].safetyval = 0; //printf("thro: %d, aile: %d, elev: %d\n\n", mapped_std_channels.throttle, mapped_std_channels.aile, mapped_std_channels.elev); MIXER_SetTemplate(mapped_std_channels.throttle, MIXERTEMPLATE_COMPLEX); MIXER_SetTemplate(mapped_std_channels.aile, MIXERTEMPLATE_CYC1); MIXER_SetTemplate(mapped_std_channels.elev, MIXERTEMPLATE_CYC2); struct Mixer *mix = MIXER_GetAllMixers(); for (unsigned idx = 0; idx < NUM_MIXERS; idx++) { if (mix[idx].src ==0) continue; if (mix[idx].dest == NUM_OUT_CHANNELS + 9) mix[idx].src = 0; // remove all mixers pointing to Virt10, because the Virt10 is reserved in Standard mode else if (MIXER_MUX(&mix[idx]) == MUX_REPLACE && mix[idx].src== INP_THROTTLE && mix[idx].dest < NUM_OUT_CHANNELS) { // src=THR && dest = virt should be pitch's mixer mix[idx].dest = mapped_std_channels.throttle; } } MIXER_SetTemplate(NUM_OUT_CHANNELS + 9, MIXERTEMPLATE_NONE);// remove all mixers pointing to Virt10 as the Virt10 is reserved in Standard mode mapped_std_channels.aile = NUM_OUT_CHANNELS; // virt 1 mapped_std_channels.elev = NUM_OUT_CHANNELS +1; // virt 2 // Simplfied timer sw, only throttle channel output is possible to be selected for (unsigned i = 0; i < NUM_TIMERS; i++) { if (Model.timer[i].src) Model.timer[i].src = mapped_std_channels.throttle + NUM_INPUTS +1; TIMER_Reset(i); } CLOCK_ResetWatchdog(); }
static void okcancel_cb(guiObject_t *obj, const void *data) { (void)obj; if (data) { //Save mixer here MIXER_SetLimit(mp->channel, &mp->limit); MIXER_SetTemplate(mp->channel, mp->cur_template); MIXER_SetMixers(mp->mixer, mp->num_mixers); } PAGE_RemoveAllObjects(); PAGE_MixerInit(mp->top_channel); }