1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-20 23:05:12 +03:00

Trims to Offsets re-implemented (still untested)

FrSky flash saving
This commit is contained in:
bsongis 2012-03-27 17:56:43 +00:00
parent ee1bd73788
commit 2acfb7df3d
15 changed files with 854 additions and 1773 deletions

View file

@ -7,16 +7,6 @@
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
@ -31,8 +21,6 @@
# Values: STD, V4, ARM
PCB = STD
# Following options for PCB=STD only (ignored otherwise) ...
# Enable JETI-Telemetry or FrSky Telemetry reception on UART0
# For this option you need to modify your hardware!
# More information at [insertURLhere]
@ -114,7 +102,6 @@ DEBUG = NO
# Define programs and commands.
SHELL = sh
IMG2LBM = python ../util/img2lbm.py
REV = $(shell sh -c "svnversion | egrep -o '[[:digit:]]+[[:alpha:]]*$$'")
@ -137,6 +124,7 @@ ifeq ($(PCB), ARM)
TRGT = arm-none-eabi-
MCU = cortex-m3
BOARDSRC = board_ersky9x.cpp
EEPROMSRC = eeprom_arm.cpp
CPPDEFS =
endif
@ -144,15 +132,11 @@ CC = $(TRGT)gcc
OBJCOPY = $(TRGT)objcopy
OBJDUMP = $(TRGT)objdump
SIZE = $(TRGT)size
#AS = $(TRGT)gcc -x assembler-with-cpp
#BIN = $(CP) -O ihex
#BINX = $(CP) -O binary
#NM = avr-nm
NM = $(TRGT)nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
#COPY = cp
#WINSHELL = cmd
# Processor frequency.
F_CPU = 16000000
@ -163,9 +147,6 @@ FORMAT = ihex
# Target file name (without extension).
TARGET = open9x
# Object files directory
OBJDIR = obj
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC = open9x.cpp pulses.cpp stamp.cpp menus.cpp model_menus.cpp general_menus.cpp main_views.cpp statistics_views.cpp $(EEPROMSRC) lcd.cpp drivers.cpp o9xstrings.cpp
@ -187,7 +168,6 @@ endif
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DBGFMT = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
@ -363,21 +343,9 @@ endif
CPPFLAGS = -g$(DBGFMT)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
#CPPFLAGS += -mint8
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -funsigned-char
#CPPFLAGS += -funsigned-bitfields
#CPPFLAGS += -fpack-struct
#CPPFLAGS += -fshort-enums
#CPPFLAGS += -fno-exceptions
#CPPFLAGS += -fno-unit-at-a-time
CPPFLAGS += -Wall
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wno-strict-aliasing
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
#CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
ifneq ($(PCB), ARM)
@ -388,47 +356,8 @@ ifneq ($(PCB), ARM)
CPPFLAGS += -fno-inline-small-functions
endif
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
@ -449,103 +378,21 @@ EXTMEMOPTS =
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
LDFLAGS += $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkII
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex:a
AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).bin:a
AVRDUDE_READ_FLASH = -U flash:r:$(TARGET).hex:r
AVRDUDE_READ_EEPROM = -U eeprom:r:$(TARGET).bin:r
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS = -B0.25 -p $(MCU) -c $(AVRDUDE_PROGRAMMER) -P $(AVRDUDE_PORT)
#AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
ifeq ($(ERAZE), NO)
AVRDUDE_FLAGS += -D
endif
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
DEBUG_UI = gdb
# DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
#DEBUG_BACKEND = avarice
DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_COMPILING = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
@ -628,68 +475,23 @@ end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
ifeq ($(PCB), ARM)
sizebefore:
sizeafter:
ELFSIZE = $(SIZE) $(TARGET).elf
else
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
endif
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi
endif
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
wflash: $(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
weeprom: $(TARGET).bin
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_EEPROM)
# Write flash and eeprom
wfe: $(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_EEPROM)
rflash: $(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FLASH)
reeprom: $(TARGET).bin
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_EEPROM)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
# gruvin: added extra include and lib paths to get simu working on my Mac
FOXINC=-I/usr/local/include/fox-1.6 -I/usr/include/fox-1.6 \
-I$(FOXPATH)/include \
@ -706,39 +508,6 @@ simu: $(BOARDSRC) $(CPPSRC) Makefile simu.cpp simpgmspace.cpp *.h *.lbm eeprom.b
eeprom.bin:
dd if=/dev/zero of=$@ bs=1 count=2048
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND),avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
ifeq ($(PCB), ARM)
@ -810,21 +579,15 @@ clean_list :
$(REMOVE) gtest_main.a
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVEDIR) $(OBJDIR)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) *.o
$(REMOVE) *.d
$(REMOVE) *.lst
$(REMOVE) allsrc.cpp
$(REMOVEDIR) .dep
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
#### GOOGLE TESTS

View file

@ -582,23 +582,7 @@ void board_init()
start_sound() ;
// init_spi() ; // TODO in eeprom_arm
}
/*TODO not here...*/
void eeDirty(uint8_t msk) { }
void eeCheck(bool immediately) {}
uint16_t eeLoadModelName(uint8_t id, char *name)
{
memset(name, 0, sizeof(g_model.name));
return 0;
}
int8_t eeFindEmptyModel(uint8_t id, bool down) { return 0;}
void eeLoadModel(uint8_t id) {}
void eeReadAll()
{
generalDefault();
modelDefault(0);
eeprom_init();
}
uint16_t getTmr2MHz()

File diff suppressed because it is too large Load diff

View file

@ -20,18 +20,33 @@
#include <inttypes.h>
#include <stdint.h>
extern uint8_t s_eeDirtyMsk;
extern uint16_t s_eeDirtyTime10ms;
extern void init_eeprom( void ) ;
// States in Eeprom32_process_state
#define E32_IDLE 1
#define E32_ERASESENDING 2
#define E32_ERASEWAITING 3
#define E32_WRITESENDING 4
#define E32_WRITEWAITING 5
#define E32_READSENDING 6
#define E32_READWAITING 7
#define E32_BLANKCHECK 8
#define E32_WRITESTART 9
extern uint8_t Eeprom32_process_state ;
extern uint32_t ee32_check_finished( void ) ;
extern void ee32StoreGeneral( void ) ;
extern void ee32StoreModel( uint8_t modelNumber, uint8_t trim ) ;
extern void eeprom_init( void ) ;
extern void end_spi(); // TODO not public
extern void ee32_process( void ) ;
extern bool ee32LoadGeneral( void ) ;
extern void ee32LoadModel(uint8_t id) ;
extern void ee32WaitLoadModel(uint8_t id) ;
extern void ee32_delete_model( uint8_t id ) ;
extern bool ee32ModelExists(uint8_t id) ;
extern uint32_t ee32_process( void ) ;
extern void eeWaitFinished();
extern void eeDeleteModel( uint8_t id ) ;
extern bool eeModelExists(uint8_t id) ;
extern bool eeCopyModel(uint8_t dst, uint8_t src);
extern void eeSwapModels(uint8_t id1, uint8_t id2);
#define DISPLAY_PROGRESS_BAR(x)
@ -44,7 +59,7 @@ struct t_file_entry
} ;
extern struct t_file_entry File_system[] ;
extern unsigned char ModelNames[][sizeof(g_model.name)] ; // Allow for general
extern char ModelNames[][sizeof(g_model.name)] ; // Allow for general
extern EEGeneral g_eeGeneral;
extern ModelData g_model;
@ -52,64 +67,5 @@ extern ModelData g_model;
extern uint8_t Spi_tx_buf[] ;
extern uint8_t Spi_rx_buf[] ;
/// fileId of general file
//#define FILE_GENERAL 0
/// convert model number 0..MAX_MODELS-1 int fileId
//#define FILE_MODEL(n) (1+n)
//#define FILE_TMP (1+16)
//bool EeFsOpen();
//int8_t EeFsck();
//void EeFsFormat();
//uint16_t EeFsGetFree();
//#define ERR_NONE 0
//#define ERR_FULL 1
//#define ERR_TMO 2
//class EFile
//{
// uint8_t m_fileId; //index of file in directory = filename
// uint16_t m_pos; //over all filepos
// uint8_t m_currBlk; //current block.id
// uint8_t m_ofs; //offset inside of the current block
// uint8_t m_bRlc; //control byte for run length decoder
// uint8_t m_err; //error reasons
// uint16_t m_stopTime10ms; //maximum point of time for writing
//public:
///remove contents of given file
// static void rm(uint8_t i_fileId);
///swap contents of file1 with them of file2
// static void swap(uint8_t i_fileId1,uint8_t i_fileId2);
///return true if the file with given fileid exists
// static bool exists(uint8_t i_fileId);
///open file for reading, no close necessary
///for writing use writeRlc() or create()
// uint8_t openRd(uint8_t i_fileId);
/// create a new file with given fileId,
/// !!! if this file already exists, then all blocks are reused
/// and all contents will be overwritten.
/// after writing closeTrunc has to be called
// void create(uint8_t i_fileId, uint8_t typ, uint16_t maxTme10ms);
/// close file and truncate the blockchain if to long.
// void closeTrunc();
///open file, write to file and close it.
///If file existed before, then contents is overwritten.
///If file was larger before, then unused blocks are freed
// uint16_t writeRlc(uint8_t i_fileId, uint8_t typ,uint8_t*buf,uint16_t i_len, uint8_t maxTme10ms);
// uint8_t read(uint8_t*buf,uint16_t i_len);
// uint8_t write(uint8_t*buf,uint8_t i_len);
///return size of compressed file without block overhead
// uint16_t size();
///read from opened file and decode rlc-coded data
// uint16_t readRlc(uint8_t*buf,uint16_t i_len);
///deliver current errno, this is reset in open
// uint8_t errno(){return m_err;}
//};
#endif
/*eof*/

View file

@ -296,7 +296,6 @@ void EFile::rm(uint8_t i_fileId)
EeFsFlushDirEnt(i_fileId);
if (i) EeFsFree(i); //chain in
s_sync_write = false;
}
uint16_t EFile::size()
@ -710,7 +709,7 @@ void eeLoadModel(uint8_t id)
}
#endif
if (sz == 0) {
if (sz < 256) {
// alert("Error Loading Model");
modelDefault(id);
eeCheck(true);
@ -725,17 +724,6 @@ void eeLoadModel(uint8_t id)
}
}
int8_t eeFindEmptyModel(uint8_t id, bool down)
{
int8_t i = id;
for (;;) {
i = (MAX_MODELS + (down ? i+1 : i-1)) % MAX_MODELS;
if (!EFile::exists(FILE_MODEL(i))) break;
if (i == id) return -1; // no free space in directory left
}
return i;
}
void eeReadAll()
{
if(!EeFsOpen() ||

View file

@ -179,5 +179,9 @@ inline void eeFlush() { theFile.flush(); }
uint16_t evalChkSum();
#define eeDeleteModel(x) EFile::rm(FILE_MODEL(x))
#define eeCopyModel(dst, src) theFile.copy(FILE_MODEL(dst), FILE_MODEL(src))
#define eeSwapModels(id1, id2) EFile::swap(FILE_MODEL(id1), FILE_MODEL(id2))
#endif
/*eof*/

View file

@ -179,7 +179,7 @@ void USART1_IRQHandler (void) { while(1); }
void MCI_IRQHandler (void) { while(1); }
// void TWI0_IRQHandler (void) { while(1); }
void TWI1_IRQHandler (void) { while(1); }
void SPI_IRQHandler (void) { while(1); }
// void SPI_IRQHandler (void) { while(1); }
void SSC_IRQHandler (void) { while(1); }
void TC0_IRQHandler (void) { while(1); }
void TC1_IRQHandler (void) { while(1); }

View file

@ -870,6 +870,32 @@ void displayGpsTime()
lcd_outdezNAtt(12*FW-1, TIME_LINE, frskyHubData.sec, att, 2);
lcd_status_line();
}
void displayGpsCoord(uint8_t y, char direction, int16_t bp, int16_t ap)
{
if (!direction) direction = '-';
lcd_outdezAtt(10*FW, y, bp / 100, LEFT); // ddd before '.'
lcd_putc(lcd_lastPos, y, '@');
uint8_t mn = bp % 100;
if (g_eeGeneral.gpsFormat == 0) {
lcd_putc(lcd_lastPos+FWNUM, y, direction);
lcd_outdezNAtt(lcd_lastPos+FW+FW+1, y, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_vline(lcd_lastPos, y, 2);
uint16_t ss = ap * 6;
lcd_outdezAtt(lcd_lastPos+3, y, ss / 1000, LEFT); // ''
lcd_plot(lcd_lastPos, y+FH-2, 0); // small decimal point
lcd_outdezAtt(lcd_lastPos+2, y, ss % 1000, LEFT); // ''
lcd_vline(lcd_lastPos, y, 2);
lcd_vline(lcd_lastPos+2, y, 2);
}
else {
lcd_outdezNAtt(lcd_lastPos+FW, y, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_plot(lcd_lastPos, y+FH-2, 0); // small decimal point
lcd_outdezNAtt(lcd_lastPos+2, y, ap, LEFT|UNSIGN|LEADING0, 4); // after '.'
lcd_putc(lcd_lastPos+1, y, direction);
}
}
#endif
uint8_t getTelemCustomField(uint8_t line, uint8_t col)
@ -1033,49 +1059,12 @@ void menuProcFrsky(uint8_t event)
else if (s_frsky_view == e_frsky_after_flight) {
// Latitude
#define LAT_LINE (1*FH+1)
lcd_putsLeft( LAT_LINE, STR_LATITUDE);
lcd_outdezAtt(10*FW, LAT_LINE, frskyHubData.gpsLatitude_bp / 100, LEFT); // ddd before '.'
lcd_putc(lcd_lastPos, LAT_LINE, '@');
uint8_t mn = frskyHubData.gpsLatitude_bp % 100;
if (g_eeGeneral.gpsFormat==1) {
lcd_outdezNAtt(lcd_lastPos+FW, LAT_LINE, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_plot(lcd_lastPos, LAT_LINE+FH-2, 0); // small decimal point
lcd_outdezNAtt(lcd_lastPos+2, LAT_LINE, frskyHubData.gpsLatitude_ap, LEFT|UNSIGN|LEADING0, 4); // after '.'
lcd_putc(lcd_lastPos+1, LAT_LINE, frskyHubData.gpsLatitudeNS ? frskyHubData.gpsLatitudeNS : '-');
} else {
lcd_putc(lcd_lastPos+FW, LAT_LINE, frskyHubData.gpsLatitudeNS ? frskyHubData.gpsLatitudeNS : '-');
lcd_outdezNAtt(lcd_lastPos+FW+FW, LAT_LINE, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_plot(lcd_lastPos, LAT_LINE, 0); // small decimal point
uint16_t ss=frskyHubData.gpsLatitude_ap*6;
lcd_outdezAtt(lcd_lastPos+2, LAT_LINE, ss / 1000, LEFT); // ''
lcd_plot(lcd_lastPos, LAT_LINE+FH-2, 0); // small decimal point
lcd_outdezAtt(lcd_lastPos+2, LAT_LINE, ss % 1000, LEFT); // ''
lcd_plot(lcd_lastPos, LAT_LINE, 0); // small decimal point
lcd_plot(lcd_lastPos+2, LAT_LINE, 0); // small decimal point
}
lcd_putsLeft(LAT_LINE, STR_LATITUDE);
displayGpsCoord(LAT_LINE, frskyHubData.gpsLatitudeNS, frskyHubData.gpsLatitude_bp, frskyHubData.gpsLatitude_ap);
// Longitude
#define LONG_LINE (2*FH+2)
lcd_putsLeft(LONG_LINE, STR_LONGITUDE);
lcd_outdezAtt(10*FW, LONG_LINE, frskyHubData.gpsLongitude_bp / 100, LEFT); // ddd before '.'
lcd_putc(lcd_lastPos, LONG_LINE, '@');
mn = frskyHubData.gpsLongitude_bp % 100;
if (g_eeGeneral.gpsFormat==1) {
lcd_outdezNAtt(lcd_lastPos+FW, LONG_LINE, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_plot(lcd_lastPos, LONG_LINE+FH-2, 0); // small decimal point
lcd_outdezNAtt(lcd_lastPos+2, LONG_LINE, frskyHubData.gpsLongitude_ap, LEFT|UNSIGN|LEADING0, 4); // after '.'
lcd_putc(lcd_lastPos+1, LONG_LINE, frskyHubData.gpsLongitudeEW ? frskyHubData.gpsLongitudeEW : '-');
} else {
lcd_putc(lcd_lastPos+FW, LONG_LINE, frskyHubData.gpsLongitudeEW ? frskyHubData.gpsLongitudeEW : '-');
lcd_outdezNAtt(lcd_lastPos+FW+FW, LONG_LINE, mn, LEFT|LEADING0, 2); // mm before '.'
lcd_plot(lcd_lastPos, LONG_LINE, 0); // small decimal point
uint16_t ss=frskyHubData.gpsLongitude_ap*6;
lcd_outdezAtt(lcd_lastPos+2, LONG_LINE, ss / 1000, LEFT); // ''
lcd_plot(lcd_lastPos, LONG_LINE+FH-2, 0); // small decimal point
lcd_outdezAtt(lcd_lastPos+2, LONG_LINE, ss % 1000, LEFT); // ''
lcd_plot(lcd_lastPos, LONG_LINE, 0); // small decimal point
lcd_plot(lcd_lastPos+2, LONG_LINE, 0); // small decimal point
}
displayGpsCoord(LONG_LINE, frskyHubData.gpsLongitudeEW, frskyHubData.gpsLongitude_bp, frskyHubData.gpsLongitude_ap);
// Rssi
#define RSSI_LINE (3*FH+3)
lcd_putsLeft(RSSI_LINE, STR_MINRSSI);

View file

@ -152,7 +152,17 @@ static uint8_t s_copyMode = 0;
static int8_t s_copySrcRow;
static int8_t s_copyTgtOfs;
// TODO add ARM code here...
inline int8_t eeFindEmptyModel(uint8_t id, bool down)
{
int8_t i = id;
for (;;) {
i = (MAX_MODELS + (down ? i+1 : i-1)) % MAX_MODELS;
if (!eeModelExists(i)) break;
if (i == id) return -1; // no free space in directory left
}
return i;
}
void menuProcModelSelect(uint8_t event)
{
TITLE(STR_MENUMODELSEL);
@ -163,9 +173,7 @@ void menuProcModelSelect(uint8_t event)
#endif
if (s_confirmation) {
#if !defined(PCBARM)
EFile::rm(FILE_MODEL(m_posVert)); // delete file
#endif
eeDeleteModel(m_posVert); // delete file
s_confirmation = 0;
s_copyMode = 0;
}
@ -173,12 +181,10 @@ void menuProcModelSelect(uint8_t event)
uint8_t _event = (s_warning ? 0 : event);
uint8_t _event_ = (IS_RE1_EVT(_event) ? 0 : _event);
#if !defined(PCBARM)
if (s_copyMode || !EFile::exists(FILE_MODEL(g_eeGeneral.currModel))) {
if (s_copyMode || !eeModelExists(g_eeGeneral.currModel)) {
if ((_event & 0x1f) == KEY_EXIT)
_event_ -= KEY_EXIT;
}
#endif
int8_t oldSub = m_posVert;
if (!check_submenu_simple(_event_, MAX_MODELS-1)) return;
@ -205,13 +211,11 @@ void menuProcModelSelect(uint8_t event)
s_editMode = -1;
break;
case EVT_KEY_LONG(KEY_EXIT):
#if !defined(PCBARM)
if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && EFile::exists(FILE_MODEL(sub))) {
if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) {
s_warning = STR_DELETEMODEL;
killEvents(_event);
break;
}
#endif
// no break
case EVT_KEY_BREAK(KEY_EXIT):
if (s_copyMode) {
@ -237,19 +241,15 @@ void menuProcModelSelect(uint8_t event)
uint8_t cur = (16 + sub + s_copyTgtOfs) % 16;
if (s_copyMode == COPY_MODE) {
#if !defined(PCBARM)
if (!theFile.copy(FILE_MODEL(cur), FILE_MODEL(s_copySrcRow)))
if (!eeCopyModel(cur, s_copySrcRow))
cur = sub;
#endif
}
s_copySrcRow = g_eeGeneral.currModel; // to update the currModel value
while (sub != cur) {
uint8_t src = cur;
cur = (s_copyTgtOfs > 0 ? cur+15 : cur+1) % 16;
#if !defined(PCBARM)
EFile::swap(FILE_MODEL(src), FILE_MODEL(cur));
#endif
eeSwapModels(src, cur);
if (src == s_copySrcRow)
s_copySrcRow = cur;
else if (cur == s_copySrcRow)
@ -281,11 +281,9 @@ void menuProcModelSelect(uint8_t event)
killEvents(event);
return;
}
#if !defined(PCBARM)
else if (EFile::exists(FILE_MODEL(sub))) {
else if (eeModelExists(sub)) {
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
}
#endif
break;
case EVT_KEY_FIRST(KEY_LEFT):
case EVT_KEY_FIRST(KEY_RIGHT):
@ -322,8 +320,8 @@ void menuProcModelSelect(uint8_t event)
break;
}
lcd_puts(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE);
#if !defined(PCBARM)
lcd_puts(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE);
lcd_outdezAtt( 17*FW, 0, EeFsGetFree(),0);
#endif
@ -332,8 +330,6 @@ void menuProcModelSelect(uint8_t event)
if (sub-s_pgOfs < 1) s_pgOfs = max(0, sub-1);
else if (sub-s_pgOfs > 5) s_pgOfs = min(MAX_MODELS-7, sub-4);
// printf("copy_mode=%d s_copySrcRow=%d s_copyTgtOfs=%d sub=%d\n", s_copyMode, s_copySrcRow, s_copyTgtOfs, sub); fflush(stdout);
for (uint8_t i=0; i<7; i++) {
uint8_t y=(i+1)*FH;
uint8_t k=i+s_pgOfs;
@ -357,14 +353,16 @@ void menuProcModelSelect(uint8_t event)
k %= 16;
#if !defined(PCBARM)
if (EFile::exists(FILE_MODEL(k))) {
if (eeModelExists(k)) {
#if defined(PCBARM)
putsModelName(4*FW, y, ModelNames[k], k, 0);
#else
uint16_t size = eeLoadModelName(k, reusableBuffer.model_name);
putsModelName(4*FW, y, reusableBuffer.model_name, k, 0);
lcd_outdezAtt(20*FW, y, size, 0);
#endif
if (k==g_eeGeneral.currModel && (s_copySrcRow<0 || i+s_pgOfs!=sub)) lcd_putc(1, y, '*');
}
#endif
if (s_copyMode && sub==i+s_pgOfs) {
lcd_filled_rect(9, y, DISPLAY_W-1-9, 7);
@ -373,8 +371,12 @@ void menuProcModelSelect(uint8_t event)
}
if (s_warning) {
#if defined(PCBARM)
s_warning_info = ModelNames[sub];
#else
eeLoadModelName(sub, reusableBuffer.model_name);
s_warning_info = reusableBuffer.model_name;
#endif
s_warning_info_len = sizeof(g_model.name);
displayConfirmation(event);
}
@ -448,6 +450,9 @@ void menuProcModel(uint8_t event)
if(s_pgOfs<subN) {
lcd_puts(0*FW, y, STR_NAME);
EditName(PARAM_OFS, y, g_model.name, sizeof(g_model.name), event, sub==subN, m_posHorz);
#if defined(PCBARM)
memcpy(ModelNames[g_eeGeneral.currModel], g_model.name, sizeof(g_model.name));
#endif
if((y+=FH)>7*FH) return;
} subN++;
@ -1568,7 +1573,7 @@ void menuProcMixAll(uint8_t event)
void menuProcLimits(uint8_t event)
{
MENU(STR_MENULIMITS, menuTabModel, e_Limits, NUM_CHNOUT+1, {0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3});
MENU(STR_MENULIMITS, menuTabModel, e_Limits, 1+NUM_CHNOUT+1, {0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3/*, 0*/});
int8_t sub = m_posVert - 1;
@ -1576,6 +1581,18 @@ void menuProcLimits(uint8_t event)
uint8_t y = (i+1)*FH;
uint8_t k = i+s_pgOfs;
if (k==NUM_CHNOUT) {
// last line available - add the "copy trim menu" line
uint8_t attr = (sub==NUM_CHNOUT) ? INVERS : 0;
lcd_putsAtt(3*FW, y, STR_TRIMS2OFFSETS, s_noHi ? 0 : attr);
if (attr && event==EVT_KEY_LONG(KEY_MENU)) {
s_noHi = NO_HI_LEN;
killEvents(event);
moveTrimsToOffsets(); // if highlighted and menu pressed - move trims to offsets
}
return;
}
LimitData *ld = limitaddress(k) ;
int16_t v = (ld->revert) ? -ld->offset : ld->offset;

View file

@ -107,7 +107,7 @@ PACK(typedef struct t_EEGeneral {
uint8_t disableAlarmWarning:1;
uint8_t stickMode:2;
int8_t timezone:5;
uint8_t spare:1;
uint8_t spare2:1;
uint8_t inactivityTimer;
uint8_t throttleReversed:1;
uint8_t minuteBeep:1;
@ -120,11 +120,11 @@ PACK(typedef struct t_EEGeneral {
uint8_t lightAutoOff;
uint8_t templateSetup; //RETA order according to chout_ar array
int8_t PPM_Multiplier;
uint8_t spare2[2];
uint8_t spare3[2];
int8_t beeperLength:3;
uint8_t hapticStrength:3;
uint8_t gpsFormat:1;
uint8_t spare3:1;
uint8_t spare4:1;
uint8_t speakerPitch;
}) EEGeneral;

View file

@ -224,7 +224,7 @@ const pm_char STR_BADEEPROMDATA[] PROGMEM = TR_BADEEPROMDATA;
const pm_char STR_EEPROMFORMATTING[] PROGMEM = TR_EEPROMFORMATTING;
const pm_char STR_EEPROMOVERFLOW[] PROGMEM = TR_EEPROMOVERFLOW;
const pm_char STR_MENUSERROR[] PROGMEM = TR_MENUSERROR;
const pm_char STR_TRIMS2OFFSETS[] PROGMEM = TR_TRIMS2OFFSETS;
const pm_char STR_MENURADIOSETUP[] PROGMEM = TR_MENURADIOSETUP;
#ifdef PCBV4

View file

@ -305,6 +305,7 @@ extern const pm_char STR_BADEEPROMDATA[];
extern const pm_char STR_EEPROMFORMATTING[];
extern const pm_char STR_EEPROMOVERFLOW[];
extern const pm_char STR_MENUSERROR[];
extern const pm_char STR_TRIMS2OFFSETS[];
extern const pm_char STR_MENURADIOSETUP[];
extern const pm_char STR_MENUDATEANDTIME[];
extern const pm_char STR_MENUTRAINER[];

View file

@ -356,6 +356,32 @@ void applyExpos(int16_t *anas, uint8_t phase)
}
}
int16_t applyLimits(uint8_t channel, int32_t value)
{
int16_t ofs = g_model.limitData[channel].offset;
int16_t lim_p = 10 * (g_model.limitData[channel].max + 100);
int16_t lim_n = 10 * (g_model.limitData[channel].min - 100); //multiply by 10 to get same range as ofs (-1000..1000)
if (ofs > lim_p) ofs = lim_p;
if (ofs < lim_n) ofs = lim_n;
if (value) value =
(value > 0) ? value * ((int32_t) lim_p - ofs) / 100000 :
-value * ((int32_t) lim_n - ofs) / 100000; //div by 100000 -> output = -1024..1024
// TODO work on an int16_t as soon as possible ...
value += calc1000toRESX(ofs);
lim_p = calc1000toRESX(lim_p);
lim_n = calc1000toRESX(lim_n);
if (value > lim_p) value = lim_p;
if (value < lim_n) value = lim_n;
if (g_model.limitData[channel].revert) value = -value; // finally do the reverse.
if (safetyCh[channel] != -128) // if safety channel available for channel check and replace val if needed
value = calc100toRESX(safetyCh[channel]);
return value;
}
int16_t ex_chans[NUM_CHNOUT] = {0}; // Outputs (before LIMITS) of the last perMain
#ifdef HELI
int16_t cyc_anas[3] = {0};
@ -1114,6 +1140,7 @@ FORCEINLINE void evalTrims(uint8_t phase)
{
for (uint8_t i=0; i<NUM_STICKS; i++) {
// do trim -> throttle trim if applicable
// TODO avoid int32_t vv
int32_t vv = 2*RESX;
int16_t trim = getTrimValue(getTrimFlightPhase(i, phase), i);
if (i==THR_STICK && g_model.thrTrim) {
@ -1130,9 +1157,19 @@ FORCEINLINE void evalTrims(uint8_t phase)
}
}
bool s_noTrainerInput = false;
enum PerOutMode {
e_perout_mode_normal = 0,
e_perout_mode_trims,
e_perout_mode_zeros,
e_instant_trim
};
uint8_t s_perout_mode = e_perout_mode_normal;
uint8_t evalSticks(uint8_t phase)
{
uint8_t anaCenter = 0;
#ifdef HELI
uint16_t d = 0;
if (g_model.swashR.value) {
@ -1145,8 +1182,6 @@ uint8_t evalSticks(uint8_t phase)
}
#endif
uint8_t anaCenter = 0;
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
// normalization [0..2048] -> [-1024..1024]
@ -1171,7 +1206,7 @@ uint8_t evalSticks(uint8_t phase)
if (tmp <= 1) anaCenter |= (tmp==0 ? 1<<ch : bpanaCenter & (1<<ch));
if (ch < NUM_STICKS) { //only do this for sticks
if (!s_noTrainerInput && (isFunctionActive(FUNC_TRAINER) || isFunctionActive(FUNC_TRAINER_RUD+ch))) {
if (s_perout_mode==e_perout_mode_normal && (isFunctionActive(FUNC_TRAINER) || isFunctionActive(FUNC_TRAINER_RUD+ch))) {
// trainer mode
TrainerMix* td = &g_eeGeneral.trainer.mix[ch];
if (td->mode) {
@ -1277,6 +1312,7 @@ void perOut(uint8_t phase)
{
uint8_t anaCenter = evalSticks(phase);
if (s_perout_mode == e_perout_mode_normal) {
//===========BEEP CENTER================
anaCenter &= g_model.beepANACenter;
if(((bpanaCenter ^ anaCenter) & anaCenter)) AUDIO_POT_STICK_MIDDLE();
@ -1347,15 +1383,16 @@ void perOut(uint8_t phase)
}
#endif
memset(chans, 0, sizeof(chans)); // All outputs to 0
s_trimPtr[0] = NULL;
s_trimPtr[1] = NULL;
s_trimPtr[2] = NULL;
s_trimPtr[3] = NULL;
}
memset(chans, 0, sizeof(chans)); // All outputs to 0
//========== MIXER LOOP ===============
mixWarning = 0;
mixWarning = 0; // TODO should be in a local variable on stack
for (uint8_t i=0; i<MAX_MIXERS; i++) {
MixData *md = mixaddress( i ) ;
@ -1380,6 +1417,11 @@ void perOut(uint8_t phase)
//Notice 0 = NC switch means not used -> always on line
uint8_t k = md->srcRaw-1;
int16_t v = 0;
if (s_perout_mode != e_perout_mode_normal) {
if (!sw || k >= NUM_STICKS || (k == THR_STICK && g_model.thrTrim))
continue;
}
else {
if (k < NUM_STICKS)
v = anas[k]; //Switch is on. MAX=FULL=512 or value.
else if (k>=MIXSRC_CH1-1 && k<=MIXSRC_CH16-1 && k-MIXSRC_CH1+1<md->destCh) // if we've already calculated the value - take it instead
@ -1389,13 +1431,16 @@ void perOut(uint8_t phase)
if (v<0 && !md->swtch)
sw = false;
}
else
else {
v = getValue(k <= MIXSRC_3POS ? k : k-MAX_SWITCH);
}
}
//========== DELAYS ===============
uint8_t swTog;
if (sw) { // switch on? (if no switch selected => on)
swTog = !swOn[i];
if (s_perout_mode == e_perout_mode_normal) {
swOn[i] = true;
if (md->delayUp) {
if (swTog) {
@ -1413,6 +1458,7 @@ void perOut(uint8_t phase)
}
if (md->mixWarn) mixWarning |= 1<<(md->mixWarn-1); // Mix warning
}
}
else {
bool has_delay = false;
swTog = swOn[i];
@ -1445,7 +1491,7 @@ void perOut(uint8_t phase)
if(md->sOffset) v += calc100toRESX(md->sOffset);
//========== SPEED ===============
if (md->speedUp || md->speedDown) // there are delay values
if (s_perout_mode==e_perout_mode_normal && (md->speedUp || md->speedDown)) // there are delay values
{
#define DEL_MULT 256
@ -1473,11 +1519,12 @@ void perOut(uint8_t phase)
v = applyCurve(v, md->curve);
//========== TRIMS ===============
// TODO use k?
if (md->srcRaw>0 && md->srcRaw<=NUM_STICKS) {
if (md->carryTrim == TRIM_ON) {
if (s_perout_mode < e_perout_mode_zeros && md->carryTrim == TRIM_ON) {
v += trims[md->srcRaw-1];
}
if (md->carryTrim == TRIM_OFFSET) {
if (s_perout_mode == e_perout_mode_normal && md->carryTrim == TRIM_OFFSET) {
v = md->sOffset;
v = calc1000toRESX(v << 3);
s_trimPtr[md->srcRaw-1] = &md->sOffset; // use the value stored here for the trim
@ -1579,32 +1626,23 @@ void perMain()
int32_t q = (s_fade_flight_phases ? (sum_chans512[i] / weight) * 16 : chans[i]);
ex_chans[i] = q / 100; // for the next perMain
int16_t ofs = g_model.limitData[i].offset;
int16_t lim_p = 10*(g_model.limitData[i].max+100);
int16_t lim_n = 10*(g_model.limitData[i].min-100); //multiply by 10 to get same range as ofs (-1000..1000)
if (ofs>lim_p) ofs = lim_p;
if(ofs<lim_n) ofs = lim_n;
if (q) q = (q>0) ?
q*((int32_t)lim_p-ofs)/100000 :
-q*((int32_t)lim_n-ofs)/100000 ; //div by 100000 -> output = -1024..1024
q += calc1000toRESX(ofs);
lim_p = calc1000toRESX(lim_p);
lim_n = calc1000toRESX(lim_n);
if(q>lim_p) q = lim_p;
if(q<lim_n) q = lim_n;
if(g_model.limitData[i].revert) q=-q;// finally do the reverse.
if (safetyCh[i] != -128) // if safety channel available for channel check and replace val if needed
q = calc100toRESX(safetyCh[i]);
int16_t value = applyLimits(i, q);
cli();
g_chans512[i] = q; //copy consistent word to int-level
g_chans512[i] = value; // copy consistent word to int-level
sei();
}
#if !defined(PCBARM)
// TODO same code here + integrate the timer which could be common
#if defined(PCBARM)
if ( Tenms ) {
Tenms = 0 ;
if (Eeprom32_process_state != E32_IDLE)
ee32_process();
else if (s_eeDirtyMsk)
eeCheck();
}
#else
if (!eeprom_buffer_size) {
if (theFile.isWriting())
theFile.nextWriteStep();
@ -2161,9 +2199,9 @@ void instantTrim()
if (i!=THR_STICK) {
// don't instant trim the throttle stick
uint8_t trim_phase = getTrimFlightPhase(i, phase);
s_noTrainerInput = true;
s_perout_mode = e_instant_trim;
evalSticks(phase);
s_noTrainerInput = false;
s_perout_mode = e_perout_mode_normal;
int16_t trim = (anas[i] + trims[i]) / 2;
if (trim < TRIM_EXTENDED_MIN) {
trim = TRIM_EXTENDED_MIN;
@ -2179,6 +2217,47 @@ void instantTrim()
AUDIO_WARNING2();
}
void moveTrimsToOffsets() // copy state of 3 primary to subtrim
{
int16_t zeros[NUM_CHNOUT];
uint8_t phase = getFlightPhase();
s_perout_mode = e_perout_mode_zeros;
perOut(phase); // do output loop - zero input sticks and trims
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
zeros[i] = applyLimits(i, chans[i]);
}
s_perout_mode = e_perout_mode_trims;
perOut(phase); // do output loop - only trims
s_perout_mode = e_perout_mode_normal;
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
int16_t output = applyLimits(i, chans[i]);
int16_t v = g_model.limitData[i].offset;
// TODO flash saving?
v += g_model.limitData[i].revert ?
(zeros[i] - output) :
(output - zeros[i]);
// TODO * 125 / 128 ?
g_model.limitData[i].offset = limit((int16_t)-1000, (int16_t)v, (int16_t)1000); // make sure the offset doesn't go haywire
}
// reset all trims, except throttle
for (uint8_t i=0; i<NUM_STICKS; i++) {
if (i!=THR_STICK) {
for (uint8_t phase=0; phase<MAX_PHASES; phase++) {
int16_t trim = getTrimValue(phase, i);
if (trim <= TRIM_EXTENDED_MAX)
setTrimValue(phase, i, 0);
}
}
}
STORE_MODELVARS;
AUDIO_WARNING2();
}
#if defined (PCBV4)
// Rotary encoder interrupts
volatile uint8_t g_rotenc[2] = {0};
@ -2454,7 +2533,7 @@ int main(void)
// BEFORE calling sam_boot()
// TODO needed for REVB soft_power_off() ;
// TODO not started end_ppm_capture() ;
// TODO in eeprom_arm ... end_spi() ;
end_spi() ; // TODO in eeprom_arm ...
end_sound() ;
TC0->TC_CHANNEL[2].TC_IDR = TC_IDR0_CPCS ;
NVIC_DisableIRQ(TC2_IRQn) ;

View file

@ -726,6 +726,7 @@ extern void deleteExpoMix(uint8_t expo, uint8_t idx);
extern void incSubtrim(uint8_t idx, int16_t inc);
extern void instantTrim();
extern void moveTrimsToOffsets();
extern uint16_t active_functions;
inline bool isFunctionActive(uint8_t func)
@ -791,9 +792,9 @@ union ReusableBuffer
{
#if !defined(PCBARM)
uint8_t eefs_buffer[BLOCKS]; // used by EeFsck
#endif
char model_name[sizeof(g_model.name)]; // used by menuProcModelSelect
#endif
struct
{

View file

@ -289,6 +289,7 @@
#define TR_MENUANA "ANA"
#define TR_MENUCALIBRATION "CALIBRATION"
#define TR_MENUSERROR "MENUS OVERFLOW"
#define TR_TRIMS2OFFSETS "Trims => Offsets"
#define TR_MENUMODELSEL "MODELSEL"
#define TR_MENUSETUP "SETUP"
#define TR_MENUFLIGHTPHASE "FLIGHT PHASE"