Example #1
0
const char *set_drsource_cb(guiObject_t *obj, int dir, void *data)
{
    (void) obj;
    u8 *source = (u8 *)data;
    u8 is_neg = MIXER_SRC_IS_INV(*source);
    u8 changed;
    u8 oldsrc = *source;
    *source = GUI_TextSelectHelper(MIXER_SRC(*source), 0, NUM_SOURCES, dir, 1, 1, &changed);
    MIXER_SET_SRC_INV(*source, is_neg);
    if (changed) {
        sync_mixers();
        if ((!! MIXER_SRC(oldsrc)) ^ (!! MIXER_SRC(*source))) {
            // bug fix (issues #191) : only invoke _update_rate_widgets() for expo template
            if (mp->cur_template == MIXERTEMPLATE_EXPO_DR) {
                if(data == &mp->mixer[1].sw)
                    _update_rate_widgets(0);
                else if(data == &mp->mixer[2].sw)
                    _update_rate_widgets(1);
            }
        } else {    
            MIXPAGE_RedrawGraphs();
        }
    }
    GUI_TextSelectEnablePress((guiTextSelect_t *)obj, MIXER_SRC(*source));
    return INPUT_SourceName(mp->tmpstr, *source);
}
Example #2
0
void STDMIXER_InitSwitches()
{
    struct Mixer *mix = MIXER_GetAllMixers();

    if (Model.limits[mapped_std_channels.throttle].safetysw)
        mapped_std_channels.switches[SWITCHFUNC_HOLD] =  MIXER_SRC(Model.limits[mapped_std_channels.throttle].safetysw);
    unsigned found_gyro_switch = 0;
    unsigned found_flymode_switch = 0;
    unsigned found_drexp_rud_switch = 0;
    unsigned found_drexp_ail_switch = 0;
    unsigned found_drexp_ele_switch = 0;
    for (unsigned idx = 0; idx < NUM_MIXERS; idx++) {
        if (!MIXER_SRC(mix[idx].src) || MIXER_MUX(&mix[idx]) != MUX_REPLACE)  // all none replace mux will be considered as program mix in the Standard mode
            continue;
        if (!found_gyro_switch && mix[idx].sw != 0 && (mix[idx].dest == mapped_std_channels.gear || mix[idx].dest == mapped_std_channels.aux2)) {
            found_gyro_switch = 1;
            mapped_std_channels.switches[SWITCHFUNC_GYROSENSE] = mix[idx].sw;
        } else if (!found_drexp_rud_switch && mix[idx].dest == mapped_std_channels.rudd && mix[idx].sw != 0) {
            found_drexp_rud_switch = 1;
            mapped_std_channels.switches[SWITCHFUNC_DREXP_RUD] = mix[idx].sw;
        } else if (!found_drexp_ail_switch && mix[idx].dest == mapped_std_channels.aile && mix[idx].sw != 0) {
            found_drexp_ail_switch = 1;
            mapped_std_channels.switches[SWITCHFUNC_DREXP_AIL] = mix[idx].sw;
        } else if (!found_drexp_ele_switch && mix[idx].dest == mapped_std_channels.elev && mix[idx].sw != 0) {
            found_drexp_ele_switch = 1;
            mapped_std_channels.switches[SWITCHFUNC_DREXP_ELE] = mix[idx].sw;
        } else if (!found_flymode_switch && (mix[idx].dest == NUM_OUT_CHANNELS + 2) && mix[idx].sw != 0) { //virt3
            found_flymode_switch = 1;
            mapped_std_channels.switches[SWITCHFUNC_FLYMODE] = mix[idx].sw;
        }
        if (found_flymode_switch && found_gyro_switch && found_drexp_rud_switch && found_drexp_ail_switch && found_drexp_ele_switch)
            break;  // don't need to check the rest
    }
}
Example #3
0
const char *set_source_cb(guiObject_t *obj, int dir, void *data)
{
    (void) obj;
    u8 *source = (u8 *)data;
    if (!GUI_IsTextSelectEnabled(obj) ) {
        strcpy(mp->tmpstr, _tr("None"));
        return mp->tmpstr;
    }
    u8 is_neg = MIXER_SRC_IS_INV(*source);
    u8 changed;
    *source = GUI_TextSelectHelper(MIXER_SRC(*source), 1, NUM_SOURCES, dir, 1, 1, &changed);
    MIXER_SET_SRC_INV(*source, is_neg);
    if (changed) {
        if(mp->cur_template == MIXERTEMPLATE_COMPLEX) {
            guiObject_t *trim = _get_obj(COMPLEX_TRIM, 0);
            if(trim) {
                if (MIXER_SourceHasTrim(MIXER_SRC(mp->mixer[0].src)))
                    GUI_SetHidden(trim, 0);
                else
                    GUI_SetHidden(trim, 1);
            }
        }
        sync_mixers();
        MIXPAGE_RedrawGraphs();
    }
    GUI_TextSelectEnablePress((guiTextSelect_t *)obj, MIXER_SRC(*source));
    return INPUT_SourceName(mp->tmpstr, *source);
}
Example #4
0
void sync_mixers()
{
    switch(mp->cur_template) {
    case MIXERTEMPLATE_NONE:
    case MIXERTEMPLATE_CYC1:
    case MIXERTEMPLATE_CYC2:
    case MIXERTEMPLATE_CYC3:
        mp->num_mixers = 0;
        break;
    case MIXERTEMPLATE_SIMPLE:
        mp->mixer[0].sw = 0;
        MIXER_SET_MUX(&mp->mixer[0], MUX_REPLACE);
        mp->num_mixers = 1;
        break;
    case MIXERTEMPLATE_COMPLEX:
        mp->num_mixers = mp->num_complex_mixers;
        break;
    case MIXERTEMPLATE_EXPO_DR:
        mp->num_mixers = 1;
        if (MIXER_SRC(mp->mixer[1].sw)) {
            mp->num_mixers++;
            mp->mixer[1].src    = mp->mixer[0].src;
            mp->mixer[1].dest   = mp->mixer[0].dest;
            MIXER_SET_MUX(&mp->mixer[1], MUX_REPLACE);
            mp->mixer[1].offset = 0;
            MIXER_SET_APPLY_TRIM(&mp->mixer[1], MIXER_APPLY_TRIM(&mp->mixer[0]));
        } else {
            mp->mixer[1].src = 0;
        }
        if (mp->link_curves & 0x01)
            mp->mixer[1].curve = mp->mixer[0].curve;
        if (MIXER_SRC(mp->mixer[2].sw)) {
            mp->num_mixers++;
            mp->mixer[2].src    = mp->mixer[0].src;
            mp->mixer[2].dest   = mp->mixer[0].dest;
            MIXER_SET_MUX(&mp->mixer[2], MUX_REPLACE);
            mp->mixer[2].offset = 0;
            MIXER_SET_APPLY_TRIM(&mp->mixer[2], MIXER_APPLY_TRIM(&mp->mixer[0]));
        } else {
            mp->mixer[2].src = 0;
        }
        if (mp->link_curves & 0x02)
            mp->mixer[2].curve = mp->mixer[0].curve;
        MIXER_SET_MUX(&mp->mixer[0], MUX_REPLACE);
        mp->mixer[0].offset = 0;
        mp->mixer[0].sw = 0;
        break;
    }
}
Example #5
0
static const char *set_source_cb(guiObject_t *obj, int dir, void *data)
{
    (void) obj;
    u8 *source = (u8 *)data;
    *source = GUI_TextSelectHelper(MIXER_SRC(*source), 0, NUM_SOURCES, dir, 1, 1, NULL);
    return INPUT_SourceName(tp->tmpstr, MIXER_MapChannel(*source));
}
Example #6
0
static void _update_rate_widgets(u8 idx)
{
    u8 mix = idx + 1;
    guiObject_t *link = GUI_GetScrollableObj(&gui->scrollable, idx ? EXPO_LINK2 : EXPO_LINK1, 0);
    guiObject_t *curve = GUI_GetScrollableObj(&gui->scrollable, idx ? EXPO_CURVE2 : EXPO_CURVE1, 0);
    guiObject_t *scale = GUI_GetScrollableObj(&gui->scrollable, idx ? EXPO_SCALE2 : EXPO_SCALE1, 0);
    if (MIXER_SRC(mp->mixer[mix].sw)) {
        if(link)
            GUI_ButtonEnable(link, 1);
        if(curve) {
            if(mp->link_curves & mix ) {
                GUI_TextSelectEnable((guiTextSelect_t *)curve, 0);
            } else {
                GUI_TextSelectEnable((guiTextSelect_t *)curve, 1);
            }
        }
        if(scale)
            GUI_TextSelectEnable((guiTextSelect_t *)scale, 1);
    } else {
        if(link)
            GUI_ButtonEnable(link, 0);
        if(curve)
            GUI_TextSelectEnable((guiTextSelect_t *)curve, 0);
        if(scale)
            GUI_TextSelectEnable((guiTextSelect_t *)scale, 0);
    }
}
Example #7
0
int compact_mixers() {
    unsigned max = NUM_MIXERS;
    unsigned i = 0;
    unsigned j;
    while(i < max) {
        unsigned src = MIXER_SRC(Model.mixers[i].src);
        if(! src 
           || Model.templates[Model.mixers[i].dest] == MIXERTEMPLATE_NONE
           || Model.templates[Model.mixers[i].dest] == MIXERTEMPLATE_CYC1
           || Model.templates[Model.mixers[i].dest] == MIXERTEMPLATE_CYC2
           || Model.templates[Model.mixers[i].dest] == MIXERTEMPLATE_CYC3)
        {
            //Found an empty space so move all following mixers down 1 and decrease max
            for (j = i + 1; j < max; j++) {
                Model.mixers[j - 1] = Model.mixers[j];
            }
            max--;
        } else {
            //Found a used mixer so go to the next one
            i++;
        }
    }
    //Zero outunused mixers
    memset(Model.mixers + max, 0, sizeof(struct Mixer) * (NUM_MIXERS - max));
    return i;
}
Example #8
0
static int complex_row_cb(int absrow, int relrow, int y, void *data)
{
    const char *label = NULL;
    void *tgl = NULL;
    void *value = NULL;
    data = NULL;
    int x = 0;
    int w = LEFT_VIEW_WIDTH;
    if (absrow + COMMON_LAST == COMPLEX_TRIM) {
        GUI_CreateButtonPlateText(&gui->value[relrow].but, x, y,
            w, ITEM_HEIGHT, &labelDesc, show_trim_cb, 0x0000, toggle_trim_cb, NULL);
        if (! MIXER_SourceHasTrim(MIXER_SRC(mp->mixer[0].src)))
            GUI_SetHidden((guiObject_t *)&gui->label[relrow], 1);
        return 1;
    }
    switch(absrow + COMMON_LAST) {
        case COMPLEX_MIXER:
            label = _tr_noop("Mixers");
            value = set_nummixers_cb;
            break;
        case COMPLEX_PAGE:
            label = _tr_noop("Page");
            tgl = reorder_cb; value = set_mixernum_cb;
            break;
        case COMPLEX_SWITCH:
            label = _tr_noop("Switch");
            tgl = sourceselect_cb; value = set_drsource_cb; data = &mp->cur_mixer->sw;
            break;
        case COMPLEX_MUX:
            label = _tr_noop("Mux");
            value = set_mux_cb;
            break;
        case COMPLEX_SRC:
            label = _tr_noop("Src");
            tgl = sourceselect_cb; value = set_source_cb; data = &mp->cur_mixer->src;
            break;
        case COMPLEX_CURVE:
            label = _tr_noop("Curve");
            tgl = curveselect_cb; value = set_curvename_cb; data = mp->cur_mixer;
            break;
        case COMPLEX_SCALE:
            label = _tr_noop("Scale");
            value = set_number100_cb; data = &mp->cur_mixer->scalar;
            break;
        case COMPLEX_OFFSET:
            label = _tr_noop("Offset");
            value = set_number100_cb; data = &mp->cur_mixer->offset;
            break;
    }
    labelDesc.style = LABEL_LEFTCENTER;
    GUI_CreateLabelBox(&gui->label[relrow], x, y, w, ITEM_HEIGHT,
            &labelDesc, NULL, NULL, _tr(label));
    labelDesc.style = LABEL_CENTER;
    GUI_CreateTextSelectPlate(&gui->value[relrow].ts, x, y + ITEM_HEIGHT + 1,
            w, ITEM_HEIGHT, &labelDesc, tgl, value, data);
    if (absrow + COMMON_LAST == COMPLEX_SRC)
        set_src_enable(CURVE_TYPE(&mp->cur_mixer->curve));
    return 1;
}
Example #9
0
void sourceselect_cb(guiObject_t *obj, void *data)
{
    u8 *source = (u8 *)data;
    if (MIXER_SRC(*source)) {
        MIXER_SET_SRC_INV(*source, ! MIXER_SRC_IS_INV(*source));
        GUI_Redraw(obj);
        MIXPAGE_RedrawGraphs();
    }
}
Example #10
0
void toggle_source_cb(guiObject_t *obj, void *data)
{
    u8 idx = (long)data;
    struct Timer *timer = &Model.timer[idx];
    if(MIXER_SRC(timer->src)) {
        MIXER_SET_SRC_INV(timer->src, ! MIXER_SRC_IS_INV(timer->src));
        TIMER_Reset(idx);
        GUI_Redraw(obj);
    }
}
Example #11
0
static void show_iconsel_page(int SelectedIcon)
{
    struct ImageMap img;
    int toggleinput = MIXER_SRC(Model.pagecfg2.elem[tp->tglidx].src);
    PAGE_RemoveAllObjects();
    PAGE_ShowHeader(INPUT_SourceNameAbbrevSwitch(tempstring, toggleinput));
    GUI_CreateButton(&gui->revert, LCD_WIDTH-96-8, 4, BUTTON_96, revert_str_cb, revert_cb, NULL);
    // Show name of source for toggle icon

    // style the switch textbox
    struct LabelDesc outline = {
        .font = DEFAULT_FONT.font,
        .style = LABEL_TRANSPARENT,
        .font_color = DEFAULT_FONT.font_color,
        .fill_color = DEFAULT_FONT.fill_color,
        .outline_color = DEFAULT_FONT.outline_color
    };

    GUI_CreateRect(&gui->toggleframe, 80+80*SelectedIcon, 39, 77, 33, &outline);

    GUI_CreateLabelBox(&gui->switchbox,  4, 47, 70, 22, &NORMALBOX_FONT, NULL, NULL,
                       INPUT_SourceNameAbbrevSwitch(tempstring, Model.pagecfg2.elem[tp->tglidx].src));

    int num_positions = INPUT_NumSwitchPos(toggleinput);
    if(num_positions < 2)
        num_positions = 2;

    GUI_CreateLabelBox(&gui->togglelabel[0], 94, 50, 30, 14, &LABEL_FONT, NULL, NULL, _tr("Pos 0"));
    img = TGLICO_GetImage(Model.pagecfg2.elem[tp->tglidx].extra[0]);
    GUI_CreateImageOffset(&gui->toggleicon[0], 124, 40, TOGGLEICON_WIDTH, TOGGLEICON_HEIGHT, img.x_off, img.y_off, img.file,
             SelectedIcon == 0 ? tglico_reset_cb : tglico_setpos_cb, (void *)0L);

    GUI_CreateLabelBox(&gui->togglelabel[1], 174, 50, 30, 14, &LABEL_FONT, NULL, NULL, _tr("Pos 1"));
    img = TGLICO_GetImage(Model.pagecfg2.elem[tp->tglidx].extra[1]);
    GUI_CreateImageOffset(&gui->toggleicon[1], 204, 40, TOGGLEICON_WIDTH, TOGGLEICON_HEIGHT, img.x_off, img.y_off, img.file,
             SelectedIcon == 1 ? tglico_reset_cb : tglico_setpos_cb, (void *)1L);
    if (num_positions == 3) {
        GUI_CreateLabelBox(&gui->togglelabel[2], 254, 50, 30, 14, &LABEL_FONT, NULL, NULL, _tr("Pos 2"));
        img = TGLICO_GetImage(Model.pagecfg2.elem[tp->tglidx].extra[2]);
        GUI_CreateImageOffset(&gui->toggleicon[2], 284, 40, TOGGLEICON_WIDTH, TOGGLEICON_HEIGHT, img.x_off, img.y_off, img.file,
             SelectedIcon == 2 ? tglico_reset_cb : tglico_setpos_cb, (void *)2L);
    }

    int count = get_toggle_icon_count();
    int max_scroll = (count + NUM_SYMBOL_COLS - 1) / NUM_SYMBOL_COLS - (NUM_SYMBOL_ROWS - 1);
    if (max_scroll > 1) GUI_CreateScrollbar(&gui->scrollbar, LCD_WIDTH-16, 80, LCD_HEIGHT-80, max_scroll, NULL, scroll_cb, (void *)(long)SelectedIcon);
    show_icons(SelectedIcon, 0);
}

void PAGE_ToggleEditInit(int page) {
    tp->tglidx = page;
    memcpy(tp->tglicons, Model.pagecfg2.elem[tp->tglidx].extra, sizeof(tp->tglicons));
    show_iconsel_page(0);
}
Example #12
0
static void navigate_toggleicons(s8 direction) {
    int toggleinput = MIXER_SRC(Model.pagecfg2.elem[tp->tglidx].src);
    int num_positions = INPUT_NumSwitchPos(toggleinput);
    if(num_positions < 2)
        num_positions = 2;
    current_toggleicon += direction;
    if (current_toggleicon < 0)
        current_toggleicon = num_positions;
    else if (current_toggleicon > num_positions)
        current_toggleicon = 0;
    show_iconsel_page(current_toggleicon);
}
Example #13
0
const char *_set_src_cb(guiTextSelect_t *obj, u8 *src, int dir, int idx, int source)
{
    u8 changed;
    if (Model.mixer_mode == MIXER_STANDARD && Model.type == MODELTYPE_HELI)  { //Improvement: only to intelligent switch setting for heli type in standard mode
        int is_neg = MIXER_SRC_IS_INV(*src);
        int step = mapped_std_channels.throttle + NUM_INPUTS +1;
        int newsrc = GUI_TextSelectHelper(MIXER_SRC(*src), 0, step, dir, step, step, &changed);
        MIXER_SET_SRC_INV(newsrc, is_neg);
        *src = newsrc;
    } else {
        if (source <= INP_NONE)
            *src = INPUT_SelectSource(*src, dir, &changed);
        else
            *src = INPUT_SelectInput(*src, source, &changed);
    }
    if (changed) {
        TIMER_Reset(idx);
    }
    GUI_TextSelectEnablePress(obj, MIXER_SRC(*src));
    return INPUT_SourceName(tempstring, *src);
}
Example #14
0
u8 curpos_cb(s16 *x, s16 *y, u8 pos, void *data)
{
    if (pos != 0)
        return 0;
    *x = mp->raw[MIXER_SRC(mp->cur_mixer->src)];
    if (*x > CHAN_MAX_VALUE)
        *x = CHAN_MAX_VALUE;
    else if (*x  < CHAN_MIN_VALUE)
        *x = CHAN_MIN_VALUE;
    *y = eval_mixer_cb(*x, data);
    return 1;
}
Example #15
0
int MIXER_GetMixers(int ch, struct Mixer *mixers, int count)
{
    int idx = 0;
    int i;
    for(i = 0; i < NUM_MIXERS; i++) {
        if (MIXER_SRC(Model.mixers[i].src) && Model.mixers[i].dest == ch) {
            mixers[idx++] = Model.mixers[i];
            if(idx == count)
                return count;
        }
    }
    return idx;
}
Example #16
0
unsigned switch_is_on(unsigned sw, volatile s32 *raw)
{
    unsigned is_neg = MIXER_SRC_IS_INV(sw);
    sw = MIXER_SRC(sw);
    if(sw == 0) {
        // No switch selected is the same as an on switch
        return 1;
    }
    s32 value = raw[sw];
    if (is_neg)
        value = - value;
    return (value > 0);
}
Example #17
0
int MIXER_SetMixers(struct Mixer *mixers, int count)
{
    int i;
    if (count) {
        int mixer_count = 0;
        unsigned dest = mixers[0].dest;
        //Determine if we have enough free mixers
        for (i = 0; i < NUM_MIXERS; i++) {
            if (MIXER_SRC(Model.mixers[i].src) && Model.mixers[i].dest != dest)
                mixer_count++;
        }
        if (mixer_count + count > NUM_MIXERS) {
            printf("Need %d free mixers, but only %d are available\n", count, NUM_MIXERS - mixer_count);
            return 0;
        }
        //Remove all mixers for this channel
        for (i = 0; i < NUM_MIXERS; i++) {
            if (MIXER_SRC(Model.mixers[i].src) && Model.mixers[i].dest == dest)
                Model.mixers[i].src = 0;
        }
    }
    unsigned pos = compact_mixers();
    for (i = 0; i < count; i++) {
        if (! MIXER_SRC(mixers[i].src) && CURVE_TYPE(&mixers[i].curve) == CURVE_FIXED) {
            mixers[i].src = mixers[i].sw || 1;
        }
        if (MIXER_SRC(mixers[i].src)) {
            Model.mixers[pos] = mixers[i];
            if(Model.templates[mixers[i].dest] != MIXERTEMPLATE_COMPLEX) {
                //Always apply the trim if the template is not 'complex'
                MIXER_SET_APPLY_TRIM(&Model.mixers[pos], 1);
            }
            pos++;
        }
    }
    fix_mixer_dependencies(pos);
    return 1;
}
Example #18
0
static const char *set_source_helper(guiObject_t *obj, void *data, int changed) {
    (void) obj;
    u8 *source = (u8 *)data;
    if (!GUI_IsTextSelectEnabled(obj) ) {
        tempstring_cpy(_tr("None"));
        return tempstring;
    }
    if (changed) {
        if(mp->cur_template == MIXERTEMPLATE_COMPLEX) {
            guiObject_t *trim = _get_obj(COMPLEX_TRIM, 0);
            if(trim) {
                if (MIXER_SourceHasTrim(MIXER_SRC(mp->mixer[0].src)))
                    GUI_SetHidden(trim, 0);
                else
                    GUI_SetHidden(trim, 1);
            }
        }
        sync_mixers();
        MIXPAGE_RedrawGraphs();
    }
    GUI_TextSelectEnablePress((guiTextSelect_t *)obj, MIXER_SRC(*source));
    return INPUT_SourceName(tempstring, *source);
}
Example #19
0
static const char *set_switch_cb(guiObject_t *obj, int dir, void *data)
{
    if(! GUI_IsTextSelectEnabled(obj)){
        return _tr("None");
    }
    u8 *source = (u8 *)data;
    u8 changed;
    u8 val = MIXER_SRC(*source);

    int newval = GUI_TextSelectHelper(val, 0, NUM_SOURCES, dir, 1, 1, &changed);
    newval = INPUT_GetAbbrevSource(val, newval, dir);
    if (val != newval) {
        val = newval;
        *source = val;
    }
    return INPUT_SourceNameAbbrevSwitch(tp->tmpstr, *source);
}
Example #20
0
s32 MIXER_ApplyLimits(unsigned channel, struct Limit *limit, volatile s32 *_raw,
                      volatile s32 *_Channels, enum LimitMask flags)
{
    int applied_safety = 0;
    s32 value = _raw[NUM_INPUTS + 1 + channel] + get_trim(NUM_INPUTS + 1 + channel);
    if (channel >= NUM_OUT_CHANNELS)
        return value;

    if ((flags & APPLY_SAFETY) && MIXER_SRC(limit->safetysw) && switch_is_on(limit->safetysw, _raw)) {
        applied_safety = 1;
        value = PCT_TO_RANGE(Model.limits[channel].safetyval);
    }
    if (flags & APPLY_SCALAR) {
        if (value >= 0 || limit->servoscale_neg == 0)
            value = (s32)value * limit->servoscale / 100;
        else
            value = (s32)value * limit->servoscale_neg / 100;
    }
    if ((flags & APPLY_REVERSE) && (limit->flags & CH_REVERSE)) {
        value = -value;
    }
    if (flags & APPLY_SUBTRIM)
        value += PCT_TO_RANGE(limit->subtrim) / 10;
    if (! applied_safety) {
        //degrees / 100msec
        if (_Channels && (flags & APPLY_SPEED) && limit->speed) {
            s32 rate = CHAN_MAX_VALUE * limit->speed / 60 * MEDIUM_PRIORITY_MSEC / 100;
            if (value - _Channels[channel] > rate)
                value = _Channels[channel] + rate;
            else if(value - _Channels[channel] < -rate)
                value = _Channels[channel] - rate;
        }
    }
    if (flags & APPLY_LIMITS) {
        if (value > PCT_TO_RANGE(limit->max))
            value = PCT_TO_RANGE(limit->max);
        else if( value < PCT_TO_RANGE(-(int)limit->min))
            value = PCT_TO_RANGE(-(int)limit->min);
    } else {
        if (value > INT16_MAX)
            value = INT16_MAX;
        else if (value < INT16_MIN)
            value = INT16_MIN;
    }      
    return value;
}
Example #21
0
s16 eval_chan_cb(void * data)
{
    (void)data;
    int i;
    struct Mixer *mix = MIXER_GetAllMixers();
    for (i = 0; i < NUM_MIXERS; i++) {
        if(MIXER_SRC(mix->src) != 0 && mix->dest != mp->cur_mixer->dest)
            MIXER_ApplyMixer(mix, mp->raw, NULL);
    }
    for (i = 0; i < mp->num_mixers; i++)
        MIXER_ApplyMixer(&mp->mixer[i], mp->raw, NULL);
    s16 value = MIXER_ApplyLimits(mp->cur_mixer->dest, &mp->limit, mp->raw, NULL, APPLY_ALL);
    if (value > CHAN_MAX_VALUE)
        return CHAN_MAX_VALUE;
    if (value < CHAN_MIN_VALUE)
        return CHAN_MIN_VALUE;
    return value;
}
Example #22
0
static void show_iconsel_page(int SelectedIcon) {
    GUI_RemoveAllObjects();
    memset(gui, 0, sizeof(*gui));
    current_toggleicon = SelectedIcon;
    int toggleinput = MIXER_SRC(Model.pagecfg2.elem[tp->tglidx].src);

    //Header
    PAGE_ShowHeader(INPUT_SourceNameAbbrevSwitch(tempstring, toggleinput));
    labelDesc.style = LABEL_CENTER;
    GUI_CreateButtonPlateText(&gui->revert, REVERT_X, 0, REVERT_W, HEADER_WIDGET_HEIGHT, &labelDesc, NULL, 0, revert_cb, (void *)_tr("Revert"));

#if SEPARATOR
    GUI_CreateRect(&gui->separator, SEPARATOR_X, HEADER_WIDGET_HEIGHT, 1, LCD_HEIGHT-HEADER_HEIGHT, &labelDesc);
#endif

    int row = ROW_Y;
    int num_positions = INPUT_NumSwitchPos(toggleinput);
    if(num_positions < 2)
        num_positions = 2;

    static const char * const tglidx[3] = {"0:", "1:", "2:"};
    labelDesc.style = LABEL_INVERTED;
    for (int i = 0; i < num_positions; i++) {
        GUI_CreateLabelBox(&gui->togglelabel[i], LABEL_X, row, LABEL_W, LABEL_H, SelectedIcon == i ? &labelDesc : &DEFAULT_FONT, NULL, NULL, tglidx[i]);
#ifdef HAS_CHAR_ICONS
        GUI_CreateLabelBox(&gui->toggleicon[i], ICON_X, row, ICON_W, LABEL_H, &DEFAULT_FONT, TGLICO_font_cb,
                           NULL, (void *)(long)Model.pagecfg2.elem[tp->tglidx].extra[i]); 
#else
        struct ImageMap img = TGLICO_GetImage(Model.pagecfg2.elem[tp->tglidx].extra[i]);
        GUI_CreateImageOffset(&gui->toggleicon[i], ICON_X, row, ICON_W, LABEL_H, img.x_off, img.y_off, img.file,
             NULL, //SelectedIcon == 0 ? tglico_reset_cb : tglico_setpos_cb,
             (void *)(long)i);
#endif

        row += ROW_INCREMENT;
    }

    int count = get_toggle_icon_count();
    int rows = (count + NUM_COLS - 1) / NUM_COLS;
    GUI_CreateScrollable(&gui->scrollable, SCROLLABLE_X, SCROLLABLE_Y, LCD_WIDTH - SCROLLABLE_X,
                     SCROLLABLE_H,
                     SCROLL_ROW_H, rows, row_cb, NULL, NULL, (void *)(long)SelectedIcon);
}
Example #23
0
void MIXER_EvalMixers(volatile s32 *raw)
{
    int i;
    s32 orig_value[NUM_CHANNELS];
    //3rd step: apply mixers
    for (i = 0; i < NUM_CHANNELS; i++) {
        orig_value[i] = raw[i + NUM_INPUTS + 1];
    }
    for (i = 0; i < NUM_MIXERS; i++) {
        struct Mixer *mixer = &Model.mixers[i];
        // Linkers are pre-ordred such that we can process them in order
        if (MIXER_SRC(mixer->src) == 0) {
            // Mixer is not defined so we are done
            break;
        }
        //apply_mixer updates mixed[mixer->dest]
        MIXER_ApplyMixer(mixer, raw, &orig_value[mixer->dest]);
    }

}
Example #24
0
unsigned find_dependencies(unsigned ch, unsigned *deps)
{
    unsigned found = 0;
    unsigned i;
    struct Mixer *mixer;
    for (i = 0; i < NUM_SOURCES; i++)
        deps[i] = 0;
    for (mixer = Model.mixers; mixer < Model.mixers + NUM_MIXERS; mixer++) {
        if (MIXER_SRC(mixer->src) && mixer->dest == ch) {
            found = 1;
            if (MIXER_SRC(mixer->src) > NUM_SOURCES && MIXER_SRC(mixer->src) != NUM_SOURCES + 1 + ch) {
                deps[MIXER_SRC(mixer->src) - NUM_SOURCES - 1] = 1;
            } 
            if (MIXER_SRC(mixer->sw) > NUM_SOURCES && MIXER_SRC(mixer->sw) != NUM_SOURCES + 1 + ch) {
                deps[MIXER_SRC(mixer->sw) - NUM_SOURCES - 1] = 1;
            }
        }
    }
    return found;
}
Example #25
0
static const char *dlgts_cb(guiObject_t *obj, int dir, void *data)
{
    (void)obj;
    int idx = (long)data;
    int type = ELEM_TYPE(pc.elem[idx]);
    switch (type) {
        case ELEM_SMALLBOX:
        case ELEM_BIGBOX:
        {
            pc.elem[idx].src = GUI_TextSelectHelper(pc.elem[idx].src, 0, NUM_RTC + NUM_TELEM + NUM_TIMERS + NUM_CHANNELS, dir, 1, 1, NULL);   
            return GetBoxSource(lp.tmp, pc.elem[idx].src);
        }
        case ELEM_BAR:
            pc.elem[idx].src = GUI_TextSelectHelper(pc.elem[idx].src, 0, NUM_CHANNELS, dir, 1, 1, NULL);   
            return INPUT_SourceName(lp.tmp, pc.elem[idx].src ? pc.elem[idx].src + NUM_INPUTS : 0);
        case ELEM_TOGGLE:
        {
            int val = MIXER_SRC(pc.elem[idx].src);
            int newval = GUI_TextSelectHelper(val, 0, NUM_SOURCES, dir, 1, 1, NULL);
            newval = INPUT_GetAbbrevSource(val, newval, dir);
            if (val != newval) {
                val = newval;
                pc.elem[idx].src = val;
            }
            return INPUT_SourceNameAbbrevSwitch(lp.tmp, pc.elem[idx].src);
        }
        case ELEM_HTRIM:
        case ELEM_VTRIM:
            pc.elem[idx].src = GUI_TextSelectHelper(pc.elem[idx].src, 0, NUM_TRIMS, dir, 1, 1, NULL);
            if (pc.elem[idx].src == 0)
                return _tr("None");
            sprintf(lp.tmp, "%s%d", _tr("Trim"),pc.elem[idx].src);
            return lp.tmp;
    }
    return "";
}
Example #26
0
void TIMER_Update()
{
    unsigned i;
    unsigned chan_val = 0;
    u32 t = CLOCK_getms();
    if (PROTOCOL_WaitingForSafe())
        return;
    if( Transmitter.power_alarm > 0 )
        TIMER_Power();
    for (i = 0; i < NUM_TIMERS; i++) {
        if (Model.timer[i].src) {
            s16 val;
            if (MIXER_SRC(Model.timer[i].src) <= NUM_INPUTS) {
                volatile s16 *raw = MIXER_GetInputs();
                val = raw[MIXER_SRC(Model.timer[i].src)];
            } else {
                val = MIXER_GetChannel(Model.timer[i].src - NUM_INPUTS - 1, APPLY_SAFETY);
            }
            if (MIXER_SRC_IS_INV(Model.timer[i].src))
                val = -val;
            if (Model.timer[i].type == TIMER_STOPWATCH_PROP
                || Model.timer[i].type == TIMER_COUNTDOWN_PROP)
            {
               chan_val = RANGE_TO_PCT(abs(val));
               if (chan_val > 100)
                   chan_val = 100;
            } else {
                unsigned new_state = (val - CHAN_MIN_VALUE > (CHAN_MAX_VALUE - CHAN_MIN_VALUE) / 20) ? 1 : 0;
                if (new_state != timer_state[i]) {
                    if (new_state)
                        last_time[i] = t;
                    timer_state[i] = new_state;
                }
            }
        }
        if (timer_state[i]) {
            s32 delta = t - last_time[i];
            if (Model.timer[i].type == TIMER_STOPWATCH_PROP || Model.timer[i].type == TIMER_COUNTDOWN_PROP) {
                delta = delta * chan_val / 100;
            }
            if (Model.timer[i].type == TIMER_PERMANENT) {
                timer_val[i] += delta;
                if( timer_val[i] >= 359999900) // Reset when 99h59mn59sec
                    timer_val[i] = 0 ;
                Model.timer[i].val = timer_val[i];
            } else if (Model.timer[i].type == TIMER_STOPWATCH || Model.timer[i].type == TIMER_STOPWATCH_PROP) {
                timer_val[i] += delta;
            } else {
                s32 warn_time;
                // start to beep  for each prealert_interval at the last prealert_time(seconds)
                if (Transmitter.countdown_timer_settings.prealert_time != 0 &&
                    Transmitter.countdown_timer_settings.prealert_interval != 0 &&
                    timer_val[i] > Transmitter.countdown_timer_settings.prealert_interval &&
                    timer_val[i] < (s32)Transmitter.countdown_timer_settings.prealert_time + 1000) { // give extra 1seconds
                    warn_time = ((timer_val[i] / Transmitter.countdown_timer_settings.prealert_interval)
                            * Transmitter.countdown_timer_settings.prealert_interval);
                    if (timer_val[i] > warn_time && (timer_val[i] - delta) <= warn_time) {
                        MUSIC_Play(MUSIC_TIMER_WARNING);
                    }
                }
                // Beep once for each timeup_interval past 0
                if (timer_val[i] < 0 && Transmitter.countdown_timer_settings.timeup_interval != 0) {
                    warn_time = ((timer_val[i] - Transmitter.countdown_timer_settings.timeup_interval) / Transmitter.countdown_timer_settings.timeup_interval)
                            * Transmitter.countdown_timer_settings.timeup_interval;
                    if (timer_val[i] > warn_time && (timer_val[i] - delta) <= warn_time) {
                        MUSIC_Play(MUSIC_ALARM1 + i);
                    }
                }
                if (timer_val[i] >= 0 && timer_val[i] < delta) {
                    MUSIC_Play(MUSIC_ALARM1 + i);
                }
                timer_val[i] -= delta;
            }
            last_time[i] = t;
        } 
        if (Model.timer[i].resetsrc) {
            s16 val;
            if (MIXER_SRC(Model.timer[i].resetsrc) <= NUM_INPUTS) {
                volatile s16 *raw = MIXER_GetInputs();
                val = raw[MIXER_SRC(Model.timer[i].resetsrc)];
            } else {
                val = MIXER_GetChannel(Model.timer[i].resetsrc - NUM_INPUTS - 1, APPLY_SAFETY);
            }
            if (MIXER_SRC_IS_INV(Model.timer[i].resetsrc))
                val = -val;
            if (val - CHAN_MIN_VALUE > (CHAN_MAX_VALUE - CHAN_MIN_VALUE) / 20) {
                TIMER_Reset(i);
            }
        }
    }
}
Example #27
0
static int expo_row_cb(int absrow, int relrow, int y, void *data)
{
    const char *label = NULL;
    int underline = 0;
    void * label_cb = NULL;
    void *tgl = NULL;
    void *value = NULL;
    data = NULL;
    void *but_tgl = NULL;
    void *but_txt = NULL;
    void *but_data = NULL;
    int disable = 0;

    int x = 0;
    int w = LEFT_VIEW_WIDTH;
    switch(absrow) {
        case COMMON_SRC:
            label = _tr("Src");
            tgl = sourceselect_cb; value = set_source_cb; data = &mp->cur_mixer->src;
            break;
        case COMMON_CURVE:
            label = _tr("High-Rate");
            tgl = curveselect_cb; value = set_curvename_cb; data = &mp->mixer[0];
            break;
        case COMMON_SCALE:
            label = (void *)0; label_cb = scalestring_cb;
            value = set_number100_cb; data = &mp->mixer[0].scalar;
            break;
        case EXPO_SWITCH1:
            label = _tr("Switch1"); underline = 1;
            tgl = sourceselect_cb; value = set_drsource_cb; data = &mp->mixer[1].sw;
            break;
        case EXPO_LINK1:
            but_tgl = toggle_link_cb; but_txt = show_rate_cb; but_data = (void *)0;
            if(! MIXER_SRC(mp->mixer[1].sw))
                disable = 1;
            break;
        case EXPO_CURVE1:
            tgl = curveselect_cb; value = set_curvename_cb; data = &mp->mixer[1];
            if(! MIXER_SRC(mp->mixer[1].sw) || mp->link_curves & 0x01)
                disable = 1;
            break;
        case EXPO_SCALE1:
            label = (void *)1; label_cb = scalestring_cb;
            value = set_number100_cb; data = &mp->mixer[1].scalar;
            if(! MIXER_SRC(mp->mixer[1].sw))
                disable = 1;
            break;
        case EXPO_SWITCH2:
            label = _tr("Switch2"); underline = 1;
            tgl = sourceselect_cb; value = set_drsource_cb; data = &mp->mixer[2].sw;
            break;
        case EXPO_LINK2:
            but_tgl = toggle_link_cb; but_txt = show_rate_cb; but_data = (void *)1;
            if(! MIXER_SRC(mp->mixer[2].sw))
                disable = 1;
            break;
        case EXPO_CURVE2:
            tgl = curveselect_cb; value = set_curvename_cb; data = &mp->mixer[2];
            if(! MIXER_SRC(mp->mixer[2].sw) || mp->link_curves & 0x02)
                disable = 1;
            break;
        case EXPO_SCALE2:
            label = (void *)2; label_cb = scalestring_cb;
            value = set_number100_cb; data = &mp->mixer[2].scalar;
            if(! MIXER_SRC(mp->mixer[2].sw))
                disable = 1;
            break;
    }
    if(label || label_cb) {
        labelDesc.style = LABEL_LEFTCENTER;
        GUI_CreateLabelBox(&gui->label[relrow], x, y, w, ITEM_HEIGHT,
            &labelDesc, label_cb, NULL, label);
        if(underline)
            GUI_CreateRect(&gui->rect1, x, y, LEFT_VIEW_WIDTH, 1, &labelDesc);
        y += ITEM_HEIGHT + 1;
    }
    labelDesc.style = LABEL_CENTER;
    if(but_tgl) {
        GUI_CreateButtonPlateText(&gui->value[relrow].but, x, y,
            w, ITEM_HEIGHT, &labelDesc, but_txt, 0xffff, but_tgl, but_data);
        if(disable) {
            GUI_ButtonEnable((guiObject_t *)&gui->value[relrow].but, 0);
        }
    } else {
        GUI_CreateTextSelectPlate(&gui->value[relrow].ts, x, y,
            w, ITEM_HEIGHT, &labelDesc, tgl, value, data);
        if(disable) {
            GUI_TextSelectEnable(&gui->value[relrow].ts, 0);
        }
    }
    return 1;
}
Example #28
0
void PAGE_MainEvent()
{
    int i;
    if (PAGE_GetModal()) {
#if HAS_TELEMETRY
        if(pagemem.modal_page == 2) {
            PAGE_TelemtestEvent();
        }
#endif
        return;
    }
    volatile s32 *raw = MIXER_GetInputs();
    for(i = 0; i < NUM_ELEMS; i++) {
        if (! ELEM_USED(pc->elem[i]))
            break;
        if (! OBJ_IS_USED(&gui->elem[i]))
            continue;
        int src = pc->elem[i].src;
        int type = ELEM_TYPE(pc->elem[i]);
        switch(type) {
            case ELEM_VTRIM:
            case ELEM_HTRIM:
            {
                int value = *(MIXER_GetTrim(src-1));
                if (mp->elem[i] != value) {
                    mp->elem[i] = value;
                    GUI_Redraw(&gui->elem[i].bar);
                }
                break;
            }
            case ELEM_SMALLBOX:
            case ELEM_BIGBOX:
            {
                s32 val = get_boxval(src);
#if HAS_RTC
                if (src <= NUM_RTC) {
                    if (mp->elem[i] != val) {
                        mp->elem[i] = val;
                        GUI_Redraw(&gui->elem[i].box);
                    }
                } else
#endif
                if (src - NUM_RTC <= NUM_TIMERS) {
                    //Timer
                    if ((val >= 0 && mp->elem[i] < 0) || (val < 0 && mp->elem[i] >= 0)) {
                        GUI_SetLabelDesc(&gui->elem[i].box, get_box_font(type == ELEM_BIGBOX ? 0 : 2, val < 0));
                        mp->elem[i] = val;
                        GUI_Redraw(&gui->elem[i].box);
                    } else if (mp->elem[i] / 1000 != val /1000) {
                        mp->elem[i] = val;
                        GUI_Redraw(&gui->elem[i].box);
                    }
                } else if (src - NUM_RTC - NUM_TIMERS <= NUM_TELEM) {
                    //Telem
                    int alarm = TELEMETRY_HasAlarm(src - NUM_RTC - NUM_TIMERS);
                    if (alarm || ! TELEMETRY_IsUpdated(0xff)) {
                        GUI_SetLabelDesc(&gui->elem[i].box, get_box_font(type == ELEM_BIGBOX ? 0 : 2, 1));
                    } else if(mp->elem[i] != val) {
                        GUI_SetLabelDesc(&gui->elem[i].box, get_box_font(type == ELEM_BIGBOX ? 0 : 2, 0));
                        mp->elem[i] = val;
                        GUI_Redraw(&gui->elem[i].box);
                    }
                } else if (mp->elem[i] != val) {
                    //Source
                    mp->elem[i] = val;
                    GUI_Redraw(&gui->elem[i].box);
                }
                break;
            }
            case ELEM_BAR:
            {
                s32 chan = MIXER_GetChannel(src-1, APPLY_SAFETY);
                if (mp->elem[i] != chan) {
                    mp->elem[i] = chan;
                    GUI_Redraw(&gui->elem[i].bar);
                }
                break;
            }
            case ELEM_TOGGLE:
            {
                src = MIXER_SRC(src);
                int idx = -1;
                if(src) {
                    if (src > INP_HAS_CALIBRATION && src < INP_LAST) {
                        //switch
                        for (int j = 0; j < 3; j++) {
                            // Assume switch 0/1/2 are in order
                            if(ELEM_ICO(pc->elem[i], j) && raw[src+j] > 0) {
                                idx = ELEM_ICO(pc->elem[i], j);
                                break;
                            }
                        }
                    } else {
                        //Non switch
                        int sw = raw[src] > 0 ? 1 : 0;
                        if (ELEM_ICO(pc->elem[i], sw)) {
                            idx = ELEM_ICO(pc->elem[i], sw);
                        }
                    }
                }
                if (idx != -1) {
#ifdef HAS_CHAR_ICONS
                    gui->elem[i].box.cb_data = (void *)(long)idx;
#else
                    struct ImageMap img;
                    img = TGLICO_GetImage(idx);
                    GUI_ChangeImage(&gui->elem[i].img, img.file, img.x_off, img.y_off);
#endif
                    GUI_SetHidden((guiObject_t *)&gui->elem[i], 0);
                } else {
                    GUI_SetHidden((guiObject_t *)&gui->elem[i], 1);
                }
            }
            break;
            case ELEM_BATTERY:
                _check_voltage(&gui->elem[i].box);
                break;
        }
    }
    if(HAS_TOUCH)  //FIXME: Hack to let 320x240 GUI continue to work
        _check_voltage(NULL);
#if HAS_RTC
    if(Display.flags & SHOW_TIME) {
        u32 time = RTC_GetValue() / 60;
        if(mp->time != time) {
            mp->time = time;
            GUI_Redraw(&gui->time);
        }
    }
#endif
}
Example #29
0
void MIXER_ApplyMixer(struct Mixer *mixer, volatile s32 *raw, s32 *orig_value)
{
    s32 value;
    if (! MIXER_SRC(mixer->src))
        return;
    if (! switch_is_on(mixer->sw, raw)) {
        // Switch is off, so this mixer is not active
        return;
    }
    //1st: Get source value with trim
    value = raw[MIXER_SRC(mixer->src)];
    //Invert if necessary
    if (MIXER_SRC_IS_INV(mixer->src))
        value = - value;

    //2nd: apply curve
    value = CURVE_Evaluate(value, &mixer->curve);

    //3rd: apply scalar and offset
    value = value * mixer->scalar / 100 + PCT_TO_RANGE(mixer->offset);

    //4th: multiplex result
    switch(MIXER_MUX(mixer)) {
    case MUX_REPLACE:
        break;
    case MUX_MULTIPLY:
        value = raw[mixer->dest + NUM_INPUTS + 1] * value / CHAN_MAX_VALUE;
        break;
    case MUX_ADD:
        value = raw[mixer->dest + NUM_INPUTS + 1] + value;
        break;
    case MUX_MAX:
        value = raw[mixer->dest + NUM_INPUTS + 1] > value
                  ? raw[mixer->dest + NUM_INPUTS + 1]
                  : value;
        break;
    case MUX_MIN:
        value = raw[mixer->dest + NUM_INPUTS + 1] < value
                  ? raw[mixer->dest + NUM_INPUTS + 1]
                  : value;
        break;
    case MUX_DELAY:
        {
            //value initially represents 20ths of seconds to cover 60-degrees
            //convert value to represent #msecs to cover 60-degrees (zero->full)
            if (value == 0 || orig_value == NULL) {
                value = raw[mixer->dest + NUM_INPUTS + 1];
                break;
            }
            value = abs(RANGE_TO_PCT(value)) * 50;
            //rate represents the maximum travel per iteration (once per MEDIUM_PRIORITY_MSEC)
            s32 rate = CHAN_MAX_VALUE * MEDIUM_PRIORITY_MSEC / value;

            value = raw[mixer->dest + NUM_INPUTS + 1];
            if (value - *orig_value > rate)
                value = *orig_value + rate;
            else if(value - *orig_value < -rate)
                value = *orig_value - rate;
        }
    case MUX_LAST: break;
    }

    //5th: apply trim
    if (MIXER_APPLY_TRIM(mixer))
        value = value + (MIXER_SRC_IS_INV(mixer->src) ? -1 : 1) * get_trim(MIXER_SRC(mixer->src));

    //Ensure we don't overflow
    if (value > INT16_MAX)
        value = INT16_MAX;
    else if (value < INT16_MIN)
        value = INT16_MIN;

    raw[mixer->dest + NUM_INPUTS + 1] = value;
}