Files
edgetx-gx12/radio/src/mixes.cpp
T

160 lines
3.7 KiB
C++

/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "mixes.h"
#include "tasks/mixer_task.h"
#include "hal/adc_driver.h"
#include "opentx.h"
static uint8_t _nb_mix_lines;
MixData* mixAddress(uint8_t idx) { return &g_model.mixData[idx]; }
uint8_t getMixCount() { return _nb_mix_lines; }
void insertMix(uint8_t idx, uint8_t channel)
{
mixerTaskStop();
MixData * mix = mixAddress(idx);
memmove(mix + 1, mix, (MAX_MIXERS - (idx + 1)) * sizeof(MixData));
memclear(mix, sizeof(MixData));
mix->destCh = channel;
mix->srcRaw = channel + 1;
if (!isSourceAvailable(mix->srcRaw)) {
if (channel >= adcGetMaxInputs(ADC_INPUT_MAIN)) {
mix->srcRaw = MIXSRC_FIRST_STICK + channel;
} else {
mix->srcRaw = MIXSRC_FIRST_STICK + inputMappingChannelOrder(channel);
}
while (!isSourceAvailable(mix->srcRaw)) {
mix->srcRaw += 1;
}
}
mix->weight = 100;
mixerTaskStart();
_nb_mix_lines += 1;
storageDirty(EE_MODEL);
}
void deleteMix(uint8_t idx)
{
mixerTaskStop();
MixData * mix = mixAddress(idx);
memmove(mix, mix + 1, (MAX_MIXERS - (idx + 1)) * sizeof(MixData));
memclear(&g_model.mixData[MAX_MIXERS - 1], sizeof(MixData));
mixerTaskStart();
_nb_mix_lines -= 1;
storageDirty(EE_MODEL);
}
void copyMix(uint8_t src, uint8_t dst, uint8_t channel)
{
mixerTaskStop();
MixData sourceMix;
memcpy(&sourceMix, mixAddress(src), sizeof(MixData));
MixData* mix = mixAddress(dst);
size_t trailingMixes = MAX_MIXERS - (dst + 1);
memmove(mix + 1, mix, trailingMixes * sizeof(MixData));
memcpy(mix, &sourceMix, sizeof(MixData));
mix->destCh = channel;
mixerTaskStart();
_nb_mix_lines += 1;
storageDirty(EE_MODEL);
}
// Move the mixer line at 'idx' up or down
// by one position and return the new index.
uint8_t moveMix(uint8_t idx, bool up)
{
MixData * x, * y;
int8_t tgt_idx = (up ? idx-1 : idx+1);
x = mixAddress(idx);
if (tgt_idx < 0) {
if (x->destCh > 0) {
x->destCh--;
storageDirty(EE_MODEL);
}
return idx;
}
if (tgt_idx == MAX_MIXERS) {
if (x->destCh < MAX_OUTPUT_CHANNELS - 1) {
x->destCh++;
storageDirty(EE_MODEL);
}
return idx;
}
y = mixAddress(tgt_idx);
uint8_t destCh = x->destCh;
// If current target is empty or
// assigned to a different channel:
//
// TODO: check what happens with the mixer
// when channel is changed on-the-fly
//
if(!y->srcRaw || destCh != y->destCh) {
if (up) {
if (destCh > 0) {
x->destCh--;
storageDirty(EE_MODEL);
}
}
else {
if (destCh < MAX_OUTPUT_CHANNELS - 1) {
x->destCh++;
storageDirty(EE_MODEL);
}
}
return idx;
}
mixerTaskStop();
memswap(x, y, sizeof(MixData));
mixerTaskStart();
storageDirty(EE_MODEL);
return tgt_idx;
}
static uint8_t _countMixLines()
{
// search for first blank
uint8_t i = 0;
do {
if (is_memclear(mixAddress(i), sizeof(MixData))) break;
} while (++i < MAX_MIXERS);
return i;
}
void updateMixCount()
{
_nb_mix_lines = _countMixLines();
}