1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-13 11:29:51 +03:00

Bsongis/ram saving (#6685)

RAM saving. Stacks reduced to have some more RAM available than 2.2 on all boards
This commit is contained in:
Bertrand Songis 2019-08-30 15:46:57 +02:00 committed by GitHub
parent ff2cde85be
commit 2d4e98d15d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 271 additions and 330 deletions

View file

@ -529,7 +529,7 @@ void audioTask(void * pdata)
RTOS_WAIT_MS(1000); // 1s
#endif
if (!unexpectedShutdown) {
if (!globalData.unexpectedShutdown) {
AUDIO_HELLO();
}

View file

@ -231,15 +231,11 @@ void drawStatusLine();
#define drawStatusLine()
#endif
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void menuTextView(event_t event);
void pushMenuTextView(const char *filename);
void pushModelNotes();
void readModelNotes();
#define LABEL(...) (uint8_t)-1
#define CURSOR_MOVED_LEFT(event) (IS_ROTARY_LEFT(event) || EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (IS_ROTARY_RIGHT(event) || EVT_KEY_MASK(event) == KEY_RIGHT)

View file

@ -22,33 +22,35 @@
void menuChannelsView(event_t event)
{
static bool longNames = false;
bool newLongNames = false;
static bool secondPage = false;
static bool mixersView = false;
uint8_t ch;
switch(event)
{
switch (event) {
case EVT_ENTRY:
memclear(&reusableBuffer.viewChannels, sizeof(reusableBuffer.viewChannels));
break;
case EVT_KEY_BREAK(KEY_EXIT):
popMenu();
break;
case EVT_KEY_FIRST(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_LEFT):
secondPage = !secondPage;
reusableBuffer.viewChannels.secondPage = !reusableBuffer.viewChannels.secondPage;
break;
case EVT_KEY_FIRST(KEY_ENTER):
mixersView = !mixersView;
reusableBuffer.viewChannels.mixersView = !reusableBuffer.viewChannels.mixersView;
break;
}
if (secondPage)
if (reusableBuffer.viewChannels.secondPage)
ch = 16;
else
ch = 0;
if (mixersView) {
if (reusableBuffer.viewChannels.mixersView) {
lcdDrawTextAlignedCenter(0, TR_MIXERS_MONITOR);
}
else {
@ -67,13 +69,13 @@ void menuChannelsView(event_t event)
// Channels
for (uint8_t line=0; line<8; line++) {
uint8_t y = 9+line*7;
int32_t val = (mixersView) ? ex_chans[ch] : channelOutputs[ch];
int32_t val = (reusableBuffer.viewChannels.mixersView) ? ex_chans[ch] : channelOutputs[ch];
uint8_t ofs = (col ? 0 : 1);
// Channel name if present, number if not
uint8_t lenLabel = ZLEN(g_model.limitData[ch].name);
if (lenLabel > 4) {
newLongNames = longNames = true;
newLongNames = reusableBuffer.viewChannels.longNames = true;
}
if (lenLabel > 0)
@ -86,7 +88,7 @@ void menuChannelsView(event_t event)
uint8_t wbar = (longNames ? 54 : 64);
lcdDrawNumber(x+LCD_W/2-3-wbar-ofs, y+1, PPM_CH_CENTER(ch)+val/2, TINSIZE|RIGHT);
#elif defined(PPM_UNIT_PERCENT_PREC1)
uint8_t wbar = (longNames ? 48 : 58);
uint8_t wbar = (reusableBuffer.viewChannels.longNames ? 48 : 58);
lcdDrawNumber(x+LCD_W/2-3-wbar-ofs, y+1, calcRESXto1000(val), PREC1|TINSIZE|RIGHT);
#else
uint8_t wbar = (longNames ? 54 : 64);
@ -105,5 +107,5 @@ void menuChannelsView(event_t event)
}
}
longNames = newLongNames;
reusableBuffer.viewChannels.longNames = newLongNames;
}

View file

@ -160,7 +160,7 @@ void menuStatisticsDebug(event_t event)
if (IS_RESET_REASON_WATCHDOG()) {
lcdDrawText(LCD_W-8*FW, 0, "WATCHDOG");
}
else if (unexpectedShutdown) {
else if (globalData.unexpectedShutdown) {
lcdDrawText(LCD_W-13*FW, 0, "UNEXP.SHTDOWN");
}
#endif

View file

@ -264,8 +264,6 @@ extern char statusLineMsg[STATUS_LINE_LENGTH];
void showStatusLine();
void drawStatusLine();
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void menuTextView(event_t event);
void pushMenuTextView(const char *filename);
void pushModelNotes();
@ -273,8 +271,6 @@ void readModelNotes();
void menuChannelsView(event_t event);
#define LABEL(...) (uint8_t)-1
#if defined(ROTARY_ENCODER_NAVIGATION)
#define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT)

View file

@ -24,20 +24,18 @@ extern uint8_t g_moduleIdx;
void menuModelFailsafe(event_t event)
{
static uint8_t maxNameLen = 4;
static int8_t lastModel = g_eeGeneral.currModel;
const coord_t barH = (LCD_H - FH) / 8 - 1;
const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2;
const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart;
uint8_t cols = 1;
uint8_t colW = LCD_W;
if (lastModel != g_eeGeneral.currModel) {
lastModel = g_eeGeneral.currModel;
maxNameLen = 4;
}
switch(event) {
case EVT_ENTRY:
reusableBuffer.modelFailsafe.maxNameLen = 4;
break;
if (event == EVT_KEY_LONG(KEY_ENTER)) {
case EVT_KEY_LONG(KEY_ENTER):
killEvents(event);
event = 0;
@ -64,6 +62,7 @@ void menuModelFailsafe(event_t event)
storageDirty(EE_MODEL);
AUDIO_WARNING1();
SEND_FAILSAFE_NOW(g_moduleIdx);
break;
}
SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx) + 1);
@ -95,7 +94,7 @@ void menuModelFailsafe(event_t event)
const int32_t channelValue = channelOutputs[ch+channelStart];
int32_t failsafeValue = g_model.failsafeChannels[8*col+line];
uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name);
uint8_t barW = colW - FW * maxNameLen - FWNUM * 3; // default bar width
uint8_t barW = colW - FW * reusableBuffer.modelFailsafe.maxNameLen - FWNUM * 3; // default bar width
#if defined(PPM_UNIT_PERCENT_PREC1)
barW -= FWNUM + 1;
@ -104,8 +103,8 @@ void menuModelFailsafe(event_t event)
// Channel name if present, number if not
if (lenLabel > 0) {
if (lenLabel > maxNameLen)
maxNameLen = lenLabel;
if (lenLabel > reusableBuffer.modelFailsafe.maxNameLen)
reusableBuffer.modelFailsafe.maxNameLen = lenLabel;
lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE);
}
else {

View file

@ -22,44 +22,46 @@
void menuChannelsView(event_t event)
{
static bool longNames = false;
static bool secondPage = false;
static bool mixersView = false;
uint8_t ch = 0;
uint8_t wbar = (longNames ? 54 : 64);
uint8_t wbar = (reusableBuffer.viewChannels.longNames ? 54 : 64);
int16_t limits = 512 * 2;
#if defined(PPM_UNIT_PERCENT_PREC1)
wbar -= 6;
#endif
switch(event)
{
switch(event) {
case EVT_ENTRY:
memclear(&reusableBuffer.viewChannels, sizeof(reusableBuffer.viewChannels));
break;
case EVT_KEY_BREAK(KEY_EXIT):
popMenu();
break;
case EVT_KEY_FIRST(KEY_RIGHT):
case EVT_KEY_FIRST(KEY_LEFT):
#if defined(ROTARY_ENCODER_NAVIGATION)
case EVT_ROTARY_LEFT:
case EVT_ROTARY_RIGHT:
#endif
secondPage = !secondPage;
reusableBuffer.viewChannels.secondPage = !reusableBuffer.viewChannels.secondPage;
break;
case EVT_KEY_FIRST(KEY_ENTER):
mixersView = !mixersView;
reusableBuffer.viewChannels.mixersView = !reusableBuffer.viewChannels.mixersView;
break;
}
if (secondPage)
if (reusableBuffer.viewChannels.secondPage)
ch = 16;
if (mixersView)
if (reusableBuffer.viewChannels.mixersView)
limits *= 2; // this could be handled nicer, but slower, by checking actual range for this mixer
else if (g_model.extendedLimits)
limits *= LIMIT_EXT_PERCENT / 100;
if (mixersView)
if (reusableBuffer.viewChannels.mixersView)
lcdDrawTextAlignedCenter(0, TR_MIXERS_MONITOR);
else
lcdDrawTextAlignedCenter(0, TR_CHANNELS_MONITOR);
@ -76,13 +78,13 @@ void menuChannelsView(event_t event)
// Channels
for (uint8_t line=0; line < 8; line++) {
const uint8_t y = 9 + line * 7;
const int32_t val = mixersView ? ex_chans[ch] : channelOutputs[ch];
const int32_t val = reusableBuffer.viewChannels.mixersView ? ex_chans[ch] : channelOutputs[ch];
const uint8_t lenLabel = ZLEN(g_model.limitData[ch].name);
// Channel name if present, number if not
if (lenLabel > 0) {
if (lenLabel > 4)
longNames = true;
reusableBuffer.viewChannels.longNames = true;
lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE);
}
else {

View file

@ -78,11 +78,11 @@ void readModelNotes()
{
LED_ERROR_BEGIN();
strcpy(s_text_file, MODELS_PATH "/");
char *buf = strcat_currentmodelname(&s_text_file[sizeof(MODELS_PATH)]);
strcpy(reusableBuffer.viewText.filename, MODELS_PATH "/");
char *buf = strcat_currentmodelname(&reusableBuffer.viewText.filename[sizeof(MODELS_PATH)]);
strcpy(buf, TEXT_EXT);
if (!isFileAvailable(s_text_file)) {
char *buf = strAppendFilename(&s_text_file[sizeof(MODELS_PATH)], g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME);
if (!isFileAvailable(reusableBuffer.viewText.filename)) {
char *buf = strAppendFilename(&reusableBuffer.viewText.filename[sizeof(MODELS_PATH)], g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME);
strcpy(buf, TEXT_EXT);
}
@ -103,11 +103,11 @@ void readModelNotes()
bool menuModelNotes(event_t event)
{
if (event == EVT_ENTRY) {
strcpy(s_text_file, MODELS_PATH "/");
char *buf = strcat_currentmodelname(&s_text_file[sizeof(MODELS_PATH)]);
strcpy(reusableBuffer.viewText.filename, MODELS_PATH "/");
char *buf = strcat_currentmodelname(&reusableBuffer.viewText.filename[sizeof(MODELS_PATH)]);
strcpy(buf, TEXT_EXT);
if (!isFileAvailable(s_text_file)) {
char *buf = strAppendFilename(&s_text_file[sizeof(MODELS_PATH)], g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME);
if (!isFileAvailable(reusableBuffer.viewText.filename)) {
char * buf = strAppendFilename(&reusableBuffer.viewText.filename[sizeof(MODELS_PATH)], g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME);
strcpy(buf, TEXT_EXT);
}
}

View file

@ -589,14 +589,10 @@ inline void POPUP_CONFIRMATION(const char *s, void (* confirmHandler)(const char
popupMenuHandler = confirmHandler;
}
#define TEXT_FILENAME_MAXLEN 40
extern char s_text_file[TEXT_FILENAME_MAXLEN];
void pushMenuTextView(const char * filename);
void pushModelNotes();
void readModelNotes();
#define LABEL(...) (uint8_t)-1
#define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT || EVT_KEY_MASK(event) == KEY_LEFT)
#define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT || EVT_KEY_MASK(event) == KEY_RIGHT)
#define REPEAT_LAST_CURSOR_MOVE(last, refresh) { if (CURSOR_MOVED_RIGHT(event)) menuHorizontalPosition = (menuHorizontalPosition >= (last) ? 0 : menuHorizontalPosition + 1); else menuHorizontalPosition = (menuHorizontalPosition <= (0) ? last : menuHorizontalPosition - 1); if (refresh) putEvent(EVT_REFRESH); }

View file

@ -20,80 +20,6 @@
#include "opentx.h"
#define TEXT_FILE_MAXSIZE 2048
char s_text_file[TEXT_FILENAME_MAXLEN];
char s_text_screen[NUM_BODY_LINES][LCD_COLS+1];
void readTextFile(int & lines_count)
{
FIL file;
int result;
char c;
unsigned int sz;
int line_length = 0;
int escape = 0;
char escape_chars[2];
int current_line = 0;
memset(s_text_screen, 0, sizeof(s_text_screen));
result = f_open(&file, s_text_file, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK) {
for (int i=0; i<TEXT_FILE_MAXSIZE && f_read(&file, &c, 1, &sz)==FR_OK && sz==1 && (lines_count==0 || current_line-menuVerticalOffset<NUM_BODY_LINES); i++) {
if (c == '\n') {
++current_line;
line_length = 0;
escape = 0;
}
else if (c!='\r' && current_line>=menuVerticalOffset && current_line-menuVerticalOffset<NUM_BODY_LINES && line_length<LCD_COLS) {
if (c=='\\' && escape==0) {
escape = 1;
continue;
}
else if (c!='\\' && escape>0 && escape<4) {
escape_chars[escape-1] = c;
if (escape == 2 && !strncmp(escape_chars, "up", 2)) {
c = '\300';
escape = 0;
}
else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) {
c = '\301';
escape = 0;
}
else if (escape == 3) {
int val = atoi(escape_chars);
if (val >= 200 && val < 225) {
c = '\200' + val-200;
}
escape = 0;
}
else {
escape++;
continue;
}
}
else if (c=='~') {
c = 'z'+1;
}
else if (c=='\t') {
c = 0x1D; //tab
}
escape = 0;
s_text_screen[current_line-menuVerticalOffset][line_length++] = c;
}
}
if (c != '\n') {
current_line += 1;
}
f_close(&file);
}
if (lines_count == 0) {
lines_count = current_line;
}
}
bool menuTextView(event_t event)
{
static int lines_count;
@ -104,7 +30,7 @@ bool menuTextView(event_t event)
case EVT_ENTRY:
menuVerticalOffset = 0;
lines_count = 0;
readTextFile(lines_count);
sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, lines_count);
break;
case EVT_ROTARY_LEFT:
@ -112,7 +38,7 @@ bool menuTextView(event_t event)
break;
else
menuVerticalOffset--;
readTextFile(lines_count);
sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, lines_count);
break;
case EVT_ROTARY_RIGHT:
@ -120,7 +46,7 @@ bool menuTextView(event_t event)
break;
else
++menuVerticalOffset;
readTextFile(lines_count);
sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, lines_count);
break;
case EVT_KEY_FIRST(KEY_EXIT):
@ -129,7 +55,7 @@ bool menuTextView(event_t event)
}
for (int i=0; i<NUM_BODY_LINES; i++) {
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + i*FH, s_text_screen[i]);
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + i*FH, reusableBuffer.viewText.lines[i]);
}
#if 0
@ -148,7 +74,7 @@ bool menuTextView(event_t event)
void pushMenuTextView(const char *filename)
{
if (strlen(filename) < TEXT_FILENAME_MAXLEN) {
strcpy(s_text_file, filename);
strcpy(reusableBuffer.viewText.filename, filename);
pushMenu(menuTextView);
}
}

View file

@ -23,8 +23,8 @@
void menuModelNotes(event_t event)
{
if (event == EVT_ENTRY) {
strcpy(s_text_file, MODELS_PATH "/");
char *buf = strcat_modelname(&s_text_file[sizeof(MODELS_PATH)], g_eeGeneral.currModel);
strcpy(reusableBuffer.viewText.filename, MODELS_PATH "/");
char *buf = strcat_modelname(&reusableBuffer.viewText.filename[sizeof(MODELS_PATH)], g_eeGeneral.currModel);
strcpy(buf, TEXT_EXT);
}

View file

@ -20,80 +20,6 @@
#include "opentx.h"
#define TEXT_FILE_MAXSIZE 2048
char s_text_file[TEXT_FILENAME_MAXLEN];
char s_text_screen[LCD_LINES-1][LCD_COLS+1];
void readTextFile(int & lines_count)
{
FIL file;
int result;
char c;
unsigned int sz;
int line_length = 0;
int escape = 0;
char escape_chars[4] = {0};
int current_line = 0;
memset(s_text_screen, 0, sizeof(s_text_screen));
result = f_open(&file, s_text_file, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK) {
for (int i=0; i<TEXT_FILE_MAXSIZE && f_read(&file, &c, 1, &sz)==FR_OK && sz==1 && (lines_count==0 || current_line-menuVerticalOffset<LCD_LINES-1); i++) {
if (c == '\n') {
++current_line;
line_length = 0;
escape = 0;
}
else if (c!='\r' && current_line>=menuVerticalOffset && current_line-menuVerticalOffset<LCD_LINES-1 && line_length<LCD_COLS) {
if (c=='\\' && escape==0) {
escape = 1;
continue;
}
else if (c!='\\' && escape>0 && escape<4) {
escape_chars[escape-1] = c;
if (escape == 2 && !strncmp(escape_chars, "up", 2)) {
c = '\300';
escape = 0;
}
else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) {
c = '\301';
escape = 0;
}
else if (escape == 3) {
int val = atoi(escape_chars);
if (val >= 200 && val < 225) {
c = '\200' + val-200;
}
escape = 0;
}
else {
escape++;
continue;
}
}
else if (c=='~') {
c = 'z'+1;
}
else if (c=='\t') {
c = 0x1D; //tab
}
escape = 0;
s_text_screen[current_line-menuVerticalOffset][line_length++] = c;
}
}
if (c != '\n') {
current_line += 1;
}
f_close(&file);
}
if (lines_count == 0) {
lines_count = current_line;
}
}
#if defined(ROTARY_ENCODER_NAVIGATION)
#define EVT_KEY_NEXT_LINE EVT_ROTARY_RIGHT
#define EVT_KEY_PREVIOUS_LINE EVT_ROTARY_LEFT
@ -106,8 +32,8 @@ void readModelNotes()
{
LED_ERROR_BEGIN();
strcpy(s_text_file, MODELS_PATH "/");
char *buf = strcat_modelname(&s_text_file[sizeof(MODELS_PATH)], g_eeGeneral.currModel);
strcpy(reusableBuffer.viewText.filename, MODELS_PATH "/");
char *buf = strcat_modelname(&reusableBuffer.viewText.filename[sizeof(MODELS_PATH)], g_eeGeneral.currModel);
strcpy(buf, TEXT_EXT);
waitKeysReleased();
@ -126,13 +52,11 @@ void readModelNotes()
void menuTextView(event_t event)
{
static int lines_count;
switch (event) {
case EVT_ENTRY:
menuVerticalOffset = 0;
lines_count = 0;
readTextFile(lines_count);
reusableBuffer.viewText.linesCount = 0;
sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount);
break;
case EVT_KEY_PREVIOUS_LINE:
@ -140,15 +64,15 @@ void menuTextView(event_t event)
break;
else
menuVerticalOffset--;
readTextFile(lines_count);
sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount);
break;
case EVT_KEY_NEXT_LINE:
if (menuVerticalOffset+LCD_LINES-1 >= lines_count)
if (menuVerticalOffset+LCD_LINES-1 >= reusableBuffer.viewText.linesCount)
break;
else
++menuVerticalOffset;
readTextFile(lines_count);
sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount);
break;
case EVT_KEY_BREAK(KEY_EXIT):
@ -157,10 +81,10 @@ void menuTextView(event_t event)
}
for (int i=0; i<LCD_LINES-1; i++) {
lcdDrawText(0, i*FH+FH+1, s_text_screen[i], FIXEDWIDTH);
lcdDrawText(0, i*FH+FH+1, reusableBuffer.viewText.lines[i], FIXEDWIDTH);
}
char * title = s_text_file;
char * title = reusableBuffer.viewText.filename;
#if defined(SIMU)
if (!strncmp(title, "./", 2)) title += 2;
#else
@ -169,15 +93,15 @@ void menuTextView(event_t event)
lcdDrawText(LCD_W/2, 0, getBasename(title), CENTERED);
lcdInvertLine(0);
if (lines_count > LCD_LINES-1) {
drawVerticalScrollbar(LCD_W-1, FH, LCD_H-FH, menuVerticalOffset, lines_count, LCD_LINES-1);
if (reusableBuffer.viewText.linesCount > LCD_LINES-1) {
drawVerticalScrollbar(LCD_W-1, FH, LCD_H-FH, menuVerticalOffset, reusableBuffer.viewText.linesCount, LCD_LINES-1);
}
}
void pushMenuTextView(const char *filename)
{
if (strlen(filename) < TEXT_FILENAME_MAXLEN) {
strcpy(s_text_file, filename);
strcpy(reusableBuffer.viewText.filename, filename);
pushMenu(menuTextView);
}
}

View file

@ -27,6 +27,7 @@
#define READONLY_ROW ((uint8_t)-1)
#define TITLE_ROW READONLY_ROW
#define LABEL(...) READONLY_ROW
#define HIDDEN_ROW ((uint8_t)-2)
#if defined(ROTARY_ENCODER_NAVIGATION)

View file

@ -39,7 +39,7 @@
event_t s_evt;
struct t_inactivity inactivity = {0};
struct InactivityData inactivity = {0};
Key keys[NUM_KEYS];
event_t getEvent(bool trim)

View file

@ -490,24 +490,23 @@ void perMain()
event_t evt = getEvent(false);
#if defined(RAMBACKUP)
if (unexpectedShutdown) {
if (globalData.unexpectedShutdown) {
drawFatalErrorScreen(STR_EMERGENCY_MODE);
return;
}
#endif
#if defined(STM32)
static bool sdcard_present_before = SD_CARD_PRESENT();
bool sdcard_present_now = SD_CARD_PRESENT();
if (sdcard_present_now && !sdcard_present_before) {
bool sdcardPresent = SD_CARD_PRESENT();
if (sdcardPresent && !globalData.sdcardPresent) {
sdMount();
}
sdcard_present_before = sdcard_present_now;
globalData.sdcardPresent = sdcardPresent;
#endif
#if !defined(EEPROM)
// In case the SD card is removed during the session
if (!SD_CARD_PRESENT() && !unexpectedShutdown) {
if (!SD_CARD_PRESENT() && !globalData.unexpectedShutdown) {
drawFatalErrorScreen(STR_NO_SDCARD);
return;
}

View file

@ -28,13 +28,9 @@ ModelData g_model;
Clipboard clipboard;
#endif
uint8_t unexpectedShutdown = 0;
uint16_t vbattRTC;
/* ARM: mixer duration in 0.5us */
uint16_t maxMixerDuration;
GlobalData globalData;
uint16_t maxMixerDuration; // step = 0.01ms
uint8_t heartbeat;
#if defined(OVERRIDE_CHANNEL_FUNCTION)
@ -672,11 +668,6 @@ getvalue_t convert16bitsTelemValue(source_t channel, ls_telemetry_value_t value)
return value;
}
ls_telemetry_value_t minTelemValue(source_t channel)
{
return 0;
}
ls_telemetry_value_t maxTelemValue(source_t channel)
{
return 30000;
@ -1841,12 +1832,14 @@ void opentxInit()
// * radios without CPU controlled power can only use Reset status register (if available)
if (UNEXPECTED_SHUTDOWN()) {
TRACE("Unexpected Shutdown detected");
unexpectedShutdown = 1;
globalData.unexpectedShutdown = 1;
}
#if defined(SDCARD)
globalData.sdcardPresent = SD_CARD_PRESENT();
// SDCARD related stuff, only done if not unexpectedShutdown
if (!unexpectedShutdown) {
if (!globalData.unexpectedShutdown) {
sdInit();
#if defined(AUTOUPDATE)
@ -1882,7 +1875,7 @@ void opentxInit()
#endif
#if defined(COLORLCD)
if (!unexpectedShutdown) {
if (!globalData.unexpectedShutdown) {
// g_model.topbarData is still zero here (because it was not yet read from SDCARD),
// but we only remember the pointer to in in constructor.
// The storageReadAll() needs topbar object, so it must be created here
@ -1896,7 +1889,7 @@ void opentxInit()
// handling of storage for radios that have no EEPROM
#if !defined(EEPROM)
#if defined(RAMBACKUP)
if (unexpectedShutdown) {
if (globalData.unexpectedShutdown) {
// SDCARD not available, try to restore last model from RAM
TRACE("rambackupRestore");
rambackupRestore();
@ -1952,7 +1945,7 @@ void opentxInit()
backlightOn();
}
if (!unexpectedShutdown) {
if (!globalData.unexpectedShutdown) {
opentxStart();
}

View file

@ -30,7 +30,6 @@
#include "opentx_types.h"
#include "debounce.h"
#if defined(SIMU)
#include "targets/simu/simpgmspace.h"
#endif
@ -413,13 +412,13 @@ void watchdogSuspend(uint32_t timeout);
#define MAX_ALERT_TIME 60
struct t_inactivity
struct InactivityData
{
uint16_t counter;
uint8_t sum;
};
extern struct t_inactivity inactivity;
extern InactivityData inactivity;
#define LEN_STD_CHARS 40
@ -566,9 +565,13 @@ extern uint8_t trimsDisplayMask;
void flightReset(uint8_t check=true);
extern uint8_t unexpectedShutdown;
PACK(struct GlobalData {
uint8_t unexpectedShutdown:1;
uint8_t sdcardPresent:1;
uint8_t spare:6;
});
extern uint16_t vbattRTC;
extern GlobalData globalData;
extern uint16_t maxMixerDuration;
@ -1075,15 +1078,17 @@ constexpr uint8_t OPENTX_START_NO_CHECKS = 0x04;
// Re-useable byte array to save having multiple buffers
#if LCD_W <= 212
#define SD_SCREEN_FILE_LENGTH 32
constexpr uint8_t SD_SCREEN_FILE_LENGTH = 32;
#else
#define SD_SCREEN_FILE_LENGTH 64
constexpr uint8_t SD_SCREEN_FILE_LENGTH = 64;
#endif
#if defined(BLUETOOTH)
#include "bluetooth.h"
#endif
constexpr uint8_t TEXT_FILENAME_MAXLEN = 40;
union ReusableBuffer
{
struct {
@ -1199,13 +1204,29 @@ union ReusableBuffer
int8_t preset;
} curveEdit;
struct {
char filename[TEXT_FILENAME_MAXLEN];
char lines[NUM_BODY_LINES][LCD_COLS + 1];
int linesCount;
} viewText;
struct {
bool longNames;
bool secondPage;
bool mixersView;
} viewChannels;
struct {
uint8_t maxNameLen;
} modelFailsafe;
#if defined(STM32)
// Data for the USB mass storage driver. If USB mass storage runs no menu is not allowed to be displayed
uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET];
#endif
};
extern union ReusableBuffer reusableBuffer;
extern ReusableBuffer reusableBuffer;
uint8_t zlen(const char *str, uint8_t size);
bool zexist(const char *str, uint8_t size);
@ -1224,13 +1245,15 @@ char * strcat_zchar(char *dest, const char *name, uint8_t size, const char *defa
// Stick tolerance varies between transmitters, Higher is better
#define STICK_TOLERANCE 64
ls_telemetry_value_t minTelemValue(source_t channel);
ls_telemetry_value_t maxTelemValue(source_t channel);
ls_telemetry_value_t maxTelemValue(source_t channel);
getvalue_t convert16bitsTelemValue(source_t channel, ls_telemetry_value_t value);
getvalue_t convertLswTelemValue(LogicalSwitchData * cs);
#define convertTelemValue(channel, value) convert16bitsTelemValue(channel, value)
inline getvalue_t convertTelemValue(source_t channel, ls_telemetry_value_t value)
{
return convert16bitsTelemValue(channel, value);
}
inline int div_and_round(int num, int den)
{
@ -1270,8 +1293,6 @@ extern uint8_t s_frsky_view;
constexpr uint32_t EARTH_RADIUS = 6371009;
void getGpsPilotPosition();
void getGpsDistance();
void varioWakeup();
#if defined(AUDIO) && defined(BUZZER)
@ -1356,15 +1377,6 @@ enum JackMode {
#include "gyro.h"
#endif
inline bool isSimu()
{
#if defined(SIMU)
return true;
#else
return false;
#endif
}
#if defined(DEBUG_LATENCY)
extern uint8_t latencyToggleSwitch;
#endif
@ -1375,7 +1387,7 @@ inline bool isAsteriskDisplayed()
return true;
#endif
return unexpectedShutdown;
return globalData.unexpectedShutdown;
}
#endif // _OPENTX_H_

View file

@ -140,7 +140,7 @@ class BindInformation {
class OtaUpdateInformation: public BindInformation {
public:
char filename[_MAX_LFN+1];
char filename[32+1];
uint32_t address;
};

View file

@ -410,6 +410,74 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
return popupMenuItemsCount;
}
constexpr uint32_t TEXT_FILE_MAXSIZE = 2048;
void sdReadTextFile(const char * filename, char lines[NUM_BODY_LINES][LCD_COLS + 1], int & lines_count)
{
FIL file;
int result;
char c;
unsigned int sz;
int line_length = 0;
uint8_t escape = 0;
char escape_chars[4] = {0};
int current_line = 0;
memclear(lines, NUM_BODY_LINES * (LCD_COLS + 1));
result = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK) {
for (unsigned i = 0; i < TEXT_FILE_MAXSIZE && f_read(&file, &c, 1, &sz) == FR_OK && sz == 1 && (lines_count == 0 || current_line - menuVerticalOffset < NUM_BODY_LINES); i++) {
if (c == '\n') {
++current_line;
line_length = 0;
escape = 0;
}
else if (c!='\r' && current_line>=menuVerticalOffset && current_line-menuVerticalOffset<NUM_BODY_LINES && line_length<LCD_COLS) {
if (c == '\\' && escape == 0) {
escape = 1;
continue;
}
else if (c != '\\' && escape > 0 && escape < sizeof(escape_chars)) {
escape_chars[escape - 1] = c;
if (escape == 2 && !strncmp(escape_chars, "up", 2)) {
c = '\300';
}
else if (escape == 2 && !strncmp(escape_chars, "dn", 2)) {
c = '\301';
}
else if (escape == 3) {
int val = atoi(escape_chars);
if (val >= 200 && val < 225) {
c = '\200' + val-200;
}
}
else {
escape++;
continue;
}
}
else if (c=='~') {
c = 'z'+1;
}
else if (c=='\t') {
c = 0x1D; //tab
}
escape = 0;
lines[current_line-menuVerticalOffset][line_length++] = c;
}
}
if (c != '\n') {
current_line += 1;
}
f_close(&file);
}
if (lines_count == 0) {
lines_count = current_line;
}
}
// returns true if current working dir is at the root level
bool isCwdAtRoot()
{

View file

@ -156,6 +156,8 @@ const char * sdCopyFile(const char * srcFilename, const char * srcDir, const cha
#define LIST_SD_FILE_EXT 2
bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen, const char * selection, uint8_t flags=0);
void sdReadTextFile(const char * filename, char lines[NUM_BODY_LINES][LCD_COLS + 1], int & lines_count);
bool isCwdAtRoot();
FRESULT sdReadDir(DIR * dir, FILINFO * fno, bool & firstTime);

View file

@ -40,22 +40,21 @@ enum LogicalSwitchContextState {
SWITCH_ENABLE
};
PACK(typedef struct {
PACK(struct LogicalSwitchContext {
uint8_t state:1;
uint8_t timerState:2;
uint8_t spare:5;
uint8_t timer;
int16_t lastValue;
}) LogicalSwitchContext;
});
PACK(typedef struct {
PACK(struct LogicalSwitchesFlightModeContext {
LogicalSwitchContext lsw[MAX_LOGICAL_SWITCHES];
}) LogicalSwitchesFlightModeContext;
});
LogicalSwitchesFlightModeContext lswFm[MAX_FLIGHT_MODES];
#define LS_LAST_VALUE(fm, idx) lswFm[fm].lsw[idx].lastValue
#if defined(PCBTARANIS) || defined(PCBHORUS)
#if defined(PCBX9E)
tmr10ms_t switchesMidposStart[16];

View file

@ -510,8 +510,8 @@ void backlightEnable(uint8_t dutyCycle = 0);
#else
#define BACKLIGHT_LEVEL_MIN 46
#endif
#define BACKLIGHT_ENABLE() backlightEnable(unexpectedShutdown ? BACKLIGHT_LEVEL_MAX : BACKLIGHT_LEVEL_MAX-g_eeGeneral.backlightBright)
#define BACKLIGHT_DISABLE() backlightEnable(unexpectedShutdown ? BACKLIGHT_LEVEL_MAX : ((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && (g_eeGeneral.backlightMode != e_backlight_mode_off)) ? 0 : g_eeGeneral.blOffBright)
#define BACKLIGHT_ENABLE() backlightEnable(globalData.unexpectedShutdown ? BACKLIGHT_LEVEL_MAX : BACKLIGHT_LEVEL_MAX-g_eeGeneral.backlightBright)
#define BACKLIGHT_DISABLE() backlightEnable(globalData.unexpectedShutdown ? BACKLIGHT_LEVEL_MAX : ((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && (g_eeGeneral.backlightMode != e_backlight_mode_off)) ? 0 : g_eeGeneral.blOffBright)
#define isBacklightEnabled() true
#if !defined(SIMU)

View file

@ -115,7 +115,7 @@ void lcdInit()
#if defined(REVX)
// 200mS delay (only if not wdt reset)
if ( ( ( ResetReason & RSTC_SR_RSTTYP ) != (2 << 8) ) && !unexpectedShutdown ) {
if ( ( ( ResetReason & RSTC_SR_RSTTYP ) != (2 << 8) ) && !globalData.unexpectedShutdown ) {
for (uint32_t j = 0; j < 100; j += 1 ) {
TC0->TC_CHANNEL[0].TC_CCR = 5; // Enable clock and trigger it (may only need trigger)
while ( TC0->TC_CHANNEL[0].TC_CV < 36000 ) {

View file

@ -329,15 +329,12 @@ void stop_trainer_module_sbus()
}
#endif
uint32_t ccount = 0;
#if defined(SBUS)
int sbusGetByte(uint8_t * byte)
{
switch (currentTrainerMode) {
#if defined(TRAINER_MODULE_SBUS_USART)
case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE:
ccount++;
return trainerSbusFifo.pop(*byte);
#endif
#if defined(AUX_SERIAL_USART)

View file

@ -18,15 +18,15 @@
* GNU General Public License for more details.
*/
#ifndef _TASKS_ARM_H_
#define _TASKS_ARM_H_
#ifndef _TASKS_H_
#define _TASKS_H_
#include "rtos.h"
// stack sizes should be in multiples of 8 for better alignment
#define MENUS_STACK_SIZE 2000
#define MIXER_STACK_SIZE 512
#define AUDIO_STACK_SIZE 512
#define MIXER_STACK_SIZE 400
#define AUDIO_STACK_SIZE 400
#define CLI_STACK_SIZE 1000 // only consumed with CLI build option
#define MIXER_TASK_PRIO 5
@ -55,4 +55,4 @@ inline void resetForcePowerOffRequest()
timeForcePowerOffPressed = 0;
}
#endif // _TASKS_ARM_H_
#endif // _TASKS_H_

View file

@ -21,14 +21,9 @@
#include "opentx.h"
uint8_t telemetryStreaming = 0;
uint8_t R9ModuleStreaming = 0;
uint8_t telemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; // Receive buffer. 9 bytes (full packet), worst case 18 bytes with byte-stuffing (+1)
uint8_t telemetryRxBufferCount = 0;
#if defined(WS_HOW_HIGH)
uint8_t wshhStreaming = 0;
#endif
uint8_t telemetryState = TELEMETRY_INIT;
TelemetryData telemetryData;
@ -210,7 +205,6 @@ void telemetryWakeup()
void telemetryInterrupt10ms()
{
if (TELEMETRY_STREAMING()) {
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
const TelemetrySensor & sensor = g_model.telemetrySensors[i];
@ -220,14 +214,6 @@ void telemetryInterrupt10ms()
}
}
#if defined(WS_HOW_HIGH)
if (wshhStreaming > 0) {
wshhStreaming--;
}
#endif
if (R9ModuleStreaming > 0) {
R9ModuleStreaming--;
}
if (telemetryStreaming > 0) {
telemetryStreaming--;
}

View file

@ -30,11 +30,6 @@
#endif
extern uint8_t telemetryStreaming; // >0 (true) == data is streaming in. 0 = no data detected for some time
extern uint8_t R9ModuleStreaming; // >0 (true) == R9 module is connected and sending data 0 = no data detected for some time
#if defined(WS_HOW_HIGH)
extern uint8_t wshhStreaming;
#endif
enum TelemetryStates {
TELEMETRY_INIT,

48
tools/extract-map.py Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/python3
import argparse
def line_index(lines, start):
for i, line in enumerate(lines):
if line.startswith(start):
return i
def extract_vars(lines):
result = []
lines = lines[line_index(lines, ".data"):line_index(lines, ".memory")]
i = 0
while i < len(lines):
line = lines[i]
i += 1
if line.startswith("*"):
continue
if line.startswith(" .data.") or line.startswith(" .bss."):
fields = (line + lines[i]).split()
# print(fields)
i += 1
var = fields[0].split(".")[-1]
offset = int(fields[1], 16)
size = int(fields[2], 16)
result.append((var, offset, size))
return result
def main():
parser = argparse.ArgumentParser(description="Extract firmware.map")
parser.add_argument("file", type=argparse.FileType("r"))
args = parser.parse_args()
f = args.file
lines = f.readlines()
vars = extract_vars(lines)
vars.sort(key=lambda var: "%08d %s" % (var[2], var[0]))
for var, offset, size in vars:
print("%s\t %d" % (var, size))
if __name__ == "__main__":
main()