189 lines
4.1 KiB
C++
189 lines
4.1 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 "debug.h"
|
|
#include "edgetx.h"
|
|
#include "os/sleep.h"
|
|
#include "os/task.h"
|
|
#include "os/time.h"
|
|
#include "os/timer.h"
|
|
#include "timers_driver.h"
|
|
#include "hal/abnormal_reboot.h"
|
|
#include "hal/watchdog_driver.h"
|
|
#include "pdm_wav_recorder.h"
|
|
|
|
#include "tasks.h"
|
|
#include "tasks/mixer_task.h"
|
|
|
|
#if defined(COLORLCD)
|
|
#include "startup_shutdown.h"
|
|
#endif
|
|
|
|
task_handle_t menusTaskId;
|
|
TASK_DEFINE_STACK(menusStack, MENUS_STACK_SIZE);
|
|
|
|
#if defined(AUDIO)
|
|
task_handle_t audioTaskId;
|
|
TASK_DEFINE_STACK(audioStack, AUDIO_STACK_SIZE);
|
|
#endif
|
|
|
|
mutex_handle_t audioMutex;
|
|
|
|
#define MENU_TASK_PERIOD (50) // 50ms
|
|
|
|
#if defined(COLORLCD) && defined(CLI)
|
|
bool perMainEnabled = true;
|
|
#endif
|
|
|
|
static void menusTask()
|
|
{
|
|
edgeTxInit();
|
|
|
|
mixerTaskInit();
|
|
|
|
#if defined(COLORLCD) && defined(RTC_BACKUP_RAM)
|
|
if (UNEXPECTED_SHUTDOWN())
|
|
drawFatalErrorScreen(STR_EMERGENCY_MODE);
|
|
#endif
|
|
|
|
#if defined(PWR_BUTTON_PRESS)
|
|
while (task_running()) {
|
|
uint32_t pwr_check = pwrCheck();
|
|
if (pwr_check == e_power_off) {
|
|
break;
|
|
} else if (pwr_check == e_power_press) {
|
|
sleep_ms(MENU_TASK_PERIOD);
|
|
continue;
|
|
}
|
|
#else
|
|
while (pwrCheck() != e_power_off) {
|
|
#endif
|
|
time_point_t next_tick = time_point_now();
|
|
DEBUG_TIMER_START(debugTimerPerMain);
|
|
#if defined(COLORLCD) && defined(CLI)
|
|
if (perMainEnabled) {
|
|
perMain();
|
|
}
|
|
#else
|
|
perMain();
|
|
#endif
|
|
DEBUG_TIMER_STOP(debugTimerPerMain);
|
|
|
|
sleep_until(&next_tick, MENU_TASK_PERIOD);
|
|
resetForcePowerOffRequest();
|
|
}
|
|
|
|
#if defined(PCBX9E)
|
|
toplcdOff();
|
|
#endif
|
|
|
|
drawSleepBitmap();
|
|
edgeTxClose();
|
|
boardOff();
|
|
}
|
|
|
|
static void audioTask()
|
|
{
|
|
while (!audioQueue.started()) {
|
|
sleep_ms(1);
|
|
}
|
|
|
|
#if defined(PCBX12S) || defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
|
|
// The audio amp needs ~2s to start
|
|
sleep_ms(1000); // 1s
|
|
#endif
|
|
|
|
time_point_t next_tick = time_point_now();
|
|
while (task_running()) {
|
|
DEBUG_TIMER_SAMPLE(debugTimerAudioIterval);
|
|
DEBUG_TIMER_START(debugTimerAudioDuration);
|
|
audioQueue.wakeup();
|
|
#if defined(PDM_CLOCK)
|
|
// Drive microphone recording (if any) at the audio-task cadence.
|
|
// Much shorter than the UI tick interval, so the PDM ring buffer
|
|
// never fills enough to trigger skip-ahead / sample drops.
|
|
PdmWavRecorder::audioTick();
|
|
#endif
|
|
DEBUG_TIMER_STOP(debugTimerAudioDuration);
|
|
sleep_until(&next_tick, 4);
|
|
}
|
|
}
|
|
|
|
static timer_handle_t _timer10ms = TIMER_INITIALIZER;
|
|
|
|
static void _timer_10ms_cb(timer_handle_t* h)
|
|
{
|
|
per10ms();
|
|
}
|
|
|
|
static void timer10msStart()
|
|
{
|
|
if (!timer_is_created(&_timer10ms)) {
|
|
timer_create(&_timer10ms, _timer_10ms_cb, "10ms", 10, true);
|
|
}
|
|
|
|
timer_start(&_timer10ms);
|
|
}
|
|
|
|
#if defined(COLORLCD) && defined(SIMU)
|
|
static timer_handle_t _timer1ms = TIMER_INITIALIZER;
|
|
|
|
static void _timer_1ms_cb(timer_handle_t* h)
|
|
{
|
|
// Increment LVGL animation timer
|
|
lv_tick_inc(1);
|
|
}
|
|
|
|
static void timer1msStart()
|
|
{
|
|
if (!timer_is_created(&_timer1ms)) {
|
|
timer_create(&_timer1ms, _timer_1ms_cb, "1ms", 1, true);
|
|
}
|
|
|
|
timer_start(&_timer1ms);
|
|
}
|
|
#endif
|
|
|
|
void tasksStart()
|
|
{
|
|
mutex_create(&audioMutex);
|
|
|
|
#if defined(CLI) && !defined(SIMU)
|
|
cliStart();
|
|
#endif
|
|
|
|
#if defined(COLORLCD) && defined(SIMU)
|
|
timer1msStart();
|
|
#endif
|
|
|
|
timer10msStart();
|
|
|
|
task_create(&menusTaskId, menusTask, "menus", menusStack, MENUS_STACK_SIZE,
|
|
MENUS_TASK_PRIO);
|
|
|
|
#if defined(AUDIO)
|
|
task_create(&audioTaskId, audioTask, "audio", audioStack, AUDIO_STACK_SIZE,
|
|
AUDIO_TASK_PRIO);
|
|
#endif
|
|
|
|
RTOS_START();
|
|
}
|