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:
parent
ee1bd73788
commit
2acfb7df3d
15 changed files with 854 additions and 1773 deletions
257
src/Makefile
257
src/Makefile
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
1302
src/eeprom_arm.cpp
1302
src/eeprom_arm.cpp
File diff suppressed because it is too large
Load diff
|
@ -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*/
|
||||
|
||||
|
|
|
@ -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() ||
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[];
|
||||
|
|
149
src/open9x.cpp
149
src/open9x.cpp
|
@ -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) ;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue