feat(radio): OS compatibility layer (#5840)
This commit is contained in:
@@ -484,9 +484,16 @@ if(NATIVE_BUILD)
|
||||
${RADIOLIB_NATIVE_SRC}
|
||||
)
|
||||
|
||||
# Add -DSIMU here PUBLIC, so it can be imported by other targets
|
||||
# Add SIMU and POSIX_THREAD here PUBLIC, so it can be imported by other targets
|
||||
# via INTERFACE_COMPILE_OPTIONS
|
||||
target_compile_options(radiolib_native PUBLIC -DSIMU)
|
||||
target_compile_options(radiolib_native PUBLIC -DSIMU -DPOSIX_THREADS)
|
||||
target_sources(radiolib_native PUBLIC
|
||||
os/async_native.cpp
|
||||
os/sleep_native.cpp
|
||||
os/task_pthread.cpp
|
||||
os/time_native.cpp
|
||||
os/timer_pthread.cpp
|
||||
)
|
||||
add_dependencies(radiolib_native ${RADIO_DEPENDENCIES})
|
||||
set_property(TARGET radiolib_native PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -554,13 +561,23 @@ if(BOOTLOADER)
|
||||
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} bootloader)
|
||||
endif()
|
||||
|
||||
add_definitions(-DFREE_RTOS)
|
||||
|
||||
add_executable(firmware ${SRC})
|
||||
link_libraries(firmware -lstdc++)
|
||||
add_dependencies(firmware ${RADIO_DEPENDENCIES})
|
||||
set_target_properties(firmware PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
target_compile_definitions(board PUBLIC FREE_RTOS)
|
||||
target_compile_definitions(board_lib PUBLIC FREE_RTOS)
|
||||
target_compile_definitions(firmware PUBLIC FREE_RTOS)
|
||||
|
||||
target_sources(firmware PUBLIC
|
||||
os/async_freertos.cpp
|
||||
os/sleep_freertos.cpp
|
||||
os/task_freertos.cpp
|
||||
os/time_freertos.cpp
|
||||
os/timer_freertos.cpp
|
||||
)
|
||||
|
||||
if(DEBUG)
|
||||
target_compile_definitions(board PRIVATE -DDEBUG)
|
||||
target_compile_definitions(firmware PRIVATE -DDEBUG)
|
||||
|
||||
+16
-35
@@ -21,6 +21,9 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "os/sleep.h"
|
||||
#include "os/task.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "strhelpers.h"
|
||||
#include "switches.h"
|
||||
@@ -32,7 +35,7 @@
|
||||
#include "model_audio.h"
|
||||
#include "hal/audio_driver.h"
|
||||
|
||||
extern RTOS_MUTEX_HANDLE audioMutex;
|
||||
extern mutex_handle_t audioMutex;
|
||||
|
||||
// Only first quadrant values - other quadrants calulated taking advantage of symmetry in sine wave.
|
||||
const int16_t sineValues[] =
|
||||
@@ -373,28 +376,6 @@ AudioQueue::AudioQueue()
|
||||
|
||||
#define CODEC_ID_PCM_S16LE 1
|
||||
|
||||
#if !defined(SIMU)
|
||||
void audioTask(void * pdata)
|
||||
{
|
||||
while (!audioQueue.started()) {
|
||||
RTOS_WAIT_TICKS(1);
|
||||
}
|
||||
|
||||
#if defined(PCBX12S) || defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
|
||||
// The audio amp needs ~2s to start
|
||||
RTOS_WAIT_MS(1000); // 1s
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
DEBUG_TIMER_SAMPLE(debugTimerAudioIterval);
|
||||
DEBUG_TIMER_START(debugTimerAudioDuration);
|
||||
audioQueue.wakeup();
|
||||
DEBUG_TIMER_STOP(debugTimerAudioDuration);
|
||||
RTOS_WAIT_MS(4); // ???
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(__SSAT)
|
||||
#define _sat_s16(x) ((int16_t)limit<int32_t>(INT16_MIN, (x), INT16_MAX))
|
||||
#else
|
||||
@@ -638,9 +619,9 @@ void AudioQueue::wakeup()
|
||||
|
||||
// mix the normal context (tones and wavs)
|
||||
if (normalContext.isEmpty() && !fragmentsFifo.empty()) {
|
||||
RTOS_LOCK_MUTEX(audioMutex);
|
||||
mutex_lock(&audioMutex);
|
||||
normalContext.setFragment(fragmentsFifo.get());
|
||||
RTOS_UNLOCK_MUTEX(audioMutex);
|
||||
mutex_unlock(&audioMutex);
|
||||
}
|
||||
result = normalContext.mixBuffer(buffer, g_eeGeneral.beepVolume, g_eeGeneral.wavVolume, fade);
|
||||
if (result > 0) {
|
||||
@@ -724,7 +705,7 @@ void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t f
|
||||
return;
|
||||
#endif
|
||||
|
||||
RTOS_LOCK_MUTEX(audioMutex);
|
||||
mutex_lock(&audioMutex);
|
||||
|
||||
freq = limit<uint16_t>(BEEP_MIN_FREQ, freq, BEEP_MAX_FREQ);
|
||||
|
||||
@@ -747,7 +728,7 @@ void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t f
|
||||
}
|
||||
}
|
||||
|
||||
RTOS_UNLOCK_MUTEX(audioMutex);
|
||||
mutex_unlock(&audioMutex);
|
||||
}
|
||||
|
||||
void AudioQueue::playFile(const char * filename, uint8_t flags, uint8_t id, int8_t fragmentVolume)
|
||||
@@ -774,7 +755,7 @@ void AudioQueue::playFile(const char * filename, uint8_t flags, uint8_t id, int8
|
||||
return;
|
||||
}
|
||||
|
||||
RTOS_LOCK_MUTEX(audioMutex);
|
||||
mutex_lock(&audioMutex);
|
||||
|
||||
if (flags & PLAY_BACKGROUND) {
|
||||
backgroundContext.clear();
|
||||
@@ -784,7 +765,7 @@ void AudioQueue::playFile(const char * filename, uint8_t flags, uint8_t id, int8
|
||||
fragmentsFifo.push(AudioFragment(filename, flags & 0x0f, fragmentVolume, id));
|
||||
}
|
||||
|
||||
RTOS_UNLOCK_MUTEX(audioMutex);
|
||||
mutex_unlock(&audioMutex);
|
||||
}
|
||||
|
||||
void AudioQueue::stopPlay(uint8_t id)
|
||||
@@ -797,12 +778,12 @@ void AudioQueue::stopPlay(uint8_t id)
|
||||
return;
|
||||
#endif
|
||||
|
||||
RTOS_LOCK_MUTEX(audioMutex);
|
||||
mutex_lock(&audioMutex);
|
||||
|
||||
fragmentsFifo.removePromptById(id);
|
||||
backgroundContext.stop(id);
|
||||
|
||||
RTOS_UNLOCK_MUTEX(audioMutex);
|
||||
mutex_unlock(&audioMutex);
|
||||
}
|
||||
|
||||
void AudioQueue::stopSD()
|
||||
@@ -815,19 +796,19 @@ void AudioQueue::stopSD()
|
||||
void AudioQueue::stopAll()
|
||||
{
|
||||
flush();
|
||||
RTOS_LOCK_MUTEX(audioMutex);
|
||||
mutex_lock(&audioMutex);
|
||||
priorityContext.clear();
|
||||
normalContext.clear();
|
||||
RTOS_UNLOCK_MUTEX(audioMutex);
|
||||
mutex_unlock(&audioMutex);
|
||||
}
|
||||
|
||||
void AudioQueue::flush()
|
||||
{
|
||||
RTOS_LOCK_MUTEX(audioMutex);
|
||||
mutex_lock(&audioMutex);
|
||||
fragmentsFifo.clear();
|
||||
varioContext.clear();
|
||||
backgroundContext.clear();
|
||||
RTOS_UNLOCK_MUTEX(audioMutex);
|
||||
mutex_unlock(&audioMutex);
|
||||
}
|
||||
|
||||
void audioPlay(unsigned int index, uint8_t id)
|
||||
|
||||
@@ -470,7 +470,6 @@ void codecsInit();
|
||||
void audioEvent(unsigned int index);
|
||||
void audioPlay(unsigned int index, uint8_t id=0);
|
||||
void audioStart();
|
||||
void audioTask(void * pdata);
|
||||
|
||||
#if defined(AUDIO) && defined(BUZZER)
|
||||
#define AUDIO_BUZZER(a, b) do { a; b; } while(0)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "edgetx.h"
|
||||
#include "io/frsky_firmware_update.h"
|
||||
#include "bluetooth_driver.h"
|
||||
#include "os/sleep.h"
|
||||
#include "trainer.h"
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
@@ -571,7 +572,7 @@ uint8_t Bluetooth::read(uint8_t * data, uint8_t size, uint32_t timeout)
|
||||
if (elapsed++ >= timeout) {
|
||||
return len;
|
||||
}
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
}
|
||||
data[len++] = byte;
|
||||
}
|
||||
@@ -829,11 +830,11 @@ const char * Bluetooth::flashFirmware(const char * filename, ProgressHandler pro
|
||||
|
||||
bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, true); // normal mode
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
sleep_ms(1000);
|
||||
|
||||
bluetoothInit(BLUETOOTH_BOOTLOADER_BAUDRATE, false); // bootloader mode
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
sleep_ms(1000);
|
||||
|
||||
const char * result = doFlashFirmware(filename, progressHandler);
|
||||
|
||||
@@ -851,7 +852,7 @@ const char * Bluetooth::flashFirmware(const char * filename, ProgressHandler pro
|
||||
|
||||
/* wait 1s off */
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
sleep_ms(1000);
|
||||
|
||||
state = BLUETOOTH_STATE_OFF;
|
||||
pulsesStart();
|
||||
|
||||
@@ -30,18 +30,13 @@
|
||||
#include "stm32_dma.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "hal/gpio.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
#endif
|
||||
#include "os/timer.h"
|
||||
|
||||
static uint8_t _led_colors[WS2812_BYTES_PER_LED * LED_STRIP_LENGTH];
|
||||
|
||||
extern const stm32_pulse_timer_t _led_timer;
|
||||
|
||||
static TimerHandle_t rgbLedTimer = nullptr;
|
||||
static StaticTimer_t rgbLedTimerBuffer;
|
||||
static timer_handle_t _refresh_timer = TIMER_INITIALIZER;
|
||||
|
||||
void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
@@ -77,35 +72,25 @@ void rgbLedClearAll()
|
||||
ws2812_update(&_led_timer);
|
||||
}
|
||||
|
||||
static void rgbLedTimerCb(TimerHandle_t xTimer)
|
||||
static void _refresh_cb(timer_handle_t* timer)
|
||||
{
|
||||
(void)xTimer;
|
||||
|
||||
(void)timer;
|
||||
ws2812_update(&_led_timer);
|
||||
}
|
||||
|
||||
void rgbLedStart()
|
||||
{
|
||||
if (!rgbLedTimer) {
|
||||
rgbLedTimer =
|
||||
xTimerCreateStatic("rgbLed", LED_STRIP_REFRESH_PERIOD / RTOS_MS_PER_TICK, pdTRUE, (void*)0,
|
||||
rgbLedTimerCb, &rgbLedTimerBuffer);
|
||||
if (!timer_is_created(&_refresh_timer)) {
|
||||
timer_create(&_refresh_timer, _refresh_cb, "rgbled",
|
||||
LED_STRIP_REFRESH_PERIOD, true);
|
||||
}
|
||||
|
||||
if (rgbLedTimer) {
|
||||
if( xTimerStart( rgbLedTimer, 0 ) != pdPASS ) {
|
||||
/* The timer could not be set into the Active state. */
|
||||
}
|
||||
}
|
||||
timer_start(&_refresh_timer);
|
||||
}
|
||||
|
||||
void rgbLedStop()
|
||||
{
|
||||
if (rgbLedTimer) {
|
||||
if( xTimerStop( rgbLedTimer, 5 / RTOS_MS_PER_TICK ) != pdPASS ) {
|
||||
/* The timer could not be stopped. */
|
||||
}
|
||||
}
|
||||
timer_stop(&_refresh_timer);
|
||||
}
|
||||
|
||||
const stm32_pulse_timer_t _led_timer = {
|
||||
|
||||
+30
-28
@@ -32,6 +32,9 @@
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "os/sleep.h"
|
||||
#include "os/time.h"
|
||||
#include "os/task.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
@@ -58,8 +61,8 @@
|
||||
|
||||
#define CLI_PRINT_BUFFER_SIZE 128
|
||||
|
||||
RTOS_TASK_HANDLE cliTaskId;
|
||||
RTOS_DEFINE_STACK(cliTaskId, cliStack, CLI_STACK_SIZE);
|
||||
task_handle_t cliTaskId;
|
||||
TASK_DEFINE_STACK(cliStack, CLI_STACK_SIZE);
|
||||
|
||||
static uint8_t cliRxBufferStorage[CLI_RX_BUFFER_SIZE];
|
||||
static StaticStreamBuffer_t cliRxBufferStatic;
|
||||
@@ -188,9 +191,9 @@ static uint32_t cliGetBaudRate()
|
||||
char cliLastLine[CLI_COMMAND_MAX_LEN+1];
|
||||
|
||||
typedef int (* CliFunction) (const char ** args);
|
||||
int cliExecLine(char * line);
|
||||
int cliExecCommand(const char ** argv);
|
||||
int cliHelp(const char ** argv);
|
||||
static int cliExecLine(char * line);
|
||||
static int cliExecCommand(const char ** argv);
|
||||
static int cliHelp(const char ** argv);
|
||||
|
||||
struct CliCommand
|
||||
{
|
||||
@@ -466,7 +469,7 @@ int cliTestNew()
|
||||
{
|
||||
char * tmp = nullptr;
|
||||
cliSerialPrint("Allocating 1kB with new()");
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
tmp = new char[1024];
|
||||
if (tmp) {
|
||||
cliSerialPrint("\tsuccess");
|
||||
@@ -478,7 +481,7 @@ int cliTestNew()
|
||||
}
|
||||
|
||||
cliSerialPrint("Allocating 10MB with (std::nothrow) new()");
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
tmp = new (std::nothrow) char[1024*1024*10];
|
||||
if (tmp) {
|
||||
cliSerialPrint("\tFAILURE, tmp = %p", tmp);
|
||||
@@ -490,7 +493,7 @@ int cliTestNew()
|
||||
}
|
||||
|
||||
cliSerialPrint("Allocating 10MB with new()");
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
tmp = new char[1024*1024*10];
|
||||
if (tmp) {
|
||||
cliSerialPrint("\tFAILURE, tmp = %p", tmp);
|
||||
@@ -569,10 +572,10 @@ void testClear() { lcdClear(); }
|
||||
float runTimedFunctionTest(timedTestFunc_t func, const char *name,
|
||||
uint32_t runtime, uint16_t step)
|
||||
{
|
||||
const uint32_t start = RTOS_GET_MS();
|
||||
const uint32_t start = time_get_ms();
|
||||
uint32_t noRuns = 0;
|
||||
uint32_t actualRuntime = 0;
|
||||
while ((actualRuntime = RTOS_GET_MS() - start) < runtime) {
|
||||
while ((actualRuntime = time_get_ms() - start) < runtime) {
|
||||
for (uint16_t n = 0; n < step; n++) {
|
||||
func();
|
||||
}
|
||||
@@ -583,14 +586,14 @@ float runTimedFunctionTest(timedTestFunc_t func, const char *name,
|
||||
cliSerialPrint("Test %s speed: %lu.%02u, (%lu runs in %lu ms)", name,
|
||||
uint32_t(result), uint16_t((result - uint32_t(result)) * 100.0f),
|
||||
noRuns, actualRuntime);
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
return result;
|
||||
}
|
||||
|
||||
int cliTestGraphics()
|
||||
{
|
||||
cliSerialPrint("Starting graphics performance test...");
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
|
||||
watchdogSuspend(6000 /*60s*/);
|
||||
if (pulsesStarted()) {
|
||||
@@ -723,7 +726,7 @@ void testMemoryCopyFrom_SDRAM_to_SDRAM_8bit()
|
||||
int cliTestMemorySpeed()
|
||||
{
|
||||
cliSerialPrint("Starting memory speed test...");
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
|
||||
watchdogSuspend(6000 /*60s*/);
|
||||
if (pulsesStarted()) {
|
||||
@@ -744,7 +747,7 @@ int cliTestMemorySpeed()
|
||||
|
||||
LTDC_Cmd(DISABLE);
|
||||
cliSerialPrint("Disabling LCD...");
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
|
||||
result += RUN_MEMORY_TEST(testMemoryReadFrom_RAM_8bit, 200);
|
||||
result += RUN_MEMORY_TEST(testMemoryReadFrom_RAM_32bit, 200);
|
||||
@@ -783,7 +786,7 @@ int cliTestModelsList()
|
||||
int count = 0;
|
||||
|
||||
cliSerialPrint("Starting fetching RF data 100x...");
|
||||
const uint32_t start = RTOS_GET_MS();
|
||||
const uint32_t start = time_get_ms();
|
||||
|
||||
const list<ModelsCategory *> &cats = modList.getCategories();
|
||||
while (1) {
|
||||
@@ -803,7 +806,7 @@ int cliTestModelsList()
|
||||
|
||||
done:
|
||||
cliSerialPrint("Done fetching %ix RF data: %lu ms", count,
|
||||
(RTOS_GET_MS() - start));
|
||||
(time_get_ms() - start));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1474,7 +1477,7 @@ int cliRepeat(const char ** argv)
|
||||
counter = interval;
|
||||
|
||||
uint8_t c;
|
||||
const TickType_t xTimeout = 20 / RTOS_MS_PER_TICK;
|
||||
const TickType_t xTimeout = 20 / portTICK_PERIOD_MS;
|
||||
while (!xStreamBufferReceive(cliRxBuffer, &c, 1, xTimeout)
|
||||
|| !(c == '\r' || c == '\n' || c == ' ')) {
|
||||
|
||||
@@ -1610,9 +1613,9 @@ int cliCrypt(const char ** argv)
|
||||
mixerTaskStop();
|
||||
perMainEnabled = false;
|
||||
|
||||
uint32_t startMs = RTOS_GET_MS();
|
||||
uint32_t startMs = time_get_ms();
|
||||
testAccessDenied(100000);
|
||||
cliSerialPrintf("access_denied: %f us/run\r\n", (RTOS_GET_MS() - startMs)*1000.0f / 100000.0f);
|
||||
cliSerialPrintf("access_denied: %f us/run\r\n", (time_get_ms() - startMs)*1000.0f / 100000.0f);
|
||||
|
||||
cliSerialPrint("Decrypted (SW):");
|
||||
dumpBody(cryptOutput, sizeof(cryptOutput));
|
||||
@@ -1706,7 +1709,7 @@ const CliCommand cliCommands[] = {
|
||||
{ nullptr, nullptr, nullptr } /* sentinel */
|
||||
};
|
||||
|
||||
int cliHelp(const char ** argv)
|
||||
static int cliHelp(const char ** argv)
|
||||
{
|
||||
for (const CliCommand * command = cliCommands; command->name != nullptr; command++) {
|
||||
if (argv[1][0] == '\0' || !strcmp(command->name, argv[0])) {
|
||||
@@ -1722,7 +1725,7 @@ int cliHelp(const char ** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cliExecCommand(const char ** argv)
|
||||
static int cliExecCommand(const char ** argv)
|
||||
{
|
||||
if (argv[0][0] == '\0')
|
||||
return 0;
|
||||
@@ -1736,7 +1739,7 @@ int cliExecCommand(const char ** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cliExecLine(char * line)
|
||||
static int cliExecLine(char * line)
|
||||
{
|
||||
int len = strlen(line);
|
||||
const char * argv[CLI_COMMAND_MAX_ARGS];
|
||||
@@ -1759,7 +1762,7 @@ int cliExecLine(char * line)
|
||||
#define CHAR_CR 0x0D
|
||||
#define CHAR_DEL 0x7F
|
||||
|
||||
void cliTask(void * pdata)
|
||||
static void cliTask()
|
||||
{
|
||||
char line[CLI_COMMAND_MAX_LEN+1];
|
||||
int pos = 0;
|
||||
@@ -1773,7 +1776,7 @@ void cliTask(void * pdata)
|
||||
// of going byte-by-byte.
|
||||
|
||||
/* Block for max 100ms. */
|
||||
const TickType_t xTimeout = 100 / RTOS_MS_PER_TICK;
|
||||
const TickType_t xTimeout = 100 / portTICK_PERIOD_MS;
|
||||
size_t xReceivedBytes = xStreamBufferReceive(cliRxBuffer, &c, 1, xTimeout);
|
||||
|
||||
if (!mixerTaskRunning()) {
|
||||
@@ -1811,8 +1814,7 @@ void cliTask(void * pdata)
|
||||
if (pos == 0 && cliLastLine[0]) {
|
||||
// execute (repeat) last command
|
||||
strcpy(line, cliLastLine);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// save new command
|
||||
strcpy(cliLastLine, line);
|
||||
}
|
||||
@@ -1843,6 +1845,6 @@ void cliStart()
|
||||
// Setup consumer callback
|
||||
cliReceiveCallBack = cliDefaultRx;
|
||||
|
||||
RTOS_CREATE_TASK(cliTaskId, cliTask, "CLI", cliStack, CLI_STACK_SIZE,
|
||||
CLI_TASK_PRIO);
|
||||
task_create(&cliTaskId, cliTask, "CLI", cliStack, CLI_STACK_SIZE,
|
||||
CLI_TASK_PRIO);
|
||||
}
|
||||
|
||||
+9
-46
@@ -19,6 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "os/sleep.h"
|
||||
#if !defined(SIMU)
|
||||
#include "stm32_ws2812.h"
|
||||
#include "boards/generic_stm32/rgb_leds.h"
|
||||
@@ -45,6 +46,7 @@
|
||||
|
||||
#include "tasks.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "os/async.h"
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
#include "bluetooth_driver.h"
|
||||
@@ -167,7 +169,7 @@ void checkValidMCU(void)
|
||||
static bool evalFSok = false;
|
||||
#endif
|
||||
|
||||
void timer_10ms()
|
||||
void per10ms()
|
||||
{
|
||||
DEBUG_TIMER_START(debugTimerPer10ms);
|
||||
DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod);
|
||||
@@ -245,44 +247,6 @@ void timer_10ms()
|
||||
DEBUG_TIMER_STOP(debugTimerPer10ms);
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
// Handle 10ms timer asynchronously
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
|
||||
static volatile bool _timer_10ms_cb_in_queue = false;
|
||||
|
||||
static void _timer_10ms_cb(void *pvParameter1, uint32_t ulParameter2)
|
||||
{
|
||||
(void)pvParameter1;
|
||||
(void)ulParameter2;
|
||||
_timer_10ms_cb_in_queue = false;
|
||||
timer_10ms();
|
||||
}
|
||||
|
||||
void per10ms()
|
||||
{
|
||||
|
||||
if (!_timer_10ms_cb_in_queue && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
xReturn = xTimerPendFunctionCallFromISR(_timer_10ms_cb, nullptr, 0, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xReturn == pdPASS) {
|
||||
_timer_10ms_cb_in_queue = true;
|
||||
} else {
|
||||
TRACE("xTimerPendFunctionCallFromISR() queue full");
|
||||
}
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
|
||||
#else // !defined(SIMU)
|
||||
void per10ms() { timer_10ms(); }
|
||||
#endif
|
||||
|
||||
|
||||
FlightModeData *flightModeAddress(uint8_t idx)
|
||||
{
|
||||
return &g_model.flightModeData[idx];
|
||||
@@ -757,7 +721,7 @@ void checkAll(bool isBootCheck)
|
||||
showMessageBox(STR_KEYSTUCK);
|
||||
tmr10ms_t tgtime = get_tmr10ms() + 500;
|
||||
while (tgtime != get_tmr10ms()) {
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
WDG_RESET();
|
||||
}
|
||||
}
|
||||
@@ -875,8 +839,7 @@ void checkThrottleStick()
|
||||
checkBacklight();
|
||||
|
||||
WDG_RESET();
|
||||
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
}
|
||||
|
||||
LED_ERROR_END();
|
||||
@@ -907,7 +870,7 @@ void alert(const char * title, const char * msg , uint8_t sound)
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
|
||||
if (getEvent()) // wait for key release
|
||||
break;
|
||||
@@ -1131,10 +1094,10 @@ void edgeTxClose(uint8_t shutdown)
|
||||
storageCheck(true);
|
||||
|
||||
while (IS_PLAYING(ID_PLAY_PROMPT_BASE + AU_BYE)) {
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
}
|
||||
|
||||
RTOS_WAIT_MS(100);
|
||||
sleep_ms(100);
|
||||
|
||||
#if defined(COLORLCD)
|
||||
cancelShutdownAnimation(); // To prevent simulator crash
|
||||
@@ -1887,7 +1850,7 @@ uint32_t pwrCheck()
|
||||
RAISE_ALERT(STR_MODEL, STR_MODEL_STILL_POWERED, STR_PRESS_ENTER_TO_CONFIRM, AU_MODEL_STILL_POWERED);
|
||||
while (TELEMETRY_STREAMING()) {
|
||||
resetForcePowerOffRequest();
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
if (pwrPressed()) {
|
||||
return e_power_on;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "tasks.h"
|
||||
|
||||
#include "mixer_scheduler.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
@@ -169,12 +171,12 @@ void menuStatisticsDebug(event_t event)
|
||||
y += FH;
|
||||
|
||||
lcdDrawTextAlignedLeft(y, STR_FREE_STACK);
|
||||
lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, menusStack.available(), LEFT);
|
||||
lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, task_get_stack_usage(&menusTaskId), LEFT);
|
||||
lcdDrawText(lcdLastRightPos, y, "/");
|
||||
lcdDrawNumber(lcdLastRightPos, y, mixerStack.available(), LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, task_get_stack_usage(&mixerTaskId), LEFT);
|
||||
#if defined(AUDIO)
|
||||
lcdDrawText(lcdLastRightPos, y, "/");
|
||||
lcdDrawNumber(lcdLastRightPos, y, audioStack.available(), LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, task_get_stack_usage(&audioTaskId), LEFT);
|
||||
#endif
|
||||
y += FH;
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "edgetx.h"
|
||||
|
||||
#include "tasks.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
#define STATS_1ST_COLUMN FW/2
|
||||
#define STATS_2ND_COLUMN 12*FW+FW/2
|
||||
@@ -188,12 +190,12 @@ void menuStatisticsDebug(event_t event)
|
||||
|
||||
lcdDrawTextAlignedLeft(y, STR_FREE_STACK);
|
||||
lcdDrawText(MENU_DEBUG_COL1_OFS, y+1, "[M]", SMLSIZE);
|
||||
lcdDrawNumber(lcdLastRightPos, y, menusStack.available(), LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, task_get_stack_usage(&menusTaskId), LEFT);
|
||||
lcdDrawText(lcdLastRightPos+2, y+1, "[X]", SMLSIZE);
|
||||
lcdDrawNumber(lcdLastRightPos, y, mixerStack.available(), LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, task_get_stack_usage(&mixerTaskId), LEFT);
|
||||
#if defined(AUDIO)
|
||||
lcdDrawText(lcdLastRightPos+2, y+1, "[A]", SMLSIZE);
|
||||
lcdDrawNumber(lcdLastRightPos, y, audioStack.available(), LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, task_get_stack_usage(&audioTaskId), LEFT);
|
||||
#endif
|
||||
lcdDrawText(lcdLastRightPos+2, y+1, "[I]", SMLSIZE);
|
||||
lcdDrawNumber(lcdLastRightPos, y, mainStackAvailable(), LEFT);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#include "LvglWrapper.h"
|
||||
#include "etx_lv_theme.h"
|
||||
@@ -359,9 +360,10 @@ LvglWrapper* LvglWrapper::instance()
|
||||
void LvglWrapper::run()
|
||||
{
|
||||
#if defined(SIMU)
|
||||
tmr10ms_t tick = get_tmr10ms();
|
||||
lv_tick_inc((tick - lastTick) * 10);
|
||||
lastTick = tick;
|
||||
static uint32_t last_tick = 0;
|
||||
uint32_t tick = time_get_ms();
|
||||
lv_tick_inc(tick - last_tick);
|
||||
last_tick = tick;
|
||||
#endif
|
||||
lv_timer_handler();
|
||||
}
|
||||
|
||||
@@ -33,9 +33,6 @@ class LvglWrapper
|
||||
static LvglWrapper *_instance;
|
||||
static void pollInputs();
|
||||
|
||||
tmr10ms_t lastTick = 0;
|
||||
// TODO: add driver instances here
|
||||
|
||||
LvglWrapper();
|
||||
~LvglWrapper() {}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "edgetx.h"
|
||||
#include "etx_lv_theme.h"
|
||||
#include "os/sleep.h"
|
||||
#include "view_main.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
@@ -186,7 +187,7 @@ static void run_ui_manually()
|
||||
checkBacklight();
|
||||
WDG_RESET();
|
||||
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
LvglWrapper::runNested();
|
||||
MainWindow::instance()->run(false);
|
||||
}
|
||||
@@ -211,7 +212,7 @@ void FullScreenDialog::runForever(bool checkPwr)
|
||||
#endif
|
||||
} else if (check == e_power_press) {
|
||||
WDG_RESET();
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "libopenui.h"
|
||||
#include "edgetx.h"
|
||||
#include "lvgl/src/hal/lv_hal_tick.h"
|
||||
#include "os/sleep.h"
|
||||
#include "pwr.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "etx_lv_theme.h"
|
||||
@@ -51,7 +53,7 @@ static void _run_popup_dialog(const char* title, const char* msg,
|
||||
#endif
|
||||
} else if (check == e_power_press) {
|
||||
WDG_RESET();
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -59,7 +61,7 @@ static void _run_popup_dialog(const char* title, const char* msg,
|
||||
WDG_RESET();
|
||||
MainWindow::instance()->run();
|
||||
LvglWrapper::runNested();
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ void POPUP_WARNING_ON_UI_TASK(const char* message, const char* info,
|
||||
|
||||
// Wait in case already in popup.
|
||||
while (ui_popup_active) {
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
}
|
||||
ui_popup_title = "Warning";
|
||||
ui_popup_msg = message;
|
||||
@@ -105,7 +107,7 @@ void POPUP_WARNING_ON_UI_TASK(const char* message, const char* info,
|
||||
// Wait until closed
|
||||
if (waitForClose) {
|
||||
while (ui_popup_active) {
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +153,8 @@ class BubbleDialog : public Window
|
||||
public:
|
||||
BubbleDialog(const char* message, int timeout, coord_t width) :
|
||||
Window(MainWindow::instance(), rect_t{(LCD_W - width) / 2, LCD_H - 100, width, 50},
|
||||
bubble_popup_create)
|
||||
bubble_popup_create),
|
||||
startTime(lv_tick_get()), timeout(timeout)
|
||||
{
|
||||
setWindowFlag(OPAQUE);
|
||||
|
||||
@@ -163,21 +166,20 @@ class BubbleDialog : public Window
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
etx_obj_add_style(label, styles->text_align_center, LV_PART_MAIN);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
|
||||
endTime = RTOS_GET_MS() + timeout;
|
||||
}
|
||||
|
||||
bool isBubblePopup() override { return true; }
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
if (RTOS_GET_MS() >= endTime) {
|
||||
if (lv_tick_elaps(startTime) >= timeout) {
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t endTime;
|
||||
uint32_t startTime;
|
||||
uint32_t timeout;
|
||||
};
|
||||
|
||||
void POPUP_BUBBLE(const char* message, uint32_t timeout, coord_t width)
|
||||
|
||||
@@ -37,13 +37,13 @@ static bool timepg = false;
|
||||
static void on_draw_begin(lv_event_t* e)
|
||||
{
|
||||
if (timepg) {
|
||||
dsms = RTOS_GET_MS();
|
||||
dsms = lv_tick_get();
|
||||
}
|
||||
}
|
||||
static void on_draw_end(lv_event_t* e)
|
||||
{
|
||||
timepg = false;
|
||||
dems = RTOS_GET_MS();
|
||||
dems = lv_tick_get();
|
||||
TRACE("tab time: build %ld layout %ld draw %ld total %ld",
|
||||
end_ms - start_ms, dsms - end_ms, dems - dsms, dems - start_ms);
|
||||
}
|
||||
@@ -301,7 +301,7 @@ void TabsGroup::setCurrentTab(unsigned index)
|
||||
currentTab = tab;
|
||||
|
||||
#if defined(DEBUG)
|
||||
start_ms = RTOS_GET_MS();
|
||||
start_ms = lv_tick_get();
|
||||
timepg = true;
|
||||
#endif
|
||||
|
||||
@@ -321,7 +321,7 @@ void TabsGroup::setCurrentTab(unsigned index)
|
||||
lv_obj_refresh_style(body->getLvObj(), LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
|
||||
#if defined(DEBUG)
|
||||
end_ms = RTOS_GET_MS();
|
||||
end_ms = lv_tick_get();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ coord_t TopBar::getVisibleHeight(float visible) const // 0.0 -> 1.0
|
||||
|
||||
void TopBar::checkEvents()
|
||||
{
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = lv_tick_get();
|
||||
if (now - lastRefresh >= TOPBAR_REFRESH) {
|
||||
lastRefresh = now;
|
||||
TopBarBase::checkEvents();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "view_statistics.h"
|
||||
#include "os/task.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "tasks.h"
|
||||
@@ -333,14 +334,14 @@ void DebugViewPage::build(Window* window)
|
||||
#endif
|
||||
new DebugInfoNumber<uint32_t>(
|
||||
line, rect_t{0, 0, DBG_B_WIDTH, DBG_B_HEIGHT},
|
||||
[] { return menusStack.available(); }, STR_STACK_MENU);
|
||||
[] { return task_get_stack_usage(&menusTaskId); }, STR_STACK_MENU);
|
||||
new DebugInfoNumber<uint32_t>(
|
||||
line, rect_t{0, 0, DBG_B_WIDTH, DBG_B_HEIGHT},
|
||||
[] { return mixerStack.available(); }, STR_STACK_MIX);
|
||||
[] { return task_get_stack_usage(&mixerTaskId); }, STR_STACK_MIX);
|
||||
#if defined(AUDIO)
|
||||
new DebugInfoNumber<uint32_t>(
|
||||
line, rect_t{0, 0, DBG_B_WIDTH, DBG_B_HEIGHT},
|
||||
[] { return audioStack.available(); }, STR_STACK_AUDIO);
|
||||
[] { return task_get_stack_usage(&audioTaskId); }, STR_STACK_AUDIO);
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_LATENCY)
|
||||
|
||||
@@ -367,7 +367,7 @@ class SensorButton : public ListLineButton
|
||||
else
|
||||
lv_obj_add_flag(fresh, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = lv_tick_get();
|
||||
TelemetryItem& telemetryItem = telemetryItems[index];
|
||||
|
||||
// Update value
|
||||
@@ -479,7 +479,7 @@ class SensorEditWindow : public SubPage
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = lv_tick_get();
|
||||
TelemetryItem& telemetryItem = telemetryItems[index];
|
||||
|
||||
if ((now - lastRefresh >= 200) || telemetryItem.isFresh()) {
|
||||
|
||||
@@ -609,8 +609,8 @@ class ModuleSubTypeChoice : public Choice
|
||||
MultiModuleStatus& status = getMultiModuleStatus(moduleIdx);
|
||||
status.invalidate();
|
||||
|
||||
uint32_t startUpdate = RTOS_GET_MS();
|
||||
while (!status.isValid() && (RTOS_GET_MS() - startUpdate < 250))
|
||||
uint32_t startUpdate = lv_tick_get();
|
||||
while (!status.isValid() && (lv_tick_elaps(startUpdate) < 250))
|
||||
;
|
||||
SET_DIRTY();
|
||||
#endif
|
||||
|
||||
@@ -44,9 +44,9 @@ void RfScanDialog::checkEvents()
|
||||
{
|
||||
if (!protos->isScanning()) {
|
||||
closeDialog();
|
||||
} else if (RTOS_GET_MS() - lastUpdate >= 200) {
|
||||
} else if (lv_tick_elaps(lastUpdate) >= 200) {
|
||||
showProgress();
|
||||
lastUpdate = RTOS_GET_MS();
|
||||
lastUpdate = lv_tick_get();
|
||||
}
|
||||
|
||||
ProgressDialog::checkEvents();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "edgetx.h"
|
||||
#include "telemetry/ghost.h"
|
||||
#include "telemetry/ghost_menu.h"
|
||||
#include "os/sleep.h"
|
||||
|
||||
class GhostModuleConfigWindow : public Window
|
||||
{
|
||||
@@ -166,7 +167,7 @@ void RadioGhostModuleConfig::onLongPressRTN()
|
||||
reusableBuffer.ghostMenu.buttonAction = GHST_BTN_NONE;
|
||||
reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_CLOSE;
|
||||
moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL;
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
#if defined(TRIMS_EMULATE_BUTTONS)
|
||||
setHatsAsKeys(false); // switch trims back to normal
|
||||
#endif
|
||||
@@ -183,7 +184,7 @@ void RadioGhostModuleConfig::checkEvents()
|
||||
reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_OPEN;
|
||||
moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL;
|
||||
} else if (reusableBuffer.ghostMenu.menuStatus == GHST_MENU_STATUS_CLOSING) {
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
deleteLater();
|
||||
#if defined(TRIMS_EMULATE_BUTTONS)
|
||||
setHatsAsKeys(false); // switch trims back to normal
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "inactivity_timer.h"
|
||||
#include "edgetx.h"
|
||||
#include "os/sleep.h"
|
||||
#include "stamp.h"
|
||||
#include "theme_manager.h"
|
||||
|
||||
@@ -123,7 +124,7 @@ void waitSplash()
|
||||
if (splashStartTime) {
|
||||
#if defined(SIMU)
|
||||
// Simulator - inputsMoved() returns true immediately without this!
|
||||
RTOS_WAIT_TICKS(30);
|
||||
sleep_ms(30);
|
||||
#endif // defined(SIMU)
|
||||
|
||||
splashStartTime += SPLASH_TIMEOUT;
|
||||
@@ -133,7 +134,7 @@ void waitSplash()
|
||||
WDG_RESET();
|
||||
checkSpeakerVolume();
|
||||
checkBacklight();
|
||||
RTOS_WAIT_TICKS(10);
|
||||
sleep_ms(10);
|
||||
auto evt = getEvent();
|
||||
if (evt || inactivityCheckInputs()) {
|
||||
if (evt) killEvents(evt);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "os/sleep.h"
|
||||
|
||||
#if defined(GHOST) && defined(HARDWARE_EXTERNAL_MODULE)
|
||||
|
||||
@@ -84,7 +85,7 @@ void menuGhostModuleConfig(event_t event)
|
||||
reusableBuffer.ghostMenu.buttonAction = GHST_BTN_NONE;
|
||||
reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_CLOSE;
|
||||
moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL;
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
popMenu();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "os/sleep.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
extern uint8_t g_moduleIdx;
|
||||
@@ -52,7 +53,7 @@ void menuRadioPowerMeter(event_t event)
|
||||
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
sleep_ms(1000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "os/sleep.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
extern uint8_t g_moduleIdx;
|
||||
@@ -49,7 +50,7 @@ void menuRadioSpectrumAnalyser(event_t event)
|
||||
#endif
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(1000);
|
||||
sleep_ms(1000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "inactivity_timer.h"
|
||||
#include "os/sleep.h"
|
||||
|
||||
static bool splashStarted = false;
|
||||
|
||||
@@ -53,7 +54,7 @@ void waitSplash()
|
||||
tmr10ms_t tgtime = get_tmr10ms() + SPLASH_TIMEOUT;
|
||||
|
||||
while (tgtime > get_tmr10ms()) {
|
||||
RTOS_WAIT_TICKS(1);
|
||||
sleep_ms(1);
|
||||
|
||||
getADC();
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "edgetx.h"
|
||||
#include "switches.h"
|
||||
#include "mixes.h"
|
||||
#include "os/sleep.h"
|
||||
|
||||
#undef CPN
|
||||
#include "MultiSubtypeDefs.h"
|
||||
@@ -756,7 +757,7 @@ static void runAntennaSelectionMenu()
|
||||
WDG_RESET();
|
||||
MainWindow::instance()->run();
|
||||
LvglWrapper::runNested();
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -1229,7 +1230,7 @@ bool confirmModelChange()
|
||||
if (TELEMETRY_STREAMING()) {
|
||||
RAISE_ALERT(STR_MODEL, STR_MODEL_STILL_POWERED, STR_PRESS_ENTER_TO_CONFIRM, AU_MODEL_STILL_POWERED);
|
||||
while (TELEMETRY_STREAMING()) {
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
if (readKeys() == (1 << KEY_ENTER)) {
|
||||
killEvents(KEY_ENTER);
|
||||
return true;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "FatFs/diskio.h"
|
||||
|
||||
#if FF_FS_REENTRANT != 0
|
||||
#include "rtos.h"
|
||||
#include "os/task.h"
|
||||
#endif
|
||||
|
||||
struct fatfs_drive_t {
|
||||
@@ -31,7 +31,7 @@ struct fatfs_drive_t {
|
||||
uint8_t lun;
|
||||
bool initialized;
|
||||
#if FF_FS_REENTRANT != 0
|
||||
RTOS_MUTEX_HANDLE mutex;
|
||||
mutex_handle_t mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ int fatfsRegisterDriver(const diskio_driver_t* drv, uint8_t lun)
|
||||
|
||||
#if FF_FS_REENTRANT != 0
|
||||
// init IO mutex only once
|
||||
RTOS_CREATE_MUTEX(drive.mutex);
|
||||
mutex_create(&drive.mutex);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
@@ -100,10 +100,10 @@ int ff_mutex_create(int vol)
|
||||
|
||||
int ff_mutex_take(int vol)
|
||||
{
|
||||
return RTOS_LOCK_MUTEX(_fatfs_drives[vol].mutex);
|
||||
return mutex_lock(&_fatfs_drives[vol].mutex);
|
||||
}
|
||||
|
||||
void ff_mutex_give(int vol) { RTOS_UNLOCK_MUTEX(_fatfs_drives[vol].mutex); }
|
||||
void ff_mutex_give(int vol) { mutex_unlock(&_fatfs_drives[vol].mutex); }
|
||||
|
||||
void ff_mutex_delete(int vol) { }
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "flash_driver.h"
|
||||
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "os/sleep.h"
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
#include "libopenui.h"
|
||||
@@ -104,9 +105,7 @@ void BootloaderFirmwareUpdate::flashFirmware(const char * filename, ProgressHand
|
||||
if (f_eof(&file)) break;
|
||||
|
||||
#if defined(SIMU)
|
||||
// add an artificial delay and check for simu quit
|
||||
if (SIMU_SLEEP_OR_EXIT_MS(30))
|
||||
break;
|
||||
sleep_ms(30);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "edgetx.h"
|
||||
#include "frsky_firmware_update.h"
|
||||
#include "debug.h"
|
||||
#include "os/sleep.h"
|
||||
#include "timers_driver.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
@@ -118,11 +119,9 @@ bool FrskyDeviceFirmwareUpdate::readBuffer(uint8_t * buffer, uint8_t count, uint
|
||||
while (index < count && elapsed < timeout) {
|
||||
if (uart_drv->getByte(uart_ctx, &(buffer[index]))) {
|
||||
++index;
|
||||
}
|
||||
else {
|
||||
RTOS_WAIT_MS(1);
|
||||
if (++elapsed == timeout)
|
||||
return false;
|
||||
} else {
|
||||
sleep_ms(1);
|
||||
if (++elapsed == timeout) return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +130,7 @@ bool FrskyDeviceFirmwareUpdate::readBuffer(uint8_t * buffer, uint8_t count, uint
|
||||
|
||||
const uint8_t * FrskyDeviceFirmwareUpdate::readFrame(uint32_t timeout)
|
||||
{
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
|
||||
uint8_t len = 0;
|
||||
bool bytestuff = false;
|
||||
@@ -142,7 +141,7 @@ const uint8_t * FrskyDeviceFirmwareUpdate::readFrame(uint32_t timeout)
|
||||
uint8_t byte = 0;
|
||||
|
||||
while (uart_drv->getByte(uart_ctx, &byte) == 0) {
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
if (elapsed++ >= timeout) {
|
||||
TRACE("timeout in frame (len=%d)",len);
|
||||
return nullptr;
|
||||
@@ -178,7 +177,7 @@ bool FrskyDeviceFirmwareUpdate::waitState(State newState, uint32_t timeout)
|
||||
static uint8_t pass = 0;
|
||||
if (++pass == 10) {
|
||||
pass = 0;
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
@@ -226,7 +225,7 @@ const char * FrskyDeviceFirmwareUpdate::sendPowerOn()
|
||||
{
|
||||
state = SPORT_POWERUP_REQ;
|
||||
|
||||
RTOS_WAIT_MS(50);
|
||||
sleep_ms(50);
|
||||
uart_drv->clearRxBuffer(uart_ctx);
|
||||
|
||||
for (int i=0; i<10; i++) {
|
||||
@@ -242,7 +241,7 @@ const char * FrskyDeviceFirmwareUpdate::sendPowerOn()
|
||||
|
||||
const char * FrskyDeviceFirmwareUpdate::sendReqVersion()
|
||||
{
|
||||
RTOS_WAIT_MS(20);
|
||||
sleep_ms(20);
|
||||
uart_drv->clearRxBuffer(uart_ctx);
|
||||
|
||||
state = SPORT_VERSION_REQ;
|
||||
@@ -354,7 +353,7 @@ const char *FrskyDeviceFirmwareUpdate::doFlashFirmware(
|
||||
if (set_pwr) set_pwr(true);
|
||||
|
||||
// wait a bit for PWR to settle
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
|
||||
// Special update method for X12S / X10 iXJT
|
||||
if (module == INTERNAL_MODULE && port == ETX_MOD_PORT_UART && set_bootcmd != nullptr) {
|
||||
@@ -408,7 +407,7 @@ const char *FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(
|
||||
|
||||
if (count == 0) {
|
||||
uart_drv->sendByte(uart_ctx, 0xA1);
|
||||
RTOS_WAIT_MS(50);
|
||||
sleep_ms(50);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -453,7 +452,7 @@ const char *FrskyDeviceFirmwareUpdate::uploadFileNormal(
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
uart_drv->clearRxBuffer(uart_ctx);
|
||||
|
||||
state = SPORT_DATA_TRANSFER;
|
||||
@@ -519,7 +518,7 @@ const char *FrskyDeviceFirmwareUpdate::flashFirmware(
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(1000 /*10s*/);
|
||||
RTOS_WAIT_MS(2000);
|
||||
sleep_ms(2000);
|
||||
|
||||
const char * result = doFlashFirmware(filename, progressHandler);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "os/sleep.h"
|
||||
#if !defined(DISABLE_MULTI_UPDATE)
|
||||
|
||||
#include "hal.h"
|
||||
@@ -32,6 +33,7 @@
|
||||
|
||||
#include "timers_driver.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -157,9 +159,9 @@ void MultiFirmwareUpdateDriver::deinit()
|
||||
|
||||
bool MultiFirmwareUpdateDriver::getRxByte(uint8_t & byte) const
|
||||
{
|
||||
uint32_t time = RTOS_GET_MS();
|
||||
uint32_t time = time_get_ms();
|
||||
|
||||
while ((RTOS_GET_MS() - time) < 100) { // 100ms
|
||||
while ((time_get_ms() - time) < 100) { // 100ms
|
||||
if (getByte(byte)) {
|
||||
#if defined(DEBUG_EXT_MODULE_FLASH)
|
||||
TRACE("[RX] 0x%X", byte);
|
||||
@@ -220,7 +222,7 @@ const char * MultiFirmwareUpdateDriver::waitForInitialSync()
|
||||
// avoids sending STK_READ_SIGN with STK_OK
|
||||
// in case the receiver is too slow changing
|
||||
// to RX mode (half-duplex).
|
||||
RTOS_WAIT_TICKS(1);
|
||||
sleep_ms(1);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -258,7 +260,7 @@ const char * MultiFirmwareUpdateDriver::loadAddress(uint32_t offset) const
|
||||
|
||||
// avoids sending next page back-to-back with STK_OK
|
||||
// in case the receiver is to slow changing to RX mode (half-duplex).
|
||||
RTOS_WAIT_TICKS(1);
|
||||
sleep_ms(1);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -310,8 +312,7 @@ const char* MultiFirmwareUpdateDriver::flashFirmware(
|
||||
#if defined(SIMU)
|
||||
for (uint16_t i = 0; i < 100; i++) {
|
||||
progressHandler(label, STR_WRITING, i, 100);
|
||||
if (SIMU_SLEEP_OR_EXIT_MS(30))
|
||||
break;
|
||||
sleep_ms(30);
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
@@ -321,7 +322,7 @@ const char* MultiFirmwareUpdateDriver::flashFirmware(
|
||||
|
||||
/* wait 500ms for power on */
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(500);
|
||||
sleep_ms(500);
|
||||
|
||||
result = waitForInitialSync();
|
||||
if (result) {
|
||||
@@ -553,7 +554,7 @@ bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, ProgressHan
|
||||
|
||||
/* wait 2s off */
|
||||
watchdogSuspend(500 /*5s*/);
|
||||
RTOS_WAIT_MS(3000);
|
||||
sleep_ms(3000);
|
||||
|
||||
MultiFirmwareUpdateDriver driver(module, type);
|
||||
const char * result = driver.flashFirmware(&file, getBasename(filename), progressHandler);
|
||||
|
||||
@@ -29,30 +29,20 @@
|
||||
#include "gui_common.h"
|
||||
|
||||
#include "edgetx.h" // reusableBuffer
|
||||
#include "os/time.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if !defined(SIMU)
|
||||
static timer_handle_t _protoScanTimers[NUM_MODULES] = {TIMER_INITIALIZER};
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
|
||||
struct ProtoScanTimer {
|
||||
TimerHandle_t timer = nullptr;
|
||||
StaticTimer_t timerBuffer;
|
||||
};
|
||||
|
||||
static ProtoScanTimer _protoScanTimers[NUM_MODULES];
|
||||
|
||||
void MultiRfProtocols::timerCb(TimerHandle_t xTimer)
|
||||
void MultiRfProtocols::timerCb(timer_handle_t* h)
|
||||
{
|
||||
uint8_t moduleIdx = (uint8_t)(uintptr_t)pvTimerGetTimerID(xTimer);
|
||||
uint8_t moduleIdx = (uint8_t)(h - _protoScanTimers);
|
||||
auto instance = MultiRfProtocols::instance(moduleIdx);
|
||||
if (instance->scanState == ScanBegin || instance->scanState == Scanning) {
|
||||
instance->fillBuiltinProtos();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MultiRfProtocols* MultiRfProtocols::_instance[MAX_MODULES] = {};
|
||||
|
||||
@@ -201,7 +191,7 @@ float MultiRfProtocols::getProgress() const
|
||||
|
||||
if (scanState == ScanStop) return 0.0;
|
||||
if (scanState == ScanBegin) {
|
||||
float t = (float)(RTOS_GET_MS() - scanStart) / (float)MULTI_PROTOLIST_START_TIMEOUT;
|
||||
float t = (float)(time_get_ms() - scanStart) / (float)MULTI_PROTOLIST_START_TIMEOUT;
|
||||
return t * WAIT_TIME_RATIO;
|
||||
}
|
||||
|
||||
@@ -225,29 +215,17 @@ bool MultiRfProtocols::triggerScan()
|
||||
scanState = ScanBegin;
|
||||
currentProto = MULTI_INVALID_PROTO;
|
||||
moduleState[moduleIdx].mode = MODULE_MODE_GET_HARDWARE_INFO;
|
||||
scanStart = lastScan = RTOS_GET_MS();
|
||||
scanStart = lastScan = time_get_ms();
|
||||
|
||||
#if !defined(SIMU)
|
||||
auto scanTimer = &_protoScanTimers[moduleIdx];
|
||||
if (!scanTimer->timer) {
|
||||
scanTimer->timer = xTimerCreateStatic(
|
||||
"MPM", MULTI_PROTOLIST_START_TIMEOUT / RTOS_MS_PER_TICK, pdTRUE,
|
||||
(void*)moduleIdx, MultiRfProtocols::timerCb, &scanTimer->timerBuffer);
|
||||
if (!timer_is_created(scanTimer)) {
|
||||
timer_create(scanTimer, MultiRfProtocols::timerCb, "mpm",
|
||||
MULTI_PROTOLIST_START_TIMEOUT, false);
|
||||
timer_start(scanTimer);
|
||||
} else {
|
||||
if (xTimerChangePeriod(scanTimer->timer,
|
||||
MULTI_PROTOLIST_START_TIMEOUT / RTOS_MS_PER_TICK,
|
||||
0) != pdPASS) {
|
||||
/* The timer period could not be reset. */
|
||||
}
|
||||
timer_set_period(scanTimer, MULTI_PROTOLIST_START_TIMEOUT);
|
||||
}
|
||||
|
||||
if (scanTimer->timer) {
|
||||
if( xTimerStart( scanTimer->timer, 0 ) != pdPASS ) {
|
||||
/* The timer could not be set into the Active state. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -291,32 +269,18 @@ bool MultiRfProtocols::scanReply(const uint8_t* packet, uint8_t len)
|
||||
}
|
||||
|
||||
currentProto++;
|
||||
lastScan = RTOS_GET_MS();
|
||||
lastScan = time_get_ms();
|
||||
|
||||
#if !defined(SIMU)
|
||||
auto scanTimer = &_protoScanTimers[moduleIdx];
|
||||
if (scanTimer->timer) {
|
||||
if (xTimerChangePeriod(scanTimer->timer,
|
||||
MULTI_PROTOLIST_TIMEOUT / RTOS_MS_PER_TICK,
|
||||
0) != pdPASS) {
|
||||
/* The timer period could not be reset. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
timer_set_period(scanTimer, MULTI_PROTOLIST_TIMEOUT);
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
scanState = ScanEnd;
|
||||
setModuleMode(moduleIdx, MODULE_MODE_NORMAL);
|
||||
|
||||
#if !defined(SIMU)
|
||||
auto scanTimer = &_protoScanTimers[moduleIdx];
|
||||
if (scanTimer->timer) {
|
||||
if (xTimerStop(scanTimer->timer, 0) != pdPASS) {
|
||||
/* The timer period could not be stopped. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
timer_stop(scanTimer);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -328,7 +292,7 @@ bool MultiRfProtocols::scanReply(const uint8_t* packet, uint8_t len)
|
||||
timeout = MULTI_PROTOLIST_START_TIMEOUT;
|
||||
}
|
||||
|
||||
if (RTOS_GET_MS() - lastScan >= timeout) {
|
||||
if (time_get_ms() - lastScan >= timeout) {
|
||||
TRACE("proto scan timeout!");
|
||||
scanState = ScanInvalid;
|
||||
}
|
||||
|
||||
@@ -22,17 +22,13 @@
|
||||
#include "dataconstants.h"
|
||||
#include "edgetx_types.h"
|
||||
|
||||
#include "os/timer.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#if !defined(SIMU)
|
||||
// Forward declare FreeRTOS timer
|
||||
struct tmrTimerControl;
|
||||
typedef struct tmrTimerControl * TimerHandle_t;
|
||||
#endif
|
||||
|
||||
class MultiRfProtocols
|
||||
{
|
||||
static MultiRfProtocols* _instance[NUM_MODULES];
|
||||
@@ -51,9 +47,7 @@ class MultiRfProtocols
|
||||
MultiRfProtocols(unsigned int moduleIdx);
|
||||
void fillBuiltinProtos();
|
||||
|
||||
#if !defined(SIMU)
|
||||
static void timerCb(TimerHandle_t xTimer);
|
||||
#endif
|
||||
static void timerCb(timer_handle_t* h);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
+19
-35
@@ -28,6 +28,9 @@
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/usb_driver.h"
|
||||
|
||||
#include "os/timer.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
#include "libopenui.h"
|
||||
#endif
|
||||
@@ -36,18 +39,11 @@ FIL g_oLogFile __DMA;
|
||||
uint8_t logDelay100ms;
|
||||
static tmr10ms_t lastLogTime = 0;
|
||||
|
||||
#if !defined(SIMU)
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
static timer_handle_t loggingTimer = TIMER_INITIALIZER;
|
||||
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
static TimerHandle_t loggingTimer = nullptr;
|
||||
static StaticTimer_t loggingTimerBuffer;
|
||||
|
||||
static void loggingTimerCb(TimerHandle_t xTimer)
|
||||
static void loggingTimerCb(timer_handle_t* timer)
|
||||
{
|
||||
(void)xTimer;
|
||||
(void)timer;
|
||||
if (mixerTaskRunning()) {
|
||||
DEBUG_TIMER_START(debugTimerLoggingWakeup);
|
||||
logsWrite();
|
||||
@@ -55,51 +51,39 @@ static void loggingTimerCb(TimerHandle_t xTimer)
|
||||
}
|
||||
}
|
||||
|
||||
void loggingTimerStart()
|
||||
void loggingTimerStart(uint32_t period)
|
||||
{
|
||||
if (!loggingTimer) {
|
||||
loggingTimer =
|
||||
xTimerCreateStatic("Logging", logDelay100ms*100 / RTOS_MS_PER_TICK, pdTRUE, (void*)0,
|
||||
loggingTimerCb, &loggingTimerBuffer);
|
||||
if (!timer_is_created(&loggingTimer)) {
|
||||
timer_create(&loggingTimer, loggingTimerCb, "logs", period, true);
|
||||
}
|
||||
|
||||
if (loggingTimer) {
|
||||
if( xTimerStart( loggingTimer, 0 ) != pdPASS ) {
|
||||
/* The timer could not be set into the Active state. */
|
||||
}
|
||||
}
|
||||
timer_start(&loggingTimer);
|
||||
}
|
||||
|
||||
void loggingTimerStop()
|
||||
void loggingTimerStop() { timer_stop(&loggingTimer); }
|
||||
|
||||
bool loggingTimerIsRunning()
|
||||
{
|
||||
if (loggingTimer) {
|
||||
if( xTimerStop( loggingTimer, 120 / RTOS_MS_PER_TICK ) != pdPASS ) {
|
||||
/* The timer could not be stopped. */
|
||||
}
|
||||
loggingTimer = nullptr;
|
||||
}
|
||||
return timer_is_active(&loggingTimer);
|
||||
}
|
||||
|
||||
void initLoggingTimer() { // called cyclically by main.cpp:perMain()
|
||||
void initLoggingTimer()
|
||||
{ // called cyclically by main.cpp:perMain()
|
||||
static uint8_t logDelay100msOld = 0;
|
||||
|
||||
if(loggingTimer == nullptr) { // log Timer not running
|
||||
if(!timer_is_active(&loggingTimer)) { // log Timer not running
|
||||
if(isFunctionActive(FUNCTION_LOGS) && logDelay100ms > 0) { // if SF Logging is active and log rate is valid
|
||||
loggingTimerStart(); // start log timer
|
||||
loggingTimerStart(logDelay100ms * 100); // start log timer
|
||||
}
|
||||
} else { // log timer is already running
|
||||
if(logDelay100msOld != logDelay100ms) { // if log rate was changed
|
||||
logDelay100msOld = logDelay100ms; // memorize new log rate
|
||||
|
||||
if(logDelay100ms > 0) {
|
||||
if(xTimerChangePeriod( loggingTimer, logDelay100ms*100, 0 ) != pdPASS ) { // and restart timer with new log rate
|
||||
/* The timer period could not be changed */
|
||||
}
|
||||
timer_set_period(&loggingTimer, logDelay100ms * 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void writeHeader();
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "touch.h"
|
||||
#include "view_main.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#define MAX_INSTRUCTIONS (20000 / 100)
|
||||
|
||||
@@ -117,11 +118,11 @@ void LuaEventHandler::event_cb(lv_event_t* e)
|
||||
_startX = rel_pos.x;
|
||||
_startY = rel_pos.y;
|
||||
|
||||
downTime = RTOS_GET_MS();
|
||||
downTime = time_get_ms();
|
||||
}
|
||||
} else if (code == LV_EVENT_RELEASED) {
|
||||
// tap count handling
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = time_get_ms();
|
||||
if (now - downTime <= LUA_TAP_TIME) {
|
||||
if (now - tapTime > LUA_TAP_TIME) {
|
||||
tapCount = 1;
|
||||
|
||||
+1
-7
@@ -465,9 +465,8 @@ void guiMain(event_t evt)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SIMU)
|
||||
// from logs.cpp
|
||||
void initLoggingTimer();
|
||||
#endif
|
||||
|
||||
void perMain()
|
||||
{
|
||||
@@ -477,12 +476,7 @@ void perMain()
|
||||
|
||||
if (!usbPlugged() || (getSelectedUsbMode() == USB_UNSELECTED_MODE)) {
|
||||
checkStorageUpdate();
|
||||
|
||||
#if !defined(SIMU) // use FreeRTOS software timer if radio firmware
|
||||
initLoggingTimer(); // initialize software timer for logging
|
||||
#else
|
||||
logsWrite(); // call logsWrite the old way for simu
|
||||
#endif
|
||||
}
|
||||
|
||||
handleUsbConnection();
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "mixer_scheduler.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "hal/usb_driver.h"
|
||||
|
||||
#include "dataconstants.h"
|
||||
#include <string.h>
|
||||
|
||||
bool mixerSchedulerWaitForTrigger(uint8_t timeoutMs)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
@@ -111,10 +113,10 @@ void mixerSchedulerISRTrigger()
|
||||
|
||||
/* At this point xTaskToNotify should not be NULL as
|
||||
a transmission was in progress. */
|
||||
configASSERT( mixerTaskId.rtos_handle != NULL );
|
||||
configASSERT( mixerTaskId._rtos_handle != NULL );
|
||||
|
||||
/* Notify the task that the transmission is complete. */
|
||||
vTaskNotifyGiveFromISR( mixerTaskId.rtos_handle,
|
||||
vTaskNotifyGiveFromISR( mixerTaskId._rtos_handle,
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef void (*async_func_t)(void* param1, uint32_t param2);
|
||||
|
||||
// schedule a function call for later
|
||||
// return true if the async call could be stacked, false otherwise
|
||||
bool async_call(async_func_t func, volatile bool* excl_flag, void* param1,
|
||||
uint32_t param2);
|
||||
|
||||
// schedule a function call for later (interrupt handler)
|
||||
bool async_call_isr(async_func_t func, volatile bool* excl_flag, void* param1,
|
||||
uint32_t param2);
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 "async.h"
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
|
||||
bool async_call(async_func_t func, volatile bool* excl_flag, void* param1,
|
||||
uint32_t param2)
|
||||
{
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
|
||||
// check exclusive flag first
|
||||
if (excl_flag && *excl_flag) return false;
|
||||
|
||||
BaseType_t xReturn = xTimerPendFunctionCall(func, param1, param2, 0);
|
||||
|
||||
// update exclusive flag if provided
|
||||
if (excl_flag && (xReturn == pdPASS)) *excl_flag = true;
|
||||
|
||||
return xReturn == pdPASS;
|
||||
}
|
||||
|
||||
func(param1, param2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool async_call_isr(async_func_t func, volatile bool* excl_flag, void* param1,
|
||||
uint32_t param2)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
|
||||
// check exclusive flag first
|
||||
if (excl_flag && *excl_flag) return false;
|
||||
|
||||
BaseType_t xReturn = xTimerPendFunctionCallFromISR(
|
||||
func, param1, param2, &xHigherPriorityTaskWoken);
|
||||
|
||||
// update exclusive flag if provided
|
||||
if (excl_flag && (xReturn == pdPASS)) *excl_flag = true;
|
||||
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
return xReturn == pdPASS;
|
||||
}
|
||||
|
||||
func(param1, param2);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 "async.h"
|
||||
#include "timer_pthread_impl.h"
|
||||
|
||||
bool async_call(async_func_t func, volatile bool* excl_flag, void* param1,
|
||||
uint32_t param2)
|
||||
{
|
||||
if (excl_flag && *excl_flag) return false;
|
||||
timer_queue::instance().pend_function(func, param1, param2);
|
||||
if (excl_flag) *excl_flag = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool async_call_isr(async_func_t func, volatile bool* excl_flag, void* param1,
|
||||
uint32_t param2)
|
||||
{
|
||||
return async_call(func, excl_flag, param1, param2);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "time.h"
|
||||
|
||||
void sleep_ms(uint32_t ms);
|
||||
void sleep_until(time_point_t* tp, uint32_t ts_ms);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 "sleep.h"
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/task.h>
|
||||
|
||||
void sleep_ms(uint32_t ms)
|
||||
{
|
||||
if (!ms) return;
|
||||
|
||||
ms /= portTICK_PERIOD_MS;
|
||||
if (!ms) ms = 1;
|
||||
|
||||
vTaskDelay(ms);
|
||||
}
|
||||
|
||||
void sleep_until(time_point_t* tp, uint32_t inc)
|
||||
{
|
||||
inc /= portTICK_PERIOD_MS;
|
||||
vTaskDelayUntil(tp, inc);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 "sleep.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
extern uint8_t simuSleep(uint32_t ms);
|
||||
|
||||
void sleep_ms(uint32_t ms)
|
||||
{
|
||||
simuSleep(ms);
|
||||
}
|
||||
|
||||
void sleep_until(time_point_t* tp, uint32_t inc)
|
||||
{
|
||||
*tp += std::chrono::duration<uint32_t, std::milli>{inc};
|
||||
std::this_thread::sleep_until(*tp);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 "sleep.h"
|
||||
|
||||
#include "timers_driver.h"
|
||||
|
||||
void sleep_ms(uint32_t ms)
|
||||
{
|
||||
if (!ms) return;
|
||||
|
||||
uint32_t timeout = timersGetMsTick();
|
||||
while (timersGetMsTick() - timeout < ms) {}
|
||||
}
|
||||
|
||||
void sleep_until(time_point_t* tp, uint32_t inc)
|
||||
{
|
||||
uint32_t start = *tp;
|
||||
*tp = start + inc;
|
||||
|
||||
while (timersGetMsTick() - start < inc) {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// OS specific implementation
|
||||
#if defined(POSIX_THREADS)
|
||||
#include "task_pthread.h"
|
||||
#elif defined(FREE_RTOS)
|
||||
#include "task_freertos.h"
|
||||
#endif
|
||||
|
||||
typedef void (*task_func_t)();
|
||||
|
||||
void task_create(task_handle_t* h, task_func_t func, const char* name,
|
||||
void* stack, unsigned stack_size, unsigned priority);
|
||||
|
||||
unsigned task_get_stack_usage(task_handle_t* h);
|
||||
unsigned task_get_stack_size(task_handle_t* h);
|
||||
|
||||
void mutex_create(mutex_handle_t* h);
|
||||
bool mutex_lock(mutex_handle_t* h);
|
||||
void mutex_unlock(mutex_handle_t* h);
|
||||
bool mutex_trylock(mutex_handle_t* h);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 "task.h"
|
||||
|
||||
static void _task_stub(void* p)
|
||||
{
|
||||
task_func_t func = (task_func_t)p;
|
||||
func();
|
||||
}
|
||||
|
||||
void task_create(task_handle_t* h, task_func_t func, const char* name,
|
||||
void* stack, unsigned stack_size, unsigned priority)
|
||||
{
|
||||
h->_stack_size = stack_size;
|
||||
h->_rtos_handle =
|
||||
xTaskCreateStatic(_task_stub, name, stack_size, (void*)func, priority,
|
||||
(StackType_t*)stack, &h->_task_struct);
|
||||
}
|
||||
|
||||
unsigned task_get_stack_usage(task_handle_t* h)
|
||||
{
|
||||
return uxTaskGetStackHighWaterMark(h->_rtos_handle);
|
||||
}
|
||||
|
||||
unsigned task_get_stack_size(task_handle_t* h)
|
||||
{
|
||||
return h->_stack_size * sizeof(StackType_t);
|
||||
}
|
||||
|
||||
void mutex_create(mutex_handle_t* h)
|
||||
{
|
||||
h->_rtos_handle = xSemaphoreCreateMutexStatic(&h->_mutex_struct);
|
||||
mutex_unlock(h);
|
||||
}
|
||||
|
||||
static inline bool _lock_mutex(mutex_handle_t* h, TickType_t xTickToWait)
|
||||
{
|
||||
return xSemaphoreTake(h->_rtos_handle, xTickToWait) == pdTRUE;
|
||||
}
|
||||
|
||||
bool mutex_lock(mutex_handle_t* h) { return _lock_mutex(h, portMAX_DELAY); }
|
||||
bool mutex_trylock(mutex_handle_t* h) { return _lock_mutex(h, (TickType_t)0); }
|
||||
void mutex_unlock(mutex_handle_t* h) { xSemaphoreGive(h->_rtos_handle); }
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/task.h>
|
||||
#include <FreeRTOS/include/semphr.h>
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
#define TASK_DEFINE_STACK(name, size) StackType_t __ALIGNED(8) name[size] __CCMRAM
|
||||
|
||||
struct task_handle_t {
|
||||
TaskHandle_t _rtos_handle;
|
||||
StaticTask_t _task_struct;
|
||||
uint32_t _stack_size;
|
||||
};
|
||||
|
||||
struct mutex_handle_t {
|
||||
SemaphoreHandle_t _rtos_handle;
|
||||
StaticSemaphore_t _mutex_struct;
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 "task.h"
|
||||
|
||||
static void* _task_stub(void* p)
|
||||
{
|
||||
task_func_t func = (task_func_t)p;
|
||||
func();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void task_create(task_handle_t* h, task_func_t func, const char* name,
|
||||
void* stack, unsigned stack_size, unsigned priority)
|
||||
{
|
||||
h->_stack_size = stack_size;
|
||||
pthread_create(&h->_thread_handle, nullptr, _task_stub, (void*)func);
|
||||
}
|
||||
|
||||
unsigned task_get_stack_usage(task_handle_t* h)
|
||||
{
|
||||
// fake...
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned task_get_stack_size(task_handle_t* h)
|
||||
{
|
||||
return h->_stack_size * 4;
|
||||
}
|
||||
|
||||
void mutex_create(mutex_handle_t* h)
|
||||
{
|
||||
*h = PTHREAD_MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
bool mutex_lock(mutex_handle_t* h)
|
||||
{
|
||||
return pthread_mutex_lock(h) == 0;
|
||||
}
|
||||
|
||||
void mutex_unlock(mutex_handle_t* h)
|
||||
{
|
||||
pthread_mutex_unlock(h);
|
||||
}
|
||||
|
||||
bool mutex_trylock(mutex_handle_t* h)
|
||||
{
|
||||
return pthread_mutex_trylock(h) == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
#define TASK_DEFINE_STACK(name, size) void* name
|
||||
|
||||
struct task_handle_t {
|
||||
pthread_t _thread_handle;
|
||||
uint32_t _stack_size;
|
||||
};
|
||||
|
||||
typedef pthread_mutex_t mutex_handle_t;
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// OS specific implementation
|
||||
#if defined(POSIX_THREADS)
|
||||
#include "time_native.h"
|
||||
#elif defined(FREE_RTOS)
|
||||
#include "time_freertos.h"
|
||||
#else
|
||||
#include "time_nortos.h"
|
||||
#endif
|
||||
|
||||
uint32_t time_get_ms();
|
||||
|
||||
time_point_t time_point_now();
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 "time.h"
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/task.h>
|
||||
|
||||
uint32_t time_get_ms()
|
||||
{
|
||||
return xTaskGetTickCount() / portTICK_PERIOD_MS;
|
||||
}
|
||||
|
||||
time_point_t time_point_now()
|
||||
{
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
|
||||
typedef TickType_t time_point_t;
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 "time.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
extern uint64_t simuTimerMicros(void);
|
||||
|
||||
uint32_t time_get_ms()
|
||||
{
|
||||
return simuTimerMicros() / 1000;
|
||||
}
|
||||
|
||||
time_point_t time_point_now()
|
||||
{
|
||||
return std::chrono::steady_clock::now();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::steady_clock> time_point_t;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 "time.h"
|
||||
|
||||
#include "timers_driver.h"
|
||||
|
||||
uint32_t time_get_ms()
|
||||
{
|
||||
return timersGetMsTick();
|
||||
}
|
||||
|
||||
time_point_t time_point_now()
|
||||
{
|
||||
return time_get_ms();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t time_point_t;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// OS specific implementation
|
||||
#if defined(POSIX_THREADS)
|
||||
#include "timer_pthread.h"
|
||||
#elif defined(FREE_RTOS)
|
||||
#include "timer_freertos.h"
|
||||
#endif
|
||||
|
||||
typedef void (*timer_func_t)(timer_handle_t*);
|
||||
|
||||
int timer_create(timer_handle_t* h, timer_func_t func, const char* name,
|
||||
unsigned period, bool repeat);
|
||||
|
||||
bool timer_is_created(timer_handle_t* h);
|
||||
bool timer_is_active(timer_handle_t* h);
|
||||
|
||||
int timer_start(timer_handle_t* h);
|
||||
int timer_stop(timer_handle_t* h);
|
||||
|
||||
int timer_set_period(timer_handle_t* h, unsigned period);
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 "timer.h"
|
||||
|
||||
static void _timer_cb(TimerHandle_t xTimer)
|
||||
{
|
||||
timer_handle_t* h = (timer_handle_t*)pvTimerGetTimerID(xTimer);
|
||||
if (h->_func) h->_func(h);
|
||||
}
|
||||
|
||||
int timer_create(timer_handle_t* h, timer_func_t func, const char* name,
|
||||
unsigned period, bool repeat)
|
||||
{
|
||||
if (h->_rtos_handle) return -1;
|
||||
h->_rtos_handle = xTimerCreateStatic(name, period / portTICK_PERIOD_MS,
|
||||
repeat ? pdTRUE : pdFALSE, (void*)h,
|
||||
_timer_cb, &h->_timer_struct);
|
||||
h->_func = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool timer_is_created(timer_handle_t* h)
|
||||
{
|
||||
return h->_rtos_handle != nullptr;
|
||||
}
|
||||
|
||||
bool timer_is_active(timer_handle_t* h)
|
||||
{
|
||||
return (h->_rtos_handle != nullptr) && (xTimerIsTimerActive(h->_rtos_handle));
|
||||
}
|
||||
|
||||
int timer_start(timer_handle_t* h)
|
||||
{
|
||||
if (!h->_rtos_handle) return -1;
|
||||
return xTimerStart(h->_rtos_handle, 0) == pdPASS ? 0 : -1;
|
||||
}
|
||||
|
||||
int timer_stop(timer_handle_t* h)
|
||||
{
|
||||
if (!h->_rtos_handle) return -1;
|
||||
return xTimerStop(h->_rtos_handle, 0) == pdPASS ? 0 : -1;
|
||||
}
|
||||
|
||||
int timer_set_period(timer_handle_t* h, unsigned period)
|
||||
{
|
||||
if (!h->_rtos_handle) return -1;
|
||||
return xTimerChangePeriod(h->_rtos_handle, period / portTICK_PERIOD_MS, 0) ==
|
||||
pdPASS
|
||||
? 0
|
||||
: -1;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
|
||||
struct timer_handle_t;
|
||||
|
||||
struct timer_handle_t {
|
||||
TimerHandle_t _rtos_handle;
|
||||
StaticTimer_t _timer_struct;
|
||||
void (*_func)(timer_handle_t*);
|
||||
};
|
||||
|
||||
#define TIMER_INITIALIZER { ._rtos_handle = nullptr }
|
||||
@@ -0,0 +1,215 @@
|
||||
#include "timer.h"
|
||||
#include "timer_pthread_impl.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
bool _timer_cmp(timer_handle_t *lh, timer_handle_t *rh) {
|
||||
return lh->next_trigger < rh->next_trigger;
|
||||
}
|
||||
|
||||
timer_queue::timer_queue() {}
|
||||
|
||||
void timer_queue::update_current_time() {
|
||||
_current_time = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void timer_queue::sort_timers() {
|
||||
std::sort(_timers.begin(), _timers.end(), _timer_cmp);
|
||||
}
|
||||
|
||||
timer_queue& timer_queue::instance()
|
||||
{
|
||||
static timer_queue _instance;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void timer_queue::start()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_cmds_mutex);
|
||||
if (!_running) {
|
||||
_running = true;
|
||||
_thread = std::make_unique<std::thread>([&]() { main_loop(); });
|
||||
}
|
||||
}
|
||||
|
||||
void timer_queue::stop() {
|
||||
bool stopping = false;
|
||||
|
||||
std::unique_lock<std::mutex> lock(_cmds_mutex);
|
||||
std::unique_lock<std::mutex> slock(_stop_mutex);
|
||||
|
||||
if (_running) {
|
||||
stopping = true;
|
||||
_running = false;
|
||||
lock.unlock();
|
||||
_cmds_condition.notify_one();
|
||||
_stop_condition.wait(slock);
|
||||
slock.unlock();
|
||||
}
|
||||
_thread->join();
|
||||
}
|
||||
|
||||
void timer_queue::create_timer(timer_handle_t *timer, timer_func_t func, const char *name,
|
||||
unsigned period, bool repeat) {
|
||||
timer->func = func;
|
||||
timer->name = name;
|
||||
timer->period = period;
|
||||
timer->repeat = repeat;
|
||||
timer->next_trigger = time_point_t{};
|
||||
}
|
||||
|
||||
void timer_queue::send_cmd(timer_req_t&& req)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(_cmds_mutex);
|
||||
_cmds.emplace_back(req);
|
||||
}
|
||||
_cmds_condition.notify_one();
|
||||
}
|
||||
|
||||
void timer_queue::start_timer(timer_handle_t *timer) {
|
||||
send_cmd(timer_req_t{.cmd = timer_req_t::cmd_start, .timer = timer});
|
||||
}
|
||||
|
||||
void timer_queue::stop_timer(timer_handle_t *timer) {
|
||||
send_cmd(timer_req_t{.cmd = timer_req_t::cmd_stop, .timer = timer});
|
||||
}
|
||||
|
||||
void timer_queue::pend_function(timer_async_func_t func, void *param1,
|
||||
uint32_t param2) {
|
||||
send_cmd(timer_req_t{
|
||||
.cmd = timer_req_t::cmd_pend_func,
|
||||
.func_call = {.func = func, .param1 = param1, .param2 = param2}});
|
||||
}
|
||||
|
||||
void timer_queue::main_loop() {
|
||||
|
||||
while (true) {
|
||||
{
|
||||
std::unique_lock lock(_cmds_mutex);
|
||||
time_point_t until;
|
||||
|
||||
update_current_time();
|
||||
process_cmds();
|
||||
|
||||
if (_timers.size() > 0) {
|
||||
timer_handle_t* t = _timers[0];
|
||||
until = t->next_trigger;
|
||||
} else {
|
||||
until = _current_time + std::chrono::milliseconds(1000);
|
||||
}
|
||||
|
||||
std::cv_status result = _cmds_condition.wait_until(lock, until);
|
||||
if (!_running) break;
|
||||
}
|
||||
|
||||
async_calls();
|
||||
trigger_timers();
|
||||
}
|
||||
|
||||
_stop_condition.notify_one();
|
||||
}
|
||||
|
||||
void timer_queue::process_cmds()
|
||||
{
|
||||
while (!_cmds.empty()) {
|
||||
timer_req_t req = _cmds.back();
|
||||
_cmds.pop_back();
|
||||
|
||||
if (req.cmd == timer_req_t::cmd_pend_func) {
|
||||
if (req.func_call.func) {
|
||||
_funcs.emplace_back(std::move(req.func_call));
|
||||
}
|
||||
} else {
|
||||
timer_handle_t *t = req.timer;
|
||||
auto pos = std::find(_timers.begin(), _timers.end(), t);
|
||||
switch (req.cmd) {
|
||||
case timer_req_t::cmd_start:
|
||||
t->next_trigger = _current_time + std::chrono::milliseconds(t->period);
|
||||
t->active = true;
|
||||
if (pos == _timers.end()) {
|
||||
_timers.emplace_back(t);
|
||||
}
|
||||
break;
|
||||
|
||||
case timer_req_t::cmd_stop:
|
||||
if (pos != _timers.end()) {
|
||||
_timers.erase(pos);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void timer_queue::trigger_timers() {
|
||||
int triggered = 0;
|
||||
for (auto t : _timers) {
|
||||
if (t->next_trigger <= _current_time) {
|
||||
if (t->repeat) {
|
||||
t->next_trigger += std::chrono::milliseconds(t->period);
|
||||
} else {
|
||||
t->active = false;
|
||||
stop_timer(t);
|
||||
}
|
||||
t->func(t);
|
||||
triggered++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (triggered) {
|
||||
sort_timers();
|
||||
}
|
||||
}
|
||||
|
||||
void timer_queue::async_calls() {
|
||||
for (auto f : _funcs) {
|
||||
f.func(f.param1, f.param2);
|
||||
}
|
||||
_funcs.clear();
|
||||
}
|
||||
|
||||
int timer_create(timer_handle_t* h, timer_func_t func, const char* name,
|
||||
unsigned period, bool repeat)
|
||||
{
|
||||
if (!h || !func) return -1;
|
||||
timer_queue::create_timer(h, func, name, period, repeat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool timer_is_created(timer_handle_t* h)
|
||||
{
|
||||
return h && h->func;
|
||||
}
|
||||
|
||||
bool timer_is_active(timer_handle_t* h)
|
||||
{
|
||||
return h && h->active;
|
||||
}
|
||||
|
||||
int timer_start(timer_handle_t* h)
|
||||
{
|
||||
if (!timer_is_created(h)) return -1;
|
||||
timer_queue::instance().start_timer(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_stop(timer_handle_t* h)
|
||||
{
|
||||
if (!timer_is_created(h)) return -1;
|
||||
timer_queue::instance().stop_timer(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_set_period(timer_handle_t *h, unsigned period)
|
||||
{
|
||||
if (!timer_is_created(h)) return -1;
|
||||
h->period = period;
|
||||
timer_queue::instance().start_timer(h);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "time.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
struct timer_handle_t;
|
||||
typedef void (*timer_func_t)(timer_handle_t*);
|
||||
typedef void (*timer_async_func_t)(void*, uint32_t);
|
||||
|
||||
using time_point = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
|
||||
struct timer_handle_t {
|
||||
timer_func_t func;
|
||||
const char* name;
|
||||
unsigned period;
|
||||
bool repeat;
|
||||
|
||||
time_point_t next_trigger;
|
||||
std::atomic_bool active;
|
||||
};
|
||||
|
||||
#define TIMER_INITIALIZER {}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "timer_pthread.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
struct timer_async_call_t {
|
||||
timer_async_func_t func;
|
||||
void *param1;
|
||||
uint32_t param2;
|
||||
};
|
||||
|
||||
struct timer_req_t {
|
||||
enum type {
|
||||
cmd_start,
|
||||
cmd_stop,
|
||||
cmd_pend_func,
|
||||
};
|
||||
|
||||
type cmd;
|
||||
|
||||
union {
|
||||
timer_handle_t *timer;
|
||||
timer_async_call_t func_call;
|
||||
};
|
||||
};
|
||||
|
||||
class timer_queue {
|
||||
|
||||
std::unique_ptr<std::thread> _thread;
|
||||
bool _running;
|
||||
|
||||
std::deque<timer_req_t> _cmds;
|
||||
std::mutex _cmds_mutex;
|
||||
std::condition_variable _cmds_condition;
|
||||
|
||||
std::mutex _stop_mutex;
|
||||
std::condition_variable _stop_condition;
|
||||
|
||||
std::vector<timer_handle_t*> _timers;
|
||||
std::vector<timer_async_call_t> _funcs;
|
||||
|
||||
time_point_t _current_time;
|
||||
|
||||
timer_queue();
|
||||
|
||||
void update_current_time();
|
||||
void sort_timers();
|
||||
void main_loop();
|
||||
void trigger_timers();
|
||||
void async_calls();
|
||||
void process_cmds();
|
||||
void send_cmd(timer_req_t&& req);
|
||||
|
||||
public:
|
||||
timer_queue(timer_queue const &) = delete;
|
||||
void operator=(timer_queue const &) = delete;
|
||||
|
||||
static timer_queue &instance();
|
||||
|
||||
static void create_timer(timer_handle_t *timer, timer_func_t func, const char *name,
|
||||
unsigned period, bool repeat);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void start_timer(timer_handle_t *timer);
|
||||
void stop_timer(timer_handle_t *timer);
|
||||
|
||||
void pend_function(timer_async_func_t func, void* param1, uint32_t param2);
|
||||
};
|
||||
+13
-16
@@ -25,7 +25,9 @@
|
||||
#include "mixer_scheduler.h"
|
||||
#include "heartbeat_driver.h"
|
||||
#include "hal/module_port.h"
|
||||
#include "os/sleep.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "os/async.h"
|
||||
|
||||
#include "pulses/pxx2.h"
|
||||
#include "pulses/flysky.h"
|
||||
@@ -106,7 +108,7 @@ void restartModule(uint8_t module)
|
||||
|
||||
// wait for the power output to be drained
|
||||
pulsesStopModule(module);
|
||||
RTOS_WAIT_MS(200);
|
||||
sleep_ms(200);
|
||||
|
||||
mixerTaskStart();
|
||||
}
|
||||
@@ -124,21 +126,21 @@ void pulsesRestartModuleUnsafe(uint8_t module)
|
||||
mod_drv->ctx = drv->init(module);
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
static volatile bool _module_restart_queued[NUM_MODULES] = {false};
|
||||
|
||||
static void _setup_async_module_restart(void* p1, uint32_t p2)
|
||||
{
|
||||
uint8_t module = (uint8_t)(uintptr_t)p1;
|
||||
_module_restart_queued[module] = false;
|
||||
|
||||
if (!mixerTaskTryLock()) {
|
||||
// In case the mixer cannot be locked, try again later
|
||||
// and make the same function pending again.
|
||||
PendedFunction_t cb = _setup_async_module_restart;
|
||||
xTimerPendFunctionCall(cb, p1, p2, 0/* do not wait */);
|
||||
async_call(_setup_async_module_restart, &_module_restart_queued[module], p1,
|
||||
p2);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t module = (uint8_t)(uintptr_t)p1;
|
||||
moduleState[module].forced_off = 1;
|
||||
|
||||
uint32_t timeout = p2;
|
||||
@@ -146,18 +148,13 @@ static void _setup_async_module_restart(void* p1, uint32_t p2)
|
||||
|
||||
mixerTaskUnlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
// return true if the request could be posted to the timer queue
|
||||
bool restartModuleAsync(uint8_t module, uint8_t cnt_delay)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
PendedFunction_t cb = _setup_async_module_restart;
|
||||
return xTimerPendFunctionCall(cb, (void*)(uintptr_t)module, cnt_delay,
|
||||
0/* do not wait */) == pdPASS;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
void* param1 = (void*)(uintptr_t)module;
|
||||
return async_call(_setup_async_module_restart,
|
||||
&_module_restart_queued[module], param1, cnt_delay);
|
||||
}
|
||||
|
||||
void pulsesModuleSettingsUpdate(uint8_t module)
|
||||
@@ -497,7 +494,7 @@ void pulsesStopModule(uint8_t module)
|
||||
while(_telemetryIsPolling) {
|
||||
// In case the telemetry timer is currently polling the port,
|
||||
// we give the timer task a chance to run and finish the polling.
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
}
|
||||
_deinit_module(module);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "io/frsky_firmware_update.h"
|
||||
#include "os/sleep.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
#include "pxx2_ota.h"
|
||||
@@ -37,7 +38,7 @@ bool Pxx2OtaUpdate::waitStep(uint8_t step, uint8_t timeout)
|
||||
if (elapsed++ > timeout) {
|
||||
return false;
|
||||
}
|
||||
RTOS_WAIT_MS(1);
|
||||
sleep_ms(1);
|
||||
telemetryWakeup();
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ void Pxx2OtaUpdate::flashFirmware(const char * filename, ProgressHandler progres
|
||||
mixerTaskStop();
|
||||
|
||||
watchdogSuspend(100 /*1s*/);
|
||||
RTOS_WAIT_MS(100);
|
||||
sleep_ms(100);
|
||||
|
||||
moduleState[module].mode = MODULE_MODE_OTA_UPDATE;
|
||||
const char * result = doFlashFirmware(filename, progressHandler);
|
||||
@@ -152,7 +153,7 @@ void Pxx2OtaUpdate::flashFirmware(const char * filename, ProgressHandler progres
|
||||
}
|
||||
|
||||
watchdogSuspend(100);
|
||||
RTOS_WAIT_MS(100);
|
||||
sleep_ms(100);
|
||||
|
||||
mixerTaskStart();
|
||||
}
|
||||
|
||||
+3
-249
@@ -32,200 +32,25 @@ extern "C++" {
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#define SIMU_SLEEP_OR_EXIT_MS(x) simuSleep(x)
|
||||
#define RTOS_MS_PER_TICK 1
|
||||
|
||||
typedef pthread_t RTOS_TASK_HANDLE;
|
||||
typedef pthread_mutex_t RTOS_MUTEX_HANDLE;
|
||||
|
||||
typedef uint32_t RTOS_FLAG_HANDLE;
|
||||
|
||||
typedef sem_t * RTOS_EVENT_HANDLE;
|
||||
|
||||
extern uint64_t simuTimerMicros(void);
|
||||
extern uint8_t simuSleep(uint32_t ms);
|
||||
|
||||
static inline void RTOS_START()
|
||||
{
|
||||
}
|
||||
|
||||
static inline void RTOS_WAIT_MS(uint32_t x)
|
||||
{
|
||||
simuSleep(x);
|
||||
}
|
||||
|
||||
static inline void RTOS_WAIT_TICKS(uint32_t x)
|
||||
{
|
||||
RTOS_WAIT_MS(x * RTOS_MS_PER_TICK);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
static inline void RTOS_CREATE_MUTEX(pthread_mutex_t &mutex)
|
||||
{
|
||||
mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
static inline bool RTOS_LOCK_MUTEX(pthread_mutex_t &mutex)
|
||||
{
|
||||
return pthread_mutex_lock(&mutex) == 0;
|
||||
}
|
||||
|
||||
static inline bool RTOS_TRYLOCK_MUTEX(pthread_mutex_t &mutex)
|
||||
{
|
||||
return pthread_mutex_trylock(&mutex) == 0;
|
||||
}
|
||||
|
||||
static inline void RTOS_UNLOCK_MUTEX(pthread_mutex_t &mutex)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
class TaskStack
|
||||
{
|
||||
public:
|
||||
TaskStack()
|
||||
{
|
||||
}
|
||||
|
||||
void paint()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t size()
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
uint32_t available()
|
||||
{
|
||||
return SIZE / 2;
|
||||
}
|
||||
};
|
||||
#define RTOS_DEFINE_STACK(taskHandle, name, size) TaskStack<size> name
|
||||
|
||||
#define TASK_FUNCTION(task) void* task(void *)
|
||||
|
||||
inline void RTOS_CREATE_TASK(pthread_t &taskId, void * (*task)(void *), const char * name)
|
||||
{
|
||||
pthread_create(&taskId, nullptr, task, nullptr);
|
||||
#ifdef __linux__
|
||||
pthread_setname_np(taskId, name);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <int SIZE>
|
||||
inline void RTOS_CREATE_TASK(pthread_t &taskId, void *(*task)(void *),
|
||||
const char *name, TaskStack<SIZE> &,
|
||||
unsigned size = 0, unsigned priority = 0)
|
||||
{
|
||||
(void)size;
|
||||
(void)priority;
|
||||
RTOS_CREATE_TASK(taskId, task, name);
|
||||
}
|
||||
|
||||
#define TASK_RETURN() return nullptr
|
||||
|
||||
constexpr uint32_t mainStackAvailable()
|
||||
static inline uint32_t mainStackAvailable()
|
||||
{
|
||||
return 500;
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// return 2ms resolution to match CoOS settings
|
||||
static inline uint32_t RTOS_GET_TIME(void)
|
||||
{
|
||||
return (uint32_t)(simuTimerMicros() / 2000);
|
||||
}
|
||||
|
||||
static inline uint32_t RTOS_GET_MS(void)
|
||||
{
|
||||
return (uint32_t)(simuTimerMicros() / 1000);
|
||||
}
|
||||
|
||||
#elif defined(FREE_RTOS)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/task.h>
|
||||
#include <FreeRTOS/include/semphr.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RTOS_MS_PER_TICK portTICK_PERIOD_MS
|
||||
|
||||
typedef struct {
|
||||
TaskHandle_t rtos_handle;
|
||||
StaticTask_t task_struct;
|
||||
} RTOS_TASK_HANDLE;
|
||||
|
||||
typedef struct {
|
||||
SemaphoreHandle_t rtos_handle;
|
||||
StaticSemaphore_t mutex_struct;
|
||||
} RTOS_MUTEX_HANDLE;
|
||||
|
||||
typedef RTOS_MUTEX_HANDLE RTOS_FLAG_HANDLE;
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/task.h>
|
||||
|
||||
static inline void RTOS_START()
|
||||
{
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
static inline void RTOS_WAIT_MS(uint32_t x)
|
||||
{
|
||||
if (!x)
|
||||
return;
|
||||
if ((x = x / RTOS_MS_PER_TICK) < 1)
|
||||
x = 1;
|
||||
|
||||
vTaskDelay(x);
|
||||
}
|
||||
|
||||
static inline void RTOS_WAIT_TICKS(uint32_t x)
|
||||
{
|
||||
vTaskDelay(x);
|
||||
}
|
||||
|
||||
static inline void _RTOS_CREATE_TASK(RTOS_TASK_HANDLE *h,
|
||||
TaskFunction_t pxTaskCode,
|
||||
const char *name,
|
||||
StackType_t *const puxStackBuffer,
|
||||
const uint32_t ulStackDepth,
|
||||
UBaseType_t uxPriority)
|
||||
{
|
||||
h->rtos_handle = xTaskCreateStatic(
|
||||
pxTaskCode, name, ulStackDepth, NULL, uxPriority,
|
||||
puxStackBuffer, &h->task_struct);
|
||||
}
|
||||
|
||||
#define RTOS_CREATE_TASK(h,task,name,stackStruct,stackSize,prio) \
|
||||
_RTOS_CREATE_TASK(&h,task,name,stackStruct.stack,stackSize,prio)
|
||||
|
||||
static inline void _RTOS_CREATE_MUTEX(RTOS_MUTEX_HANDLE* h)
|
||||
{
|
||||
h->rtos_handle = xSemaphoreCreateMutexStatic(&h->mutex_struct);
|
||||
xSemaphoreGive(h->rtos_handle);
|
||||
}
|
||||
|
||||
#define RTOS_CREATE_MUTEX(handle) _RTOS_CREATE_MUTEX(&handle)
|
||||
|
||||
static inline bool _RTOS_LOCK_MUTEX(RTOS_MUTEX_HANDLE* h, TickType_t xTickToWait)
|
||||
{
|
||||
return xSemaphoreTake(h->rtos_handle, xTickToWait) == pdTRUE;
|
||||
}
|
||||
|
||||
#define RTOS_LOCK_MUTEX(handle) _RTOS_LOCK_MUTEX(&handle, portMAX_DELAY)
|
||||
#define RTOS_TRYLOCK_MUTEX(handle) _RTOS_LOCK_MUTEX(&handle, (TickType_t)0)
|
||||
|
||||
static inline void _RTOS_UNLOCK_MUTEX(RTOS_MUTEX_HANDLE* h)
|
||||
{
|
||||
xSemaphoreGive(h->rtos_handle);
|
||||
}
|
||||
|
||||
#define RTOS_UNLOCK_MUTEX(handle) _RTOS_UNLOCK_MUTEX(&handle)
|
||||
|
||||
static inline uint32_t getStackAvailable(void * address, uint32_t size)
|
||||
{
|
||||
uint32_t * array = (uint32_t *)address;
|
||||
@@ -248,77 +73,6 @@ extern "C++" {
|
||||
return getStackAvailable(&_main_stack_start, stackSize());
|
||||
}
|
||||
|
||||
//#define RTOS_CREATE_FLAG(flag) flag = CoCreateFlag(false, false)
|
||||
//#define RTOS_SET_FLAG(flag) (void)CoSetFlag(flag)
|
||||
//#define RTOS_CLEAR_FLAG(flag) (void)CoClearFlag(flag)
|
||||
|
||||
// returns true if timeout
|
||||
static inline bool _RTOS_WAIT_FLAG(RTOS_FLAG_HANDLE* flag, uint32_t timeout)
|
||||
{
|
||||
return xSemaphoreTake(flag->rtos_handle, timeout * RTOS_MS_PER_TICK)
|
||||
== pdFALSE;
|
||||
}
|
||||
|
||||
#define RTOS_WAIT_FLAG(flag,timeout) _RTOS_WAIT_FLAG(&flag,timeout)
|
||||
|
||||
static inline void _RTOS_ISR_SET_FLAG(RTOS_FLAG_HANDLE* flag)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
// Give semaphore back from ISR to trigger a task waiting for it
|
||||
xSemaphoreGiveFromISR( flag->rtos_handle, &xHigherPriorityTaskWoken );
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to true we should yield
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
#define RTOS_ISR_SET_FLAG(flag) _RTOS_ISR_SET_FLAG(&flag)
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<int SIZE>
|
||||
class TaskStack
|
||||
{
|
||||
public:
|
||||
TaskStack(RTOS_TASK_HANDLE *h) {
|
||||
this->h = h;
|
||||
}
|
||||
|
||||
uint32_t size()
|
||||
{
|
||||
return SIZE * 4;
|
||||
}
|
||||
|
||||
uint32_t available()
|
||||
{
|
||||
return uxTaskGetStackHighWaterMark(h->rtos_handle);
|
||||
}
|
||||
|
||||
StackType_t stack[SIZE];
|
||||
protected:
|
||||
RTOS_TASK_HANDLE *h;
|
||||
};
|
||||
#endif // __cplusplus
|
||||
|
||||
static inline TickType_t RTOS_GET_TIME(void)
|
||||
{
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
||||
static inline uint32_t RTOS_GET_MS(void)
|
||||
{
|
||||
return (RTOS_GET_TIME() * RTOS_MS_PER_TICK);
|
||||
}
|
||||
|
||||
// stack must be aligned to 8 bytes otherwise printf for %f does not work!
|
||||
#define RTOS_DEFINE_STACK(taskHandle, name, size) TaskStack<size> __ALIGNED(8) name __CCMRAM (&taskHandle)
|
||||
|
||||
#define TASK_FUNCTION(task) void task(void *)
|
||||
#define TASK_RETURN() vTaskDelete(nullptr)
|
||||
|
||||
#else // no RTOS
|
||||
|
||||
#error "No RTOS implementation defined"
|
||||
|
||||
#endif // RTOS type
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+7
-6
@@ -37,6 +37,8 @@
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
#include "os/time.h"
|
||||
|
||||
#if LCD_W > 212
|
||||
#define LCD_ZOOM 1
|
||||
#else
|
||||
@@ -181,7 +183,6 @@ OpenTxSim::~OpenTxSim()
|
||||
TRACE("OpenTxSim::~OpenTxSim()");
|
||||
|
||||
simuStop();
|
||||
stopAudioThread();
|
||||
|
||||
delete bmp;
|
||||
delete sliders[0];
|
||||
@@ -520,7 +521,7 @@ long OpenTxSim::onTimeout(FXObject*, FXSelector, void*)
|
||||
|
||||
static uint32_t last_tick = 0;
|
||||
if (rotencAction) {
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = time_get_ms();
|
||||
uint32_t dt = now - last_tick;
|
||||
rotencDt += dt;
|
||||
last_tick = now;
|
||||
@@ -528,12 +529,11 @@ long OpenTxSim::onTimeout(FXObject*, FXSelector, void*)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(SIMU_BOOTLOADER)
|
||||
per10ms();
|
||||
#else
|
||||
#if defined(SIMU_BOOTLOADER)
|
||||
void interrupt10ms();
|
||||
interrupt10ms();
|
||||
#endif
|
||||
|
||||
refreshDisplay();
|
||||
getApp()->addTimeout(this, 2, 10);
|
||||
return 0;
|
||||
@@ -681,8 +681,9 @@ int main(int argc, char ** argv)
|
||||
printf("Model size = %d\n", (int)sizeof(g_model));
|
||||
|
||||
#if !defined(SIMU_BOOTLOADER)
|
||||
startAudioThread();
|
||||
startAudio();
|
||||
#endif
|
||||
|
||||
simuStart(true/*false*/, argc >= 3 ? argv[2] : 0, argc >= 4 ? argv[3] : 0);
|
||||
|
||||
return application.run();
|
||||
|
||||
@@ -20,13 +20,8 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
// #include <ctype.h>
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
#endif
|
||||
#include "os/timer.h"
|
||||
|
||||
struct spacemousedata_t
|
||||
{
|
||||
@@ -57,11 +52,9 @@ spacemousedata_t spacemouseData;
|
||||
|
||||
void spacemouseWakeup();
|
||||
|
||||
#if !defined(SIMU)
|
||||
static TimerHandle_t spacemouseTimer = nullptr;
|
||||
static StaticTimer_t spacemouseTimerBuffer;
|
||||
static timer_handle_t spacemouseTimer = TIMER_INITIALIZER;
|
||||
|
||||
static void spacemouseTimerCb(TimerHandle_t xTimer)
|
||||
static void spacemouseTimerCb(timer_handle_t* timer)
|
||||
{
|
||||
if (mixerTaskRunning()) {
|
||||
DEBUG_TIMER_START(debugTimerSpacemouseWakeup);
|
||||
@@ -73,28 +66,17 @@ static void spacemouseTimerCb(TimerHandle_t xTimer)
|
||||
|
||||
void spacemouseStart()
|
||||
{
|
||||
if (!spacemouseTimer) {
|
||||
spacemouseTimer =
|
||||
xTimerCreateStatic("SpaceM", 10 / RTOS_MS_PER_TICK, pdTRUE, (void*)0,
|
||||
spacemouseTimerCb, &spacemouseTimerBuffer);
|
||||
if (!timer_is_created(&spacemouseTimer)) {
|
||||
timer_create(&spacemouseTimer, spacemouseTimerCb, "spacem", 10, true);
|
||||
}
|
||||
|
||||
if (spacemouseTimer) {
|
||||
if( xTimerStart( spacemouseTimer, 0 ) != pdPASS ) {
|
||||
/* The timer could not be set into the Active state. */
|
||||
}
|
||||
}
|
||||
timer_start(&spacemouseTimer);
|
||||
}
|
||||
|
||||
void spacemouseStop()
|
||||
{
|
||||
if (spacemouseTimer) {
|
||||
if( xTimerStop( spacemouseTimer, 12 / RTOS_MS_PER_TICK ) != pdPASS ) {
|
||||
/* The timer could not be stopped. */
|
||||
}
|
||||
}
|
||||
timer_stop(&spacemouseTimer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void spacemouseParseNewData(uint8_t c)
|
||||
{
|
||||
@@ -155,9 +137,7 @@ void spacemouseSetSerialDriver(void* ctx, const etx_serial_driver_t* drv)
|
||||
spacemouseSerialCtx = ctx;
|
||||
spacemouseSerialDrv = drv;
|
||||
spaceMouseTelegram.parsestate = sm_bytetype::SM_START;
|
||||
#if !defined(SIMU)
|
||||
spacemouseStart();
|
||||
#endif
|
||||
}
|
||||
|
||||
int16_t get_spacemouse_value(uint8_t ch)
|
||||
|
||||
@@ -31,6 +31,7 @@ using std::list;
|
||||
#include "yaml/yaml_labelslist.h"
|
||||
#include "yaml/yaml_modelslist.h"
|
||||
#include "yaml/yaml_parser.h"
|
||||
#include "os/sleep.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
@@ -727,7 +728,7 @@ bool ModelMap::renameLabel(const std::string &from, std::string to,
|
||||
(uint8_t *)modeldata, 0) != NULL);
|
||||
}
|
||||
#if defined(SIMU)
|
||||
if (SIMU_SLEEP_OR_EXIT_MS(100)) break;
|
||||
sleep_ms(100);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "os/sleep.h"
|
||||
#include "timers_driver.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "mixes.h"
|
||||
@@ -76,8 +77,9 @@ void preModelLoad()
|
||||
LayoutFactory::deleteCustomScreens(true);
|
||||
#endif
|
||||
|
||||
if (needDelay)
|
||||
RTOS_WAIT_MS(200);
|
||||
if (needDelay) {
|
||||
sleep_ms(200);
|
||||
}
|
||||
}
|
||||
|
||||
void postRadioSettingsLoad()
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "myeeprom.h"
|
||||
#include "edgetx.h"
|
||||
#include "edgetx_constants.h"
|
||||
#include "os/sleep.h"
|
||||
#include "switches.h"
|
||||
#include "input_mapping.h"
|
||||
#include "inactivity_timer.h"
|
||||
@@ -1051,8 +1052,7 @@ void checkSwitches()
|
||||
checkBacklight();
|
||||
|
||||
WDG_RESET();
|
||||
|
||||
RTOS_WAIT_MS(10);
|
||||
sleep_ms(10);
|
||||
}
|
||||
|
||||
LED_ERROR_END();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "hal/gpio.h"
|
||||
#include "hal/audio_driver.h"
|
||||
|
||||
#include "os/sleep.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_timer.h"
|
||||
#include "stm32_dma.h"
|
||||
@@ -162,7 +163,7 @@ void audioUnmute()
|
||||
if (get_mute_pin()) {
|
||||
// ..un-mute
|
||||
set_mute_pin(false);
|
||||
RTOS_WAIT_MS(AUDIO_UNMUTE_DELAY);
|
||||
sleep_ms(AUDIO_UNMUTE_DELAY);
|
||||
}
|
||||
// reset the mute delay
|
||||
audioQueue.lastAudioPlayTime = 0;
|
||||
|
||||
@@ -6,6 +6,8 @@ AddHWGenTarget(${HW_DESC_JSON} hal_keys hal_keys.inc)
|
||||
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/hal_keys.inc
|
||||
${RADIO_SRC_DIR}/os/time_nortos.cpp
|
||||
${RADIO_SRC_DIR}/os/sleep_nortos.cpp
|
||||
${RADIO_SRC_DIR}/keys.cpp
|
||||
${RADIO_SRC_DIR}/strhelpers.cpp
|
||||
${RADIO_SRC_DIR}/stamp.cpp
|
||||
|
||||
@@ -135,6 +135,11 @@ void bootloaderInitApp()
|
||||
boardBLInit();
|
||||
}
|
||||
|
||||
#if defined(FIRMWARE_FORMAT_UF2)
|
||||
// make linker happy
|
||||
void per5ms() {}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
#else // SIMU
|
||||
void bootloaderInitApp() {}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#include "boot.h"
|
||||
#include "hal/usb_driver.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#include "lcd.h"
|
||||
|
||||
extern volatile uint8_t tenms;
|
||||
#define FRAME_INTERVAL_MS 20
|
||||
|
||||
void bootloaderDFU()
|
||||
{
|
||||
@@ -13,8 +15,11 @@ void bootloaderDFU()
|
||||
|
||||
bootloaderDrawDFUScreen();
|
||||
|
||||
uint32_t next_frame = time_get_ms();
|
||||
for (;;) {
|
||||
if (tenms) {
|
||||
if (time_get_ms() - next_frame >= FRAME_INTERVAL_MS) {
|
||||
next_frame += FRAME_INTERVAL_MS;
|
||||
|
||||
if (!usbPlugged()) break;
|
||||
bootloaderDrawDFUScreen();
|
||||
lcdRefresh();
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#include "lcd.h"
|
||||
|
||||
#define FRAME_INTERVAL_MS 20
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
#define MAIN_MENU_LEN 3
|
||||
#else
|
||||
@@ -17,16 +20,8 @@
|
||||
#define SEL_CLEAR_FLASH_STORAGE_MENU_LEN 2
|
||||
#endif
|
||||
|
||||
volatile tmr10ms_t g_tmr10ms;
|
||||
volatile uint8_t tenms = 1;
|
||||
|
||||
void per5ms() {} // make linker happy
|
||||
|
||||
void per10ms()
|
||||
void pollInputs()
|
||||
{
|
||||
tenms |= 1u; // 10 mS has passed
|
||||
g_tmr10ms++;
|
||||
|
||||
keysPollingCycle();
|
||||
|
||||
// TODO: use rotaryEncoderPollingCycle() instead
|
||||
@@ -42,6 +37,13 @@ void per10ms()
|
||||
#endif
|
||||
}
|
||||
|
||||
// poll inputs every 10ms
|
||||
void per5ms()
|
||||
{
|
||||
static uint32_t cnt = 0;
|
||||
if (++cnt & 1) { pollInputs(); }
|
||||
}
|
||||
|
||||
FlashCheckRes valid;
|
||||
|
||||
int menuFlashFile(uint32_t index, event_t event)
|
||||
@@ -74,10 +76,12 @@ void bootloaderMenu()
|
||||
|
||||
sdInit();
|
||||
|
||||
uint32_t next_frame = time_get_ms();
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (tenms) {
|
||||
tenms = 0;
|
||||
if (time_get_ms() - next_frame >= FRAME_INTERVAL_MS) {
|
||||
next_frame += FRAME_INTERVAL_MS;
|
||||
|
||||
if (state != ST_USB && state != ST_FLASHING
|
||||
&& state != ST_FLASH_DONE && state != ST_RADIO_MENU) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/storage.h"
|
||||
#include "hal/fatfs_diskio.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#include "thirdparty/FatFs/diskio.h"
|
||||
#include "drivers/uf2_ghostfat.h"
|
||||
@@ -10,19 +11,10 @@
|
||||
#include "board.h"
|
||||
#include "lcd.h"
|
||||
|
||||
#define FRAME_INTERVAL_MS 20
|
||||
|
||||
extern uf2_fat_write_state_t _uf2_write_state;
|
||||
|
||||
volatile tmr10ms_t g_tmr10ms;
|
||||
volatile uint8_t tenms = 1;
|
||||
|
||||
void per5ms() {} // make linker happy
|
||||
|
||||
void per10ms()
|
||||
{
|
||||
tenms |= 1u; // 10 mS has passed
|
||||
g_tmr10ms++;
|
||||
}
|
||||
|
||||
void bootloaderUF2()
|
||||
{
|
||||
BootloaderState state = ST_START;
|
||||
@@ -31,10 +23,12 @@ void bootloaderUF2()
|
||||
storageInit();
|
||||
disk_initialize(0);
|
||||
|
||||
uint32_t next_frame = time_get_ms();
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (tenms) {
|
||||
tenms = 0;
|
||||
if (time_get_ms() - next_frame >= FRAME_INTERVAL_MS) {
|
||||
next_frame += FRAME_INTERVAL_MS;
|
||||
|
||||
if (state != ST_USB && state != ST_FLASHING && state != ST_FLASH_DONE) {
|
||||
if (usbPlugged()) {
|
||||
|
||||
@@ -137,7 +137,7 @@ void rotaryEncoderCheck()
|
||||
rotenc_t diff = (value - last_value);
|
||||
|
||||
if (diff != 0) {
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = timersGetMsTick();
|
||||
uint32_t dt = now - last_tick;
|
||||
// pre-compute accumulated dt (dx/dt is done later in LVGL driver)
|
||||
rotencDt += dt;
|
||||
|
||||
@@ -100,8 +100,6 @@ static inline void _interrupt_1ms()
|
||||
watchdogTimeout -= 1;
|
||||
WDG_RESET(); // Retrigger hardware watchdog
|
||||
}
|
||||
|
||||
per10ms();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "vs1053b.h"
|
||||
|
||||
#include "os/sleep.h"
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "stm32_gpio.h"
|
||||
@@ -327,7 +328,7 @@ static void vs1053b_unmute()
|
||||
if (_is_muted) {
|
||||
// ..un-mute
|
||||
_set_mute_pin(false);
|
||||
RTOS_WAIT_MS(_instance->unmute_delay_ms);
|
||||
sleep_ms(_instance->unmute_delay_ms);
|
||||
}
|
||||
// reset the mute delay
|
||||
_last_play_ts = 0;
|
||||
|
||||
@@ -42,8 +42,8 @@ volatile static bool touchEventOccured;
|
||||
|
||||
static tc_handle_TypeDef tc_handle = {0, 0};
|
||||
|
||||
tmr10ms_t downTime = 0;
|
||||
tmr10ms_t tapTime = 0;
|
||||
uint32_t downTime = 0;
|
||||
uint32_t tapTime = 0;
|
||||
short tapCount = 0;
|
||||
#define TAP_TIME 250 // ms
|
||||
|
||||
@@ -251,7 +251,7 @@ TouchState touchPanelRead()
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
tmr10ms_t now = RTOS_GET_MS();
|
||||
uint32_t now = timersGetMsTick();
|
||||
internalTouchState.tapCount = 0;
|
||||
|
||||
if (cst836u_TS_DetectTouch()) {
|
||||
|
||||
@@ -29,10 +29,11 @@
|
||||
#include "stm32_exti_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "timers_driver.h"
|
||||
#include "tp_gt911.h"
|
||||
#include "delays_driver.h"
|
||||
|
||||
#include "rtos.h"
|
||||
#include "os/sleep.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "debug.h"
|
||||
|
||||
@@ -651,7 +652,7 @@ struct TouchState touchPanelRead()
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
uint32_t startReadStatus = RTOS_GET_MS();
|
||||
uint32_t startReadStatus = timersGetMsTick();
|
||||
do {
|
||||
if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG, &state, 1)) {
|
||||
// ledRed();
|
||||
@@ -665,15 +666,15 @@ struct TouchState touchPanelRead()
|
||||
// ready
|
||||
break;
|
||||
}
|
||||
RTOS_WAIT_MS(1);
|
||||
} while (RTOS_GET_MS() - startReadStatus < GT911_TIMEOUT);
|
||||
sleep_ms(1);
|
||||
} while (timersGetMsTick() - startReadStatus < GT911_TIMEOUT);
|
||||
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
TRACE("touch state = 0x%x", state);
|
||||
if (state & 0x80u) {
|
||||
uint8_t pointsCount = (state & 0x0Fu);
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = timersGetMsTick();
|
||||
internalTouchState.tapCount = 0;
|
||||
|
||||
if (pointsCount > 0 && pointsCount <= GT911_MAX_TP) {
|
||||
|
||||
@@ -7,7 +7,6 @@ endif()
|
||||
|
||||
set(SIMU_DRIVERS
|
||||
simpgmspace.cpp
|
||||
simueeprom.cpp
|
||||
simufatfs.cpp
|
||||
simudisk.cpp
|
||||
simulcd.cpp
|
||||
@@ -186,7 +185,7 @@ if(FOX_FOUND)
|
||||
|
||||
target_include_directories(simu PUBLIC ${FOX_INCLUDE_DIR} )
|
||||
target_link_libraries(simu ${FOX_LIBRARY} pthread ${SDL2_LIBRARIES})
|
||||
target_compile_options(simu PRIVATE -DSIMU)
|
||||
target_compile_options(simu PRIVATE ${SIMU_SRC_OPTIONS})
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QElapsedTimer>
|
||||
@@ -282,9 +283,9 @@ void OpenTxSimulator::start(const char * filename, bool tests)
|
||||
|
||||
QMutexLocker lckr(&m_mtxSimuMain);
|
||||
QMutexLocker slckr(&m_mtxSettings);
|
||||
startEepromThread(filename);
|
||||
startAudioThread(volumeGain);
|
||||
simuStart(tests, simuSdDirectory.toLatin1().constData(), simuSettingsDirectory.toLatin1().constData());
|
||||
startAudio(volumeGain);
|
||||
simuStart(tests, simuSdDirectory.toLatin1().constData(),
|
||||
simuSettingsDirectory.toLatin1().constData());
|
||||
|
||||
emit started();
|
||||
QTimer::singleShot(0, this, SLOT(run())); // old style for Qt < 5.4
|
||||
@@ -300,8 +301,6 @@ void OpenTxSimulator::stop()
|
||||
|
||||
QMutexLocker lckr(&m_mtxSimuMain);
|
||||
simuStop();
|
||||
stopAudioThread();
|
||||
stopEepromThread();
|
||||
|
||||
emit stopped();
|
||||
}
|
||||
@@ -321,20 +320,20 @@ void OpenTxSimulator::setVolumeGain(const int value)
|
||||
|
||||
void OpenTxSimulator::setRadioData(const QByteArray & data)
|
||||
{
|
||||
#if defined(EEPROM_SIZE)
|
||||
QMutexLocker lckr(&m_mtxRadioData);
|
||||
eeprom = (uint8_t *)malloc(qMin<int>(EEPROM_SIZE, data.size()));
|
||||
memcpy(eeprom, data.data(), qMin<int>(EEPROM_SIZE, data.size()));
|
||||
#endif
|
||||
// #if defined(EEPROM_SIZE)
|
||||
// QMutexLocker lckr(&m_mtxRadioData);
|
||||
// eeprom = (uint8_t *)malloc(qMin<int>(EEPROM_SIZE, data.size()));
|
||||
// memcpy(eeprom, data.data(), qMin<int>(EEPROM_SIZE, data.size()));
|
||||
// #endif
|
||||
}
|
||||
|
||||
void OpenTxSimulator::readRadioData(QByteArray & dest)
|
||||
{
|
||||
#if defined(EEPROM_SIZE)
|
||||
QMutexLocker lckr(&m_mtxRadioData);
|
||||
if (eeprom)
|
||||
memcpy(dest.data(), eeprom, qMin<int>(EEPROM_SIZE, dest.size()));
|
||||
#endif
|
||||
// #if defined(EEPROM_SIZE)
|
||||
// QMutexLocker lckr(&m_mtxRadioData);
|
||||
// if (eeprom)
|
||||
// memcpy(dest.data(), eeprom, qMin<int>(EEPROM_SIZE, dest.size()));
|
||||
// #endif
|
||||
}
|
||||
|
||||
uint8_t * OpenTxSimulator::getLcd()
|
||||
@@ -428,7 +427,7 @@ void OpenTxSimulator::rotaryEncoderEvent(int steps)
|
||||
steps *= -1;
|
||||
rotencValue += steps * ROTARY_ENCODER_GRANULARITY;
|
||||
// TODO: set rotencDt
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = time_get_ms();
|
||||
uint32_t dt = now - last_tick;
|
||||
rotencDt += dt;
|
||||
last_tick = now;
|
||||
@@ -771,8 +770,6 @@ void OpenTxSimulator::run()
|
||||
|
||||
++loops;
|
||||
|
||||
per10ms();
|
||||
|
||||
checkLcdChanged();
|
||||
|
||||
if (!(loops % 5)) {
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/audio_driver.h"
|
||||
|
||||
#include "os/task.h"
|
||||
#include "os/timer_pthread_impl.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
@@ -211,6 +214,7 @@ void simuStart(bool tests, const char * sdPath, const char * settingsPath)
|
||||
lcdInit();
|
||||
|
||||
#if !defined(SIMU_BOOTLOADER)
|
||||
timer_queue::instance().start();
|
||||
simuMain();
|
||||
#else
|
||||
pthread_attr_t attr;
|
||||
@@ -232,8 +236,8 @@ void simuStart(bool tests, const char * sdPath, const char * settingsPath)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern RTOS_TASK_HANDLE mixerTaskId;
|
||||
extern RTOS_TASK_HANDLE menusTaskId;
|
||||
extern task_handle_t mixerTaskId;
|
||||
extern task_handle_t menusTaskId;
|
||||
|
||||
void simuStop()
|
||||
{
|
||||
@@ -242,8 +246,12 @@ void simuStop()
|
||||
|
||||
simu_shutdown = true;
|
||||
|
||||
pthread_join(mixerTaskId, nullptr);
|
||||
pthread_join(menusTaskId, nullptr);
|
||||
pthread_join(mixerTaskId._thread_handle, nullptr);
|
||||
pthread_join(menusTaskId._thread_handle, nullptr);
|
||||
|
||||
#if defined(SIMU_AUDIO)
|
||||
stopAudio();
|
||||
#endif
|
||||
|
||||
simu_running = false;
|
||||
}
|
||||
@@ -253,8 +261,6 @@ struct SimulatorAudio {
|
||||
int currentVolume;
|
||||
int16_t leftoverData[AUDIO_BUFFER_SIZE];
|
||||
int leftoverLen;
|
||||
bool threadRunning;
|
||||
pthread_t threadPid;
|
||||
} simuAudio;
|
||||
|
||||
bool simuIsRunning()
|
||||
@@ -264,10 +270,9 @@ bool simuIsRunning()
|
||||
|
||||
uint8_t simuSleep(uint32_t ms)
|
||||
{
|
||||
for (uint32_t i = 0; i < ms; ++i){
|
||||
if (simu_shutdown || !simu_running)
|
||||
return 1;
|
||||
sleep(1);
|
||||
for (uint32_t i = 0; i < ms; i++) {
|
||||
if (simu_shutdown || !simu_running) return 1;
|
||||
usleep(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -336,77 +341,44 @@ void fillAudioBuffer(void *udata, Uint8 *stream, int len)
|
||||
}
|
||||
}
|
||||
|
||||
//fill the rest of buffer with silence
|
||||
// fill the rest of buffer with silence
|
||||
if (len > 0) {
|
||||
SDL_memset(stream, 0x8000, len); // make sure this is silence.
|
||||
// putchar('.');
|
||||
}
|
||||
}
|
||||
|
||||
void * audioThread(void *)
|
||||
int startAudio(int volumeGain)
|
||||
{
|
||||
/*
|
||||
Checking here if SDL audio was initialized is wrong, because
|
||||
the SDL_CloseAudio() de-initializes it.
|
||||
simuAudio = {
|
||||
.volumeGain = volumeGain,
|
||||
.leftoverLen = 0,
|
||||
};
|
||||
|
||||
if ( !SDL_WasInit(SDL_INIT_AUDIO) ) {
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL audio support\n");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
SDL_AudioSpec wanted, have;
|
||||
|
||||
/* Set the audio format */
|
||||
wanted.freq = AUDIO_SAMPLE_RATE;
|
||||
wanted.format = AUDIO_S16SYS;
|
||||
wanted.channels = 1; /* 1 = mono, 2 = stereo */
|
||||
wanted.samples =
|
||||
AUDIO_BUFFER_SIZE * 2; /* Good low-latency value for callback */
|
||||
wanted.callback = fillAudioBuffer;
|
||||
wanted.userdata = nullptr;
|
||||
|
||||
/*
|
||||
SDL_OpenAudio() internally calls SDL_InitSubSystem(SDL_INIT_AUDIO),
|
||||
which initializes SDL Audio subsystem if necessary
|
||||
*/
|
||||
if ( SDL_OpenAudio(&wanted, &have) < 0 ) {
|
||||
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
|
||||
return nullptr;
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
while (simuAudio.threadRunning) {
|
||||
audioQueue.wakeup();
|
||||
sleep(1);
|
||||
}
|
||||
SDL_CloseAudio();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void startAudioThread(int volumeGain)
|
||||
{
|
||||
simuAudio.leftoverLen = 0;
|
||||
simuAudio.threadRunning = true;
|
||||
simuAudio.volumeGain = volumeGain;
|
||||
TRACE_SIMPGMSPACE("startAudioThread(%d)", volumeGain);
|
||||
TRACE("startAudioThread(%d)", volumeGain);
|
||||
audioSetVolume(VOLUME_LEVEL_DEF);
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
struct sched_param sp;
|
||||
sp.sched_priority = SCHED_RR;
|
||||
pthread_attr_setschedparam(&attr, &sp);
|
||||
pthread_create(&simuAudio.threadPid, &attr, &audioThread, nullptr);
|
||||
#ifdef __linux__
|
||||
pthread_setname_np(simuAudio.threadPid, "audio");
|
||||
#endif
|
||||
/* Set the audio format */
|
||||
SDL_AudioSpec desired = {
|
||||
.freq = AUDIO_SAMPLE_RATE,
|
||||
.format = AUDIO_S16SYS,
|
||||
.channels = 1,
|
||||
.samples = AUDIO_BUFFER_SIZE * 2,
|
||||
.callback = fillAudioBuffer,
|
||||
.userdata = nullptr,
|
||||
};
|
||||
|
||||
SDL_AudioSpec obtained;
|
||||
if ( SDL_OpenAudio(&desired, &obtained) < 0 ) {
|
||||
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stopAudioThread()
|
||||
void stopAudio()
|
||||
{
|
||||
simuAudio.threadRunning = false;
|
||||
pthread_join(simuAudio.threadPid, nullptr);
|
||||
SDL_CloseAudio();
|
||||
}
|
||||
#endif // #if defined(SIMU_AUDIO)
|
||||
|
||||
@@ -675,6 +647,3 @@ struct TouchState getInternalTouchState()
|
||||
return simTouchState;
|
||||
}
|
||||
#endif
|
||||
|
||||
void telemetryStart() {}
|
||||
void telemetryStop() {}
|
||||
|
||||
@@ -30,17 +30,11 @@
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
|
||||
// #undef min
|
||||
// #undef max
|
||||
|
||||
extern uint8_t * eeprom;
|
||||
|
||||
#define __disable_irq()
|
||||
#define __enable_irq()
|
||||
|
||||
extern char * main_thread_error;
|
||||
|
||||
|
||||
uint64_t simuTimerMicros(void);
|
||||
uint8_t simuSleep(uint32_t ms); // returns true if thread shutdown requested
|
||||
|
||||
@@ -57,21 +51,16 @@ void startEepromThread(const char * filename = "eeprom.bin");
|
||||
void stopEepromThread();
|
||||
|
||||
#if defined(SIMU_AUDIO)
|
||||
void startAudioThread(int volumeGain = 10);
|
||||
void stopAudioThread(void);
|
||||
int startAudio(int volumeGain = 10);
|
||||
void stopAudio();
|
||||
#else
|
||||
#define startAudioThread(dummy)
|
||||
#define stopAudioThread()
|
||||
#define startAudio(dummy) (-1)
|
||||
#define stopAudio()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void simuMain();
|
||||
|
||||
|
||||
// inline void delay_01us(uint32_t dummy) { }
|
||||
|
||||
#define configure_pins(...)
|
||||
|
||||
#if !defined(SKIP_FATFS_DECLARATION) && !defined(SIMU_DISKIO)
|
||||
#define SIMU_USE_SDCARD
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "os/sleep.h"
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
@@ -32,6 +33,7 @@
|
||||
#include "hal.h"
|
||||
|
||||
#include "stm32h7rsxx_hal_gpio.h"
|
||||
#include "timers_driver.h"
|
||||
#include "tp_gt911.h"
|
||||
#include "delays_driver.h"
|
||||
|
||||
@@ -215,7 +217,7 @@ struct TouchState touchPanelRead()
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
uint32_t startReadStatus = RTOS_GET_MS();
|
||||
uint32_t startReadStatus = timersGetMsTick();
|
||||
do {
|
||||
if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG, &state, 1)) {
|
||||
// ledRed();
|
||||
@@ -229,15 +231,15 @@ struct TouchState touchPanelRead()
|
||||
// ready
|
||||
break;
|
||||
}
|
||||
RTOS_WAIT_MS(1);
|
||||
} while (RTOS_GET_MS() - startReadStatus < GT911_TIMEOUT);
|
||||
sleep_ms(1);
|
||||
} while (timersGetMsTick() - startReadStatus < GT911_TIMEOUT);
|
||||
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
TRACE("touch state = 0x%x", state);
|
||||
if (state & 0x80u) {
|
||||
uint8_t pointsCount = (state & 0x0Fu);
|
||||
uint32_t now = RTOS_GET_MS();
|
||||
uint32_t now = timersGetMsTick();
|
||||
internalTouchState.tapCount = 0;
|
||||
|
||||
if (pointsCount > 0 && pointsCount <= GT911_MAX_TP) {
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
*/
|
||||
|
||||
#include "bsp_io.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "drivers/pca95xx.h"
|
||||
#include "os/async.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "timers_driver.h"
|
||||
#include "stm32_ws2812.h"
|
||||
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "drivers/pca95xx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "myeeprom.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "stm32_ws2812.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
struct bsp_io_expander {
|
||||
pca95xx_t exp;
|
||||
@@ -58,30 +58,18 @@ static uint32_t _read_io_expander(bsp_io_expander* io)
|
||||
return io->state;
|
||||
}
|
||||
|
||||
static void _poll_switches(void *pvParameter1, uint32_t ulParameter2)
|
||||
static void _poll_switches(void *param1, uint32_t param2)
|
||||
{
|
||||
(void)ulParameter2;
|
||||
(void)param1;
|
||||
(void)param2;
|
||||
_poll_switches_in_queue = false;
|
||||
bsp_io_read_switches();
|
||||
bsp_io_read_fs_switches();
|
||||
_read_io_expander(&_io_switches);
|
||||
_read_io_expander(&_io_fs_switches);
|
||||
}
|
||||
|
||||
static void _io_int_handler()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
if (!_poll_switches_in_queue && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
xReturn = xTimerPendFunctionCallFromISR(_poll_switches, nullptr, 0,
|
||||
&xHigherPriorityTaskWoken);
|
||||
|
||||
if (xReturn == pdPASS) {
|
||||
_poll_switches_in_queue = true;
|
||||
} else {
|
||||
TRACE("xTimerPendFunctionCallFromISR() queue full");
|
||||
}
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
async_call_isr(_poll_switches, &_poll_switches_in_queue, nullptr, 0);
|
||||
}
|
||||
|
||||
int bsp_io_init()
|
||||
|
||||
+60
-25
@@ -19,7 +19,12 @@
|
||||
* 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"
|
||||
@@ -32,23 +37,23 @@
|
||||
#include "startup_shutdown.h"
|
||||
#endif
|
||||
|
||||
RTOS_TASK_HANDLE menusTaskId;
|
||||
RTOS_DEFINE_STACK(menusTaskId, menusStack, MENUS_STACK_SIZE);
|
||||
task_handle_t menusTaskId;
|
||||
TASK_DEFINE_STACK(menusStack, MENUS_STACK_SIZE);
|
||||
|
||||
#if defined(AUDIO)
|
||||
RTOS_TASK_HANDLE audioTaskId;
|
||||
RTOS_DEFINE_STACK(audioTaskId, audioStack, AUDIO_STACK_SIZE);
|
||||
task_handle_t audioTaskId;
|
||||
TASK_DEFINE_STACK(audioStack, AUDIO_STACK_SIZE);
|
||||
#endif
|
||||
|
||||
RTOS_MUTEX_HANDLE audioMutex;
|
||||
mutex_handle_t audioMutex;
|
||||
|
||||
#define MENU_TASK_PERIOD_TICKS (50 / RTOS_MS_PER_TICK) // 50ms
|
||||
#define MENU_TASK_PERIOD (50) // 50ms
|
||||
|
||||
#if defined(COLORLCD) && defined(CLI)
|
||||
bool perMainEnabled = true;
|
||||
#endif
|
||||
|
||||
TASK_FUNCTION(menusTask)
|
||||
static void menusTask()
|
||||
{
|
||||
#if defined(LIBOPENUI)
|
||||
LvglWrapper::instance();
|
||||
@@ -63,15 +68,14 @@ TASK_FUNCTION(menusTask)
|
||||
uint32_t pwr_check = pwrCheck();
|
||||
if (pwr_check == e_power_off) {
|
||||
break;
|
||||
}
|
||||
else if (pwr_check == e_power_press) {
|
||||
RTOS_WAIT_TICKS(MENU_TASK_PERIOD_TICKS);
|
||||
} else if (pwr_check == e_power_press) {
|
||||
sleep_ms(MENU_TASK_PERIOD);
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
while (pwrCheck() != e_power_off) {
|
||||
#endif
|
||||
uint32_t start = (uint32_t)RTOS_GET_TIME();
|
||||
time_point_t next_tick = time_point_now();
|
||||
DEBUG_TIMER_START(debugTimerPerMain);
|
||||
#if defined(COLORLCD) && defined(CLI)
|
||||
if (perMainEnabled) {
|
||||
@@ -81,14 +85,8 @@ TASK_FUNCTION(menusTask)
|
||||
perMain();
|
||||
#endif
|
||||
DEBUG_TIMER_STOP(debugTimerPerMain);
|
||||
// TODO remove completely massstorage from sky9x firmware
|
||||
uint32_t runtime = ((uint32_t)RTOS_GET_TIME() - start);
|
||||
// deduct the thread run-time from the wait, if run-time was more than
|
||||
// desired period, then skip the wait all together
|
||||
if (runtime < MENU_TASK_PERIOD_TICKS) {
|
||||
RTOS_WAIT_TICKS(MENU_TASK_PERIOD_TICKS - runtime);
|
||||
}
|
||||
|
||||
sleep_until(&next_tick, MENU_TASK_PERIOD);
|
||||
resetForcePowerOffRequest();
|
||||
}
|
||||
|
||||
@@ -99,24 +97,61 @@ TASK_FUNCTION(menusTask)
|
||||
drawSleepBitmap();
|
||||
edgeTxClose();
|
||||
boardOff();
|
||||
}
|
||||
|
||||
TASK_RETURN();
|
||||
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 (true) {
|
||||
DEBUG_TIMER_SAMPLE(debugTimerAudioIterval);
|
||||
DEBUG_TIMER_START(debugTimerAudioDuration);
|
||||
audioQueue.wakeup();
|
||||
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();
|
||||
}
|
||||
|
||||
void timer10msStart()
|
||||
{
|
||||
if (!timer_is_created(&_timer10ms)) {
|
||||
timer_create(&_timer10ms, _timer_10ms_cb, "10ms", 10, true);
|
||||
}
|
||||
|
||||
timer_start(&_timer10ms);
|
||||
}
|
||||
|
||||
void tasksStart()
|
||||
{
|
||||
RTOS_CREATE_MUTEX(audioMutex);
|
||||
mutex_create(&audioMutex);
|
||||
|
||||
#if defined(CLI) && !defined(SIMU)
|
||||
cliStart();
|
||||
#endif
|
||||
|
||||
RTOS_CREATE_TASK(menusTaskId, menusTask, "menus", menusStack,
|
||||
MENUS_STACK_SIZE, MENUS_TASK_PRIO);
|
||||
timer10msStart();
|
||||
|
||||
#if !defined(SIMU) && defined(AUDIO)
|
||||
RTOS_CREATE_TASK(audioTaskId, audioTask, "audio", audioStack,
|
||||
AUDIO_STACK_SIZE, AUDIO_TASK_PRIO);
|
||||
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();
|
||||
|
||||
+4
-5
@@ -21,7 +21,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rtos.h"
|
||||
#include "os/task.h"
|
||||
|
||||
// stack sizes should be in multiples of 8 for better alignment
|
||||
#if defined (COLORLCD)
|
||||
@@ -53,15 +53,14 @@
|
||||
#endif
|
||||
|
||||
|
||||
extern TaskStack<MENUS_STACK_SIZE> menusStack;
|
||||
extern TaskStack<MIXER_STACK_SIZE> mixerStack;
|
||||
extern task_handle_t menusTaskId;
|
||||
|
||||
#if defined(AUDIO)
|
||||
extern TaskStack<AUDIO_STACK_SIZE> audioStack;
|
||||
extern task_handle_t audioTaskId;
|
||||
#endif
|
||||
|
||||
#if defined(CLI)
|
||||
extern TaskStack<CLI_STACK_SIZE> cliStack;
|
||||
extern task_handle_t cliTaskId;
|
||||
#endif
|
||||
|
||||
void tasksStart();
|
||||
|
||||
@@ -23,22 +23,25 @@
|
||||
#include "mixer_task.h"
|
||||
#include "mixer_scheduler.h"
|
||||
|
||||
#include "os/task.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "switches.h"
|
||||
#include "hal/usb_driver.h"
|
||||
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#if defined(HALL_SYNC) && !defined(SIMU)
|
||||
#include "stm32_gpio.h"
|
||||
#include "hal/gpio.h"
|
||||
#endif
|
||||
|
||||
RTOS_TASK_HANDLE mixerTaskId;
|
||||
RTOS_DEFINE_STACK(mixerTaskId, mixerStack, MIXER_STACK_SIZE);
|
||||
task_handle_t mixerTaskId;
|
||||
TASK_DEFINE_STACK(mixerStack, MIXER_STACK_SIZE);
|
||||
|
||||
// mixer hold this mutex while computing
|
||||
// channels and sending them out
|
||||
static RTOS_MUTEX_HANDLE mixerMutex;
|
||||
static mutex_handle_t mixerMutex;
|
||||
|
||||
// The mixer will start in 'paused' mode
|
||||
// and start working properly once
|
||||
@@ -49,26 +52,26 @@ static bool _mixer_exit = false;
|
||||
|
||||
void mixerTaskLock()
|
||||
{
|
||||
RTOS_LOCK_MUTEX(mixerMutex);
|
||||
mutex_lock(&mixerMutex);
|
||||
}
|
||||
|
||||
// returns true if the lock could be acquired
|
||||
bool mixerTaskTryLock()
|
||||
{
|
||||
return RTOS_TRYLOCK_MUTEX(mixerMutex);
|
||||
return mutex_trylock(&mixerMutex);
|
||||
}
|
||||
|
||||
void mixerTaskUnlock()
|
||||
{
|
||||
RTOS_UNLOCK_MUTEX(mixerMutex);
|
||||
mutex_unlock(&mixerMutex);
|
||||
}
|
||||
|
||||
void mixerTaskInit()
|
||||
{
|
||||
mixerSchedulerInit();
|
||||
RTOS_CREATE_MUTEX(mixerMutex);
|
||||
RTOS_CREATE_TASK(mixerTaskId, mixerTask, "mixer", mixerStack,
|
||||
MIXER_STACK_SIZE, MIXER_TASK_PRIO);
|
||||
mutex_create(&mixerMutex);
|
||||
task_create(&mixerTaskId, mixerTask, "mixer", mixerStack, MIXER_STACK_SIZE,
|
||||
MIXER_TASK_PRIO);
|
||||
mixerSchedulerStart();
|
||||
}
|
||||
|
||||
@@ -133,17 +136,9 @@ void execMixerFrequentActions()
|
||||
#if defined(BLUETOOTH)
|
||||
bluetooth.wakeup();
|
||||
#endif
|
||||
|
||||
#if defined(SIMU)
|
||||
if (_mixer_running) {
|
||||
DEBUG_TIMER_START(debugTimerTelemetryWakeup);
|
||||
telemetryWakeup();
|
||||
DEBUG_TIMER_STOP(debugTimerTelemetryWakeup);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TASK_FUNCTION(mixerTask)
|
||||
void mixerTask()
|
||||
{
|
||||
#if defined(IMU)
|
||||
gyroInit();
|
||||
@@ -173,9 +168,8 @@ TASK_FUNCTION(mixerTask)
|
||||
mixerSchedulerEnableTrigger();
|
||||
|
||||
#if defined(SIMU)
|
||||
// TODO: should be using mixerTaskExit() instead...
|
||||
if (pwrCheck() == e_power_off) {
|
||||
TASK_RETURN();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// Emergency power OFF: in case the UI is not functional anymore
|
||||
@@ -218,8 +212,6 @@ TASK_FUNCTION(mixerTask)
|
||||
maxMixerDuration = t0;
|
||||
}
|
||||
}
|
||||
|
||||
TASK_RETURN();
|
||||
}
|
||||
|
||||
void doMixerCalculations()
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rtos.h"
|
||||
#include "os/task.h"
|
||||
|
||||
// needed by the mixer scheduler
|
||||
extern RTOS_TASK_HANDLE mixerTaskId;
|
||||
extern task_handle_t mixerTaskId;
|
||||
|
||||
// function running the mixer task
|
||||
TASK_FUNCTION(mixerTask);
|
||||
void mixerTask();
|
||||
|
||||
// init, create and start the OS task itself
|
||||
void mixerTaskInit();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "os/time.h"
|
||||
|
||||
/* Full telemetry
|
||||
packet[0] = TX RSSI value
|
||||
@@ -354,7 +355,7 @@ void processHitecPacket(const uint8_t * packet)
|
||||
alt = (int16_t) ((packet[3] << 8) | packet[4]);
|
||||
sensor = getHitecSensor(HITEC_ID_ALT);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_ALT, 0, 0, alt, sensor->unit, sensor->precision);
|
||||
current_ms = RTOS_GET_MS();
|
||||
current_ms = time_get_ms();
|
||||
sensor = getHitecSensor(HITEC_ID_VARIO);
|
||||
value = (alt - last_alt) * 100;
|
||||
if ((current_ms - last_ms) < 1000)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "multi.h"
|
||||
#include "os/async.h"
|
||||
#include "os/timer.h"
|
||||
#include "pulses/afhds3.h"
|
||||
#include "pulses/flysky.h"
|
||||
#include "mixer_scheduler.h"
|
||||
@@ -168,14 +170,10 @@ void telemetryMirrorSend(uint8_t data)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
static TimerHandle_t telemetryTimer = nullptr;
|
||||
static StaticTimer_t telemetryTimerBuffer;
|
||||
static timer_handle_t telemetryTimer = TIMER_INITIALIZER;
|
||||
|
||||
static void telemetryTimerCb(TimerHandle_t xTimer)
|
||||
static void telemetryTimerCb(timer_handle_t* h)
|
||||
{
|
||||
(void)xTimer;
|
||||
|
||||
DEBUG_TIMER_START(debugTimerTelemetryWakeup);
|
||||
telemetryWakeup();
|
||||
DEBUG_TIMER_STOP(debugTimerTelemetryWakeup);
|
||||
@@ -183,25 +181,17 @@ static void telemetryTimerCb(TimerHandle_t xTimer)
|
||||
|
||||
void telemetryStart()
|
||||
{
|
||||
if (!telemetryTimer) {
|
||||
telemetryTimer =
|
||||
xTimerCreateStatic("Telem", 2 / RTOS_MS_PER_TICK, pdTRUE, (void*)0,
|
||||
telemetryTimerCb, &telemetryTimerBuffer);
|
||||
if (!timer_is_created(&telemetryTimer)) {
|
||||
timer_create(&telemetryTimer, telemetryTimerCb, "Telem", 2, true);
|
||||
}
|
||||
|
||||
if (telemetryTimer) {
|
||||
if( xTimerStart( telemetryTimer, 0 ) != pdPASS ) {
|
||||
/* The timer could not be set into the Active state. */
|
||||
}
|
||||
}
|
||||
timer_start(&telemetryTimer);
|
||||
}
|
||||
|
||||
void telemetryStop()
|
||||
{
|
||||
if (telemetryTimer) {
|
||||
if( xTimerStop( telemetryTimer, 5 / RTOS_MS_PER_TICK ) != pdPASS ) {
|
||||
/* The timer could not be stopped. */
|
||||
}
|
||||
if (!timer_is_created(&telemetryTimer)) {
|
||||
timer_stop(&telemetryTimer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,21 +238,8 @@ static void _poll_frame(void *pvParameter1, uint32_t ulParameter2)
|
||||
|
||||
void telemetryFrameTrigger_ISR(uint8_t module, const etx_proto_driver_t* drv)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
if (!_poll_frame_queued[module] && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
xReturn = xTimerPendFunctionCallFromISR(_poll_frame, (void*)drv, module, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xReturn == pdPASS) {
|
||||
_poll_frame_queued[module] = true;
|
||||
} else {
|
||||
TRACE("xTimerPendFunctionCallFromISR() queue full");
|
||||
}
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
async_call_isr(_poll_frame, &_poll_frame_queued[module], (void*)drv, module);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool isBadAntennaDetected()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user