185 lines
6.8 KiB
C
185 lines
6.8 KiB
C
/*
|
|
* Copyright (C) 2021-2025 Roger Clark, VK3KYY / G4KYF
|
|
* Daniel Caujolle-Bert, F1RMB
|
|
*
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
|
|
* in the documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* 4. Use of this source code or binary releases for commercial purposes is strictly forbidden. This includes, without limitation,
|
|
* incorporation in a commercial product or incorporation into a product or project which allows commercial use.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "functions/rxPowerSaving.h"
|
|
#include "functions/trx.h"
|
|
#include "functions/ticks.h"
|
|
#include <interfaces/clockManager.h>
|
|
#include "usb/usb_com.h"
|
|
|
|
|
|
#define LOW_SPEED_CLOCK_ECO_THRESHOLD 2
|
|
static ecoPhase_t rxPowerSavingState = ECOPHASE_POWERSAVE_INACTIVE;
|
|
static ticksTimer_t ecoPhaseTimer = { 0, 0 };
|
|
volatile static int powerSavingLevel = 1;
|
|
static bool hrc6000IsPoweredOff = false;
|
|
|
|
|
|
|
|
bool rxPowerSavingIsRxOn(void)
|
|
{
|
|
return (rxPowerSavingState != ECOPHASE_POWERSAVE_ACTIVE___RX_IS_OFF);
|
|
}
|
|
|
|
void rxPowerSavingSetLevel(int newLevel)
|
|
{
|
|
if (powerSavingLevel != newLevel)
|
|
{
|
|
if (newLevel == 0)
|
|
{
|
|
rxPowerSavingSetState(ECOPHASE_POWERSAVE_INACTIVE);
|
|
}
|
|
|
|
powerSavingLevel = newLevel;
|
|
}
|
|
}
|
|
|
|
int rxPowerSavingGetLevel(void)
|
|
{
|
|
return powerSavingLevel;
|
|
}
|
|
|
|
static void resumeBeepAndC6000Tasks(void)
|
|
{
|
|
vTaskResume(hrc6000Task.Handle);
|
|
hrc6000Task.Running = true;
|
|
hrc6000Task.AliveCount = TASK_FLAGGED_ALIVE;
|
|
vTaskResume(beepTask.Handle);
|
|
beepTask.Running = true;
|
|
beepTask.AliveCount = TASK_FLAGGED_ALIVE;
|
|
//HRC6000FlushMusic(); //G4EML Needed after restarting the HRC6000 Task to prevent missing DMR audio;
|
|
}
|
|
|
|
static void suspendBeepAndC6000Tasks(void)
|
|
{
|
|
vTaskSuspend(beepTask.Handle);
|
|
beepTask.Running = false;
|
|
vTaskSuspend(hrc6000Task.Handle);
|
|
hrc6000Task.Running = false;
|
|
}
|
|
|
|
void rxPowerSavingSetState(ecoPhase_t newState)
|
|
{
|
|
if (rxPowerSavingState != newState)
|
|
{
|
|
if (rxPowerSavingState == ECOPHASE_POWERSAVE_ACTIVE___RX_IS_OFF)
|
|
{
|
|
hrc6000IsPoweredOff = trxPowerUpDownRxAndC6000(true, hrc6000IsPoweredOff, false);
|
|
}
|
|
|
|
rxPowerSavingState = newState;
|
|
|
|
// Avoid to instantly jump to power saving mode
|
|
if (rxPowerSavingState == ECOPHASE_POWERSAVE_INACTIVE)
|
|
{
|
|
if (powerSavingLevel >= LOW_SPEED_CLOCK_ECO_THRESHOLD)
|
|
{
|
|
clockManagerSetRunMode(kAPP_PowerModeRun, CLOCK_MANAGER_SPEED_RUN);
|
|
resumeBeepAndC6000Tasks();
|
|
}
|
|
|
|
ticksTimerStart(&ecoPhaseTimer, ((12 - (MIN(powerSavingLevel, 4) * 2)) * 1000));
|
|
}
|
|
}
|
|
}
|
|
|
|
void rxPowerSavingTick(uiEvent_t *ev, bool hasSignal)
|
|
{
|
|
if ((settingsUsbMode != USB_MODE_HOTSPOT) || (rxPowerSavingState != ECOPHASE_POWERSAVE_INACTIVE))
|
|
{
|
|
if (USB_DeviceIsResetting() || isCompressingAMBE || hasSignal || trxTransmissionEnabled || trxIsTransmitting ||
|
|
(menuSystemGetCurrentMenuNumber() == UI_TX_SCREEN) || (menuSystemGetCurrentMenuNumber() == UI_CPS) ||
|
|
(uiDataGlobal.Scan.active && uiDataGlobal.Scan.scanType == SCAN_TYPE_NORMAL_STEP) || ev->hasEvent)
|
|
{
|
|
if (rxPowerSavingState != ECOPHASE_POWERSAVE_INACTIVE)
|
|
{
|
|
if (rxPowerSavingState == ECOPHASE_POWERSAVE_ACTIVE___RX_IS_OFF)
|
|
{
|
|
hrc6000IsPoweredOff = trxPowerUpDownRxAndC6000(true, hrc6000IsPoweredOff, false);// Power up AT1846S, C6000 and preamp
|
|
}
|
|
|
|
if (powerSavingLevel >= LOW_SPEED_CLOCK_ECO_THRESHOLD)
|
|
{
|
|
clockManagerSetRunMode(kAPP_PowerModeRun, CLOCK_MANAGER_SPEED_RUN);
|
|
resumeBeepAndC6000Tasks();
|
|
}
|
|
|
|
rxPowerSavingState = ECOPHASE_POWERSAVE_INACTIVE;
|
|
}
|
|
|
|
// Postpone entering the ECOPHASE_POWERSAVE_INACTIVE
|
|
ticksTimerStart(&ecoPhaseTimer, ((12 - (MIN(powerSavingLevel, 4) * 2)) * 1000));
|
|
}
|
|
else
|
|
{
|
|
if (ticksTimerHasExpired(&ecoPhaseTimer) &&
|
|
((powerSavingLevel > 0) && (codeplugChannelGetFlag(currentChannelData, CHANNEL_FLAG_NO_ECO) == 0)) &&
|
|
(melody_play == NULL) && (voicePromptsIsPlaying() == false)
|
|
#if defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
|
|
&& (voxIsEnabled() == false)
|
|
#endif
|
|
)
|
|
{
|
|
int rxDuration = (130 - (10 * powerSavingLevel));
|
|
|
|
switch(rxPowerSavingState)
|
|
{
|
|
case ECOPHASE_POWERSAVE_INACTIVE:// wait before shutting down
|
|
|
|
ticksTimerStart(&ecoPhaseTimer, ((12 - (MIN(powerSavingLevel, 4) * 2)) * 1000));
|
|
rxPowerSavingState = ECOPHASE_POWERSAVE_WAIT_START;
|
|
break;
|
|
|
|
case ECOPHASE_POWERSAVE_WAIT_START:
|
|
if ((powerSavingLevel >= LOW_SPEED_CLOCK_ECO_THRESHOLD) && (SETTINGS_GPS_MODE_GET(nonVolatileSettings) <= GPS_MODE_OFF))
|
|
{
|
|
suspendBeepAndC6000Tasks();
|
|
clockManagerSetRunMode(kAPP_PowerModeRun, CLOCK_MANAGER_RUN_ECO_POWER_MODE);
|
|
}
|
|
|
|
rxPowerSavingState = ECOPHASE_POWERSAVE_ACTIVE___RX_IS_ON;
|
|
// drop through
|
|
|
|
case ECOPHASE_POWERSAVE_ACTIVE___RX_IS_ON:
|
|
hrc6000IsPoweredOff = trxPowerUpDownRxAndC6000(false, (powerSavingLevel > 1), false);// Power down AT1846S, C6000 and preamp
|
|
ticksTimerStart(&ecoPhaseTimer, (rxDuration * (1 << (powerSavingLevel - 1))));
|
|
rxPowerSavingState = ECOPHASE_POWERSAVE_ACTIVE___RX_IS_OFF;
|
|
break;
|
|
|
|
case ECOPHASE_POWERSAVE_ACTIVE___RX_IS_OFF:
|
|
//USB_DEBUG_printf("ECOPHASE_POWERSAVE_ACTIVE___RX_IS_ON\n");
|
|
hrc6000IsPoweredOff = trxPowerUpDownRxAndC6000(true, hrc6000IsPoweredOff, false);// Power up AT1846S, C6000 and preamps
|
|
ticksTimerStart(&ecoPhaseTimer, (rxDuration * 1));
|
|
trxPostponeReadRSSIAndNoise(0); // Give it a bit of time, after powering up, before checking the RSSI and Noise values
|
|
rxPowerSavingState = ECOPHASE_POWERSAVE_ACTIVE___RX_IS_ON;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|