/* * 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 "edgetx.h" #include "ff.h" #include "analogs.h" #include "switches.h" #include "hal/adc_driver.h" #include "hal/switch_driver.h" #include "hal/usb_driver.h" #include "os/timer.h" #include "tasks/mixer_task.h" FIL g_oLogFile __DMA; uint8_t logDelay100ms; static tmr10ms_t lastLogTime = 0; static timer_handle_t loggingTimer = TIMER_INITIALIZER; static void loggingTimerCb(timer_handle_t* timer) { (void)timer; if (mixerTaskRunning()) { DEBUG_TIMER_START(debugTimerLoggingWakeup); logsWrite(); DEBUG_TIMER_STOP(debugTimerLoggingWakeup); } } void loggingTimerStart(uint32_t period) { if (!timer_is_created(&loggingTimer)) { timer_create(&loggingTimer, loggingTimerCb, "logs", period, true); } timer_start(&loggingTimer); } void loggingTimerStop() { timer_stop(&loggingTimer); } bool loggingTimerIsRunning() { return timer_is_active(&loggingTimer); } void initLoggingTimer() { // called cyclically by main.cpp:perMain() static uint8_t logDelay100msOld = 0; 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(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) { timer_set_period(&loggingTimer, logDelay100ms * 100); } } } } void writeHeader(); int getSwitchState(uint8_t swtch) { int value = getValue(MIXSRC_FIRST_SWITCH + swtch); return (value == 0) ? 0 : (value < 0) ? -1 : +1; } void logsInit() { memset(&g_oLogFile, 0, sizeof(g_oLogFile)); } const char * logsOpen() { if (!sdMounted()) return STR_NO_SDCARD; // Determine and set log file filename FRESULT result; // /LOGS/modelnamexxxxxx_YYYY-MM-DD-HHMMSS.log char filename[sizeof(LOGS_PATH) + LEN_MODEL_NAME + 18 + 4 + 1]; // check and create folder here char* tmp = strAppend(filename, LOGS_PATH); const char * error = sdCheckAndCreateDirectory(filename); if (error) { return error; } tmp = strAppend(tmp, "/"); if (g_model.header.name[0]) { tmp = strAppend(tmp, sanitizeForFilename(g_model.header.name, LEN_MODEL_NAME)); } else { // TODO uint8_t num = 1; tmp = strAppend(tmp, STR_MODEL); tmp = strAppendUnsigned(tmp, num, 2); } #if defined(RTCLOCK) tmp = strAppendDate(tmp, true); #endif strAppend(tmp, LOGS_EXT); result = f_open(&g_oLogFile, filename, FA_OPEN_ALWAYS | FA_WRITE | FA_OPEN_APPEND); if (result != FR_OK) { return SDCARD_ERROR(result); } if (f_size(&g_oLogFile) == 0) { writeHeader(); } return nullptr; } void logsClose() { if (g_oLogFile.obj.fs && sdMounted()) { if (f_close(&g_oLogFile) != FR_OK) { // close failed, forget file g_oLogFile.obj.fs = nullptr; } lastLogTime = 0; } } void writeHeader() { #if defined(RTCLOCK) f_puts("Date,Time,", &g_oLogFile); #else f_puts("Time,", &g_oLogFile); #endif char label[TELEM_LABEL_LEN+7]; for (int i=0; i 0 && !usbPlugged()) { #if defined(SIMU) || !defined(RTCLOCK) tmr10ms_t tmr10ms = get_tmr10ms(); // tmr10ms works in 10ms increments if (lastLogTime == 0 || (tmr10ms_t)(tmr10ms - lastLogTime) >= (tmr10ms_t)(logDelay100ms*10)-1) { lastLogTime = tmr10ms; #else { #endif bool sdCardFull = sdIsFull(); // check if file needs to be opened if (!g_oLogFile.obj.fs) { const char *result = sdCardFull ? STR_SDCARD_FULL_EXT : logsOpen(); // SD card is full or file open failed if (result) { if (result != error_displayed) { error_displayed = result; POPUP_WARNING_ON_UI_TASK(result, nullptr); } return; } } // check at every write cycle if (sdCardFull) { logsClose(); // timer is still running and code above will try to // open the file again but will fail with error // which will trigger the warning popup return; } #if defined(RTCLOCK) { static struct gtm utm; static gtime_t lastRtcTime = 0; if (g_rtcTime != lastRtcTime) { lastRtcTime = g_rtcTime; gettime(&utm); } f_printf(&g_oLogFile, "%4d-%02d-%02d,%02d:%02d:%02d.%02d0,", utm.tm_year+TM_YEAR_BASE, utm.tm_mon+1, utm.tm_mday, utm.tm_hour, utm.tm_min, utm.tm_sec, g_ms100); } #else f_printf(&g_oLogFile, "%d,", tmr10ms); #endif for (int i=0; i