diff --git a/src/Makefile b/src/Makefile index 63808024e..e652eb3e4 100644 --- a/src/Makefile +++ b/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 -# 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 diff --git a/src/board_ersky9x.cpp b/src/board_ersky9x.cpp index 565350c6e..3f203181a 100644 --- a/src/board_ersky9x.cpp +++ b/src/board_ersky9x.cpp @@ -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() diff --git a/src/eeprom_arm.cpp b/src/eeprom_arm.cpp index d6e88732d..c00775f0a 100644 --- a/src/eeprom_arm.cpp +++ b/src/eeprom_arm.cpp @@ -22,6 +22,8 @@ #include "string.h" volatile uint32_t Spi_complete ; +uint8_t s_eeDirtyMsk; +uint16_t s_eeDirtyTime10ms; // Logic for storing to EERPOM/loading from EEPROM // If main needs to wait for the eeprom, call mainsequence without actioning menus @@ -40,7 +42,7 @@ volatile uint32_t Spi_complete ; - +#define WRITE_DELAY_10MS 100 // These may not be needed, or might just be smaller uint8_t Spi_tx_buf[24] ; @@ -49,7 +51,7 @@ uint8_t Spi_rx_buf[24] ; struct t_file_entry File_system[MAX_MODELS+1] ; -unsigned char ModelNames[MAX_MODELS+1][sizeof(g_model.name)] ; // Allow for general +char ModelNames[MAX_MODELS][sizeof(g_model.name)] ; // Allow for general //static uint32_t Eeprom_image_updated ; // Ram image changed @@ -61,7 +63,7 @@ unsigned char ModelNames[MAX_MODELS+1][sizeof(g_model.name)] ; // Allow for gen //static uint8_t Eeprom_write_pending ; //static uint8_t Eeprom_writing_block_no ; - +// TODO check everything here uint8_t Eeprom32_process_state ; uint8_t Eeprom32_state_after_erase ; uint8_t Eeprom32_write_pending ; @@ -75,13 +77,6 @@ uint32_t Eeprom32_data_size ; uint16_t General_timer ; uint16_t Model_timer ; uint32_t Update_timer ; -uint8_t General_dirty ; -uint8_t Model_dirty ; - -uint8_t Ee32_general_write_pending ; -uint8_t Ee32_model_write_pending ; -uint8_t Ee32_model_delete_pending ; - // States in Eeprom_process_state @@ -92,44 +87,24 @@ uint8_t Ee32_model_delete_pending ; //#define E_WRITEWAITING 5 //#define E_32ACTIVE 6 -#define EE_WAIT 0 +#define EE_WAIT 0 #define EE_NO_WAIT 1 - -// 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 - //#define E32_READING 10 // Set elsewhere as a lock +void eeDirty(uint8_t msk) +{ + s_eeDirtyMsk |= msk; + s_eeDirtyTime10ms = get_tmr10ms() ; +} void handle_serial( void ) ; -//void hello( void ) ; -//void dbl9x( void ) ; -//uint32_t read_switch( enum EnumKeys enuk ) ; -//uint32_t read_eeprom_block( uint32_t block_no, uint32_t immediate ) ; -//uint32_t write_eeprom_block( uint32_t block_no, uint32_t sub_no, uint32_t size, uint32_t immediate ) ; -//uint32_t eeprom_image_blank( uint32_t image_index ) ; -bool ee32ModelExists(uint8_t id) ; uint32_t get_current_block_number( uint32_t block_no, uint16_t *p_size, uint32_t *p_seq ) ; uint32_t read32_eeprom_data( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate ) ; uint32_t write32_eeprom_block( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate ) ; void ee32_read_model_names( void ) ; -void ee32LoadModelName(uint8_t id, unsigned char*buf,uint8_t len) ; -void ee32_update_name( uint32_t id, uint8_t *source ) ; - - - -void eeprom_process( void ) ; -uint32_t ee32_process( void ) ; +void ee32LoadModelName(uint8_t id, char *buf, uint8_t len) ; // New file system @@ -150,273 +125,224 @@ struct t_eeprom_header uint8_t hcsum ; } ; -// Structure of data in a block -struct t_eeprom_block -{ - struct t_eeprom_header header ; - union - { - uint8_t bytes[4088] ; - uint32_t words[1022] ; - } data ; -} ; - -//struct t_gen_buf -//{ -// struct t_eeprom_header header ; -// EEGeneral data ; -//} ; - -//struct t_model_buf -//{ -// struct t_eeprom_header header ; -// ModelData data ; -//} ; - #define EEPROM_BUFFER_SIZE ((sizeof(ModelData) + sizeof( struct t_eeprom_header ) + 3)/4) - struct t_eeprom_buffer { - struct t_eeprom_header header ; - union t_eeprom_data - { - EEGeneral general_data ; - ModelData model_data ; - uint32_t words[ EEPROM_BUFFER_SIZE ] ; - } data ; + struct t_eeprom_header header ; + union t_eeprom_data + { + EEGeneral general_data ; + ModelData model_data ; + uint32_t words[ EEPROM_BUFFER_SIZE ] ; + } data ; } Eeprom_buffer ; +#define EEPROM_BUFFER_SIZE ((sizeof(ModelData) + sizeof( struct t_eeprom_header ) + 3)/4) -//union t_eeprom_buffer -//{ -// struct t_gen_buf eeGeneral_buffer ; -// struct t_model_buf eeModel_buffer ; -// uint32_t words[ EEPROM_BUFFER_SIZE ] ; -//} Eeprom_buffer ; - - - -//struct t_eeprom_block E_images[2] ; - -// Check all 4096 bytes of an image to see if they are blank -//uint32_t eeprom_image_blank( uint32_t image_index ) -//{ -// register uint32_t x ; -// register uint32_t *p ; - -// p = &E_images[image_index].sequence_no ; - -// for ( x = 0 ; x < 1024 ; x += 1 ) -// { -// if ( *p++ != 0xFFFFFFFF ) -// { -// return 0 ; -// } -// } -// return 1 ; -//} - -// genaral data needs to be written to EEPROM -void ee32StoreGeneral() +void eeDeleteModel(uint8_t id) { - General_dirty = 1 ; - General_timer = 500 ; // 5 seconds timeout before writing + eeCheck(true); + + memset(ModelNames[id], ' ', sizeof(g_model.name)); + + Eeprom32_source_address = (uint8_t *)&g_model ; // Get data from here + Eeprom32_data_size = 0 ; // This much + Eeprom32_file_index = id + 1 ; // This file system entry + Eeprom32_process_state = E32_BLANKCHECK ; + eeWaitFinished(); } - -// Store model to EEPROM, trim is non-zero if this is the result of a trim change -void ee32StoreModel( uint8_t modelNumber, uint8_t trim ) +bool eeCopyModel(uint8_t dst, uint8_t src) { - Model_dirty = modelNumber + 1 ; - Model_timer = 500 ; - ee32_update_name( Model_dirty, (uint8_t *)&g_model ) ; // In case it's changed + // eeCheck(true) should have been called before entering here + + uint16_t size = File_system[src+1].size ; + read32_eeprom_data( (File_system[src+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&Eeprom_buffer.data.model_data, size, 0 ) ; + + memcpy(ModelNames[dst], Eeprom_buffer.data.model_data.name, sizeof(g_model.name)); + + Eeprom32_source_address = (uint8_t *)&Eeprom_buffer.data.model_data; // Get data from here + Eeprom32_data_size = sizeof(g_model) ; // This much + Eeprom32_file_index = dst + 1 ; // This file system entry + Eeprom32_process_state = E32_BLANKCHECK ; + eeWaitFinished(); + return true; } -void ee32_delete_model( uint8_t id ) +void eeSwapModels(uint8_t id1, uint8_t id2) { - uint8_t buffer[sizeof(g_model.name)] ; - memset( buffer, ' ', sizeof(g_model.name) ) ; - ee32_update_name( id + 1, buffer ) ; - Ee32_model_delete_pending = id + 1 ; -} + // eeCheck(true) should have been called before entering here + // id2 must exist -void ee32_read_model_names() -{ - uint32_t i ; + uint16_t id1_size = File_system[id1+1].size; + uint32_t id1_block_no = File_system[id1+1].block_no; - for ( i = 1 ; i <= MAX_MODELS ; i += 1 ) - { - ee32LoadModelName( i, ModelNames[i], sizeof(g_model.name) ) ; - } -} + eeCopyModel(id1, id2); -void ee32_update_name( uint32_t id, uint8_t *source ) -{ - uint8_t * p ; - uint32_t i ; + // block_no has been shifted now, but we have the size + read32_eeprom_data( (id1_block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&Eeprom_buffer.data.model_data, id1_size, 0 ) ; - p = ModelNames[id] ; - for ( i = 0 ; i < sizeof(g_model.name) ; i += 1 ) - { - *p++ = *source++ ; - } + // TODO flash saving with function above ... + memcpy(ModelNames[id2], Eeprom_buffer.data.model_data.name, sizeof(g_model.name)); + + Eeprom32_source_address = (uint8_t *)&Eeprom_buffer.data.model_data; // Get data from here + Eeprom32_data_size = sizeof(g_model) ; // This much + Eeprom32_file_index = id2 + 1 ; // This file system entry + Eeprom32_process_state = E32_BLANKCHECK ; + eeWaitFinished(); } uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count ) { - register Spi *spiptr ; -// register uint32_t result ; - register uint32_t condition ; - static uint8_t discard_rx_command[4] ; + register Spi *spiptr ; + register uint32_t condition ; + static uint8_t discard_rx_command[4] ; // PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI - Spi_complete = 0 ; - if ( comlen > 4 ) - { - Spi_complete = 1 ; - return 0x4FFFF ; - } - condition = SPI_SR_TXEMPTY ; - spiptr = SPI ; - spiptr->SPI_CR = 1 ; // Enable - (void) spiptr->SPI_RDR ; // Dump any rx data - (void) spiptr->SPI_SR ; // Clear error flags - spiptr->SPI_RPR = (uint32_t)discard_rx_command ; - spiptr->SPI_RCR = comlen ; - if ( rx ) - { - spiptr->SPI_RNPR = (uint32_t)rx ; - spiptr->SPI_RNCR = count ; - condition = SPI_SR_RXBUFF ; - } - spiptr->SPI_TPR = (uint32_t)command ; - spiptr->SPI_TCR = comlen ; - if ( tx ) - { - spiptr->SPI_TNPR = (uint32_t)tx ; - } - else - { - spiptr->SPI_TNPR = (uint32_t)rx ; - } - spiptr->SPI_TNCR = count ; + Spi_complete = 0 ; + if ( comlen > 4 ) + { + Spi_complete = 1 ; + return 0x4FFFF ; + } + condition = SPI_SR_TXEMPTY ; + spiptr = SPI ; + spiptr->SPI_CR = 1 ; // Enable + (void) spiptr->SPI_RDR ; // Dump any rx data + (void) spiptr->SPI_SR ; // Clear error flags + spiptr->SPI_RPR = (uint32_t)discard_rx_command ; + spiptr->SPI_RCR = comlen ; + if ( rx ) + { + spiptr->SPI_RNPR = (uint32_t)rx ; + spiptr->SPI_RNCR = count ; + condition = SPI_SR_RXBUFF ; + } + spiptr->SPI_TPR = (uint32_t)command ; + spiptr->SPI_TCR = comlen ; + if ( tx ) + { + spiptr->SPI_TNPR = (uint32_t)tx ; + } + else + { + spiptr->SPI_TNPR = (uint32_t)rx ; + } + spiptr->SPI_TNCR = count ; - spiptr->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN ; // Start transfers + spiptr->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN ; // Start transfers - // Wait for things to get started, avoids early interrupt - for ( count = 0 ; count < 1000 ; count += 1 ) - { - if ( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 ) - { - break ; - } - } - spiptr->SPI_IER = condition ; + // Wait for things to get started, avoids early interrupt + for ( count = 0 ; count < 1000 ; count += 1 ) + { + if ( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 ) + { + break ; + } + } + spiptr->SPI_IER = condition ; - return 0 ; + return 0 ; } uint32_t eeprom_write_one( uint8_t byte, uint8_t count ) { - register Spi *spiptr ; - register uint32_t result ; + register Spi *spiptr; + register uint32_t result; - spiptr = SPI ; - spiptr->SPI_CR = 1 ; // Enable - (void) spiptr->SPI_RDR ; // Dump any rx data + spiptr = SPI; + spiptr->SPI_CR = 1; // Enable + (void) spiptr->SPI_RDR; // Dump any rx data - spiptr->SPI_TDR = byte ; + spiptr->SPI_TDR = byte; - result = 0 ; - while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 ) - { - // wait for received - if ( ++result > 10000 ) - { - break ; - } - } - if ( count == 0 ) - { - spiptr->SPI_CR = 2 ; // Disable - return spiptr->SPI_RDR ; - } - (void) spiptr->SPI_RDR ; // Dump the rx data - spiptr->SPI_TDR = 0 ; - result = 0 ; - while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 ) - { - // wait for received - if ( ++result > 10000 ) - { - break ; - } - } - spiptr->SPI_CR = 2 ; // Disable - return spiptr->SPI_RDR ; + result = 0; + while ((spiptr->SPI_SR & SPI_SR_RDRF) == 0) { + // wait for received + if (++result > 10000) { + break; + } + } + if (count == 0) { + spiptr->SPI_CR = 2; // Disable + return spiptr->SPI_RDR; + } + (void) spiptr->SPI_RDR; // Dump the rx data + spiptr->SPI_TDR = 0; + result = 0; + while ((spiptr->SPI_SR & SPI_SR_RDRF) == 0) { + // wait for received + if (++result > 10000) { + break; + } + } + spiptr->SPI_CR = 2; // Disable + return spiptr->SPI_RDR ; } void eeprom_write_enable() { - eeprom_write_one( 6, 0 ) ; + eeprom_write_one( 6, 0 ) ; +} + +uint32_t eeprom_read_status() +{ + return eeprom_write_one( 5, 1 ) ; } // Read eeprom data starting at random address uint32_t read32_eeprom_data( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate ) { - register uint8_t *p ; - register uint32_t x ; + register uint8_t *p ; + register uint32_t x ; - p = Spi_tx_buf ; - *p = 3 ; // Read command - *(p+1) = eeAddress >> 16 ; - *(p+2) = eeAddress >> 8 ; - *(p+3) = eeAddress ; // 3 bytes address - spi_PDC_action( p, 0, buffer, 4, size ) ; + p = Spi_tx_buf ; + *p = 3 ; // Read command + *(p+1) = eeAddress >> 16 ; + *(p+2) = eeAddress >> 8 ; + *(p+3) = eeAddress ; // 3 bytes address + spi_PDC_action( p, 0, buffer, 4, size ) ; - if ( immediate ) - { - return 0 ; - } - for ( x = 0 ; x < 100000 ; x += 1 ) - { - if ( Spi_complete ) - { - break ; - } - } - return x ; + if ( immediate ) + { + return 0 ; + } + for ( x = 0 ; x < 100000 ; x += 1 ) + { + // TODO while + ERROR_TIMEOUT + if ( Spi_complete ) + { + break ; + } + } + return x ; } - uint32_t write32_eeprom_block( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate ) { - register uint8_t *p ; - register uint32_t x ; + register uint8_t *p; + register uint32_t x; - eeprom_write_enable() ; + eeprom_write_enable(); - p = Spi_tx_buf ; - *p = 2 ; // Write command - *(p+1) = eeAddress >> 16 ; - *(p+2) = eeAddress >> 8 ; - *(p+3) = eeAddress ; // 3 bytes address - spi_PDC_action( p, buffer, 0, 4, size ) ; + p = Spi_tx_buf; + *p = 2; // Write command + *(p + 1) = eeAddress >> 16; + *(p + 2) = eeAddress >> 8; + *(p + 3) = eeAddress; // 3 bytes address + spi_PDC_action(p, buffer, 0, 4, size); - if ( immediate ) - { - return 0 ; - } - for ( x = 0 ; x < 100000 ; x += 1 ) - { - if ( Spi_complete ) - { - break ; - } - } - return x ; + if (immediate) { + return 0; + } + for (x = 0; x < 100000; x += 1) { + if (Spi_complete) { + break; + } + } + return x ; } uint8_t byte_checksum( uint8_t *p, uint32_t size ) @@ -450,188 +376,233 @@ uint32_t ee32_check_header( struct t_eeprom_header *hptr ) // and the sequence number if required uint32_t get_current_block_number( uint32_t block_no, uint16_t *p_size, uint32_t *p_seq ) { - struct t_eeprom_header b0 ; - struct t_eeprom_header b1 ; + struct t_eeprom_header b0 ; + struct t_eeprom_header b1 ; uint32_t sequence_no ; uint16_t size ; - read32_eeprom_data( block_no << 12, ( uint8_t *)&b0, sizeof(b0), EE_WAIT ) ; // Sequence # 0 - read32_eeprom_data( (block_no+1) << 12, ( uint8_t *)&b1, sizeof(b1), EE_WAIT ) ; // Sequence # 1 + read32_eeprom_data( block_no << 12, ( uint8_t *)&b0, sizeof(b0), EE_WAIT ) ; // Sequence # 0 + read32_eeprom_data( (block_no+1) << 12, ( uint8_t *)&b1, sizeof(b1), EE_WAIT ) ; // Sequence # 1 - if ( ee32_check_header( &b0 ) == 0 ) - { - b0.sequence_no = 0 ; - b0.data_size = 0 ; - b0.flags = 0 ; - } + if ( ee32_check_header( &b0 ) == 0 ) + { + b0.sequence_no = 0 ; + b0.data_size = 0 ; + b0.flags = 0 ; + } - size = b0.data_size ; + size = b0.data_size ; sequence_no = b0.sequence_no ; - if ( ee32_check_header( &b0 ) == 0 ) - { - if ( ee32_check_header( &b1 ) != 0 ) - { - size = b1.data_size ; - sequence_no = b1.sequence_no ; - block_no += 1 ; - } - else - { - size = 0 ; - sequence_no = 1 ; - } - } - else - { - if ( ee32_check_header( &b1 ) != 0 ) - { - if ( b1.sequence_no > b0.sequence_no ) - { - size = b1.data_size ; - sequence_no = b1.sequence_no ; - block_no += 1 ; - } - } - } + if ( ee32_check_header( &b0 ) == 0 ) + { + if ( ee32_check_header( &b1 ) != 0 ) + { + size = b1.data_size ; + sequence_no = b1.sequence_no ; + block_no += 1 ; + } + else + { + size = 0 ; + sequence_no = 1 ; + } + } + else + { + if ( ee32_check_header( &b1 ) != 0 ) + { + if ( b1.sequence_no > b0.sequence_no ) + { + size = b1.data_size ; + sequence_no = b1.sequence_no ; + block_no += 1 ; + } + } + } - if ( size == 0xFFFF ) - { - size = 0 ; - } + if ( size == 0xFFFF ) + { + size = 0 ; + } if ( p_size ) - { - *p_size = size ; - } + { + *p_size = size ; + } if ( sequence_no == 0xFFFFFFFF ) - { - sequence_no = 0 ; - } + { + sequence_no = 0 ; + } if ( p_seq ) - { - *p_seq = sequence_no ; - } + { + *p_seq = sequence_no ; + } // Block_needs_erasing = erase ; - return block_no ; + return block_no ; } bool ee32LoadGeneral() { - uint16_t size ; + uint16_t size ; - size = File_system[0].size ; + size = File_system[0].size ; memset(&g_eeGeneral, 0, sizeof(EEGeneral)); - if ( size > sizeof(EEGeneral) ) - { - size = sizeof(EEGeneral) ; - } + if ( size > sizeof(EEGeneral) ) { + size = sizeof(EEGeneral) ; + } - if ( size ) - { - read32_eeprom_data( ( File_system[0].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_eeGeneral, size, 0 ) ; - } + if ( size ) { + read32_eeprom_data( ( File_system[0].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_eeGeneral, size, 0 ) ; + } /*if(g_eeGeneral.myVers(sizeof(EEGeneral)-20)) for(uint8_t i=0; i<12;i++) sum+=g_eeGeneral.calibMid[i]; return g_eeGeneral.chkSum == sum; } -void ee32WaitLoadModel(uint8_t id) +void eeLoadModel(uint8_t id) { - // Wait for EEPROM to be idle - if ( General_timer ) - { - General_timer = 1 ; // Make these happen soon - } - if ( Model_timer ) - { - Model_timer = 1 ; - } + uint16_t size ; - while( ( Eeprom32_process_state != E32_IDLE ) - || ( General_timer ) - || ( Model_timer ) ) - { - mainSequence( NO_MENU ) ; // Wait for EERPOM to be IDLE - } + if (id sizeof(g_model) ) - { - size = sizeof(g_model) ; - } - - if(size<256) // if not loaded a fair amount - { - modelDefault(id) ; - } - else - { - read32_eeprom_data( ( File_system[id+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_model, size, 0 ) ; - } - - for(uint8_t i=0; i sizeof(g_model) ) + { + size = sizeof(g_model) ; + } + + if(size<256) // if not loaded a fair amount + { + modelDefault(id) ; + eeCheck(true); + } + else + { + read32_eeprom_data( ( File_system[id+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_model, size, 0 ) ; } -} -bool ee32ModelExists(uint8_t id) -{ - return ( File_system[id+1].size > 0 ) ; -} + resetProto(); + resetAll(); -void ee32LoadModelName( uint8_t id, unsigned char*buf, uint8_t len ) -{ - if(id<=MAX_MODELS) - { - memset(buf,' ',len); - if ( File_system[id].size > sizeof(g_model.name) ) - { - read32_eeprom_data( ( File_system[id].block_no << 12) + 8, ( uint8_t *)buf, sizeof(g_model.name), 0 ) ; - } +#ifdef LOGS + initLogs(); +#endif } } - -void fill_file_index() +bool eeModelExists(uint8_t id) { - uint32_t i ; - for ( i = 0 ; i < MAX_MODELS + 1 ; i += 1 ) - { - File_system[i].block_no = get_current_block_number( i * 2, &File_system[i].size, &File_system[i].sequence_no ) ; - } + return ( File_system[id+1].size > 0 ) ; } +void ee32LoadModelName(uint8_t id, char *buf, uint8_t len) +{ + if (id < MAX_MODELS) { + id += 1; + memset(buf, ' ', len); + if (File_system[id].size > sizeof(g_model.name) ) { + read32_eeprom_data( ( File_system[id].block_no << 12) + 8, ( uint8_t *)buf, sizeof(g_model.name), 0 ) ; + } + } +} -// TODO => eeprom_arm +void eeReadAll() +{ +// txmit('a') ; + if (!ee32LoadGeneral() ) +// !EeFsOpen() || +// EeFsck() < 0 || +// ) + { +// txmit('b') ; + + alert((char const *)"Bad EEprom Data", true); + g_eeGeneral.contrast = 25 ; + message(PSTR("EEPROM Formatting")); +// EeFsFormat(); + //alert(PSTR("format ok")); + generalDefault(); + // alert(PSTR("default ok")); + +// uint16_t sz = theFile.writeRlc(FILE_GENERAL,FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral,sizeof(EEGeneral),200); +// if(sz!=sizeof(EEGeneral)) alert(PSTR("genwrite error")); + + modelDefault(0); + //alert(PSTR("modef ok")); +// theFile.writeRlc(FILE_MODEL(0),FILE_TYP_MODEL,(uint8_t*)&g_model,sizeof(g_model),200); + //alert(PSTR("modwrite ok")); + STORE_GENERALVARS; + STORE_MODELVARS; + } + else + { + eeLoadModel(g_eeGeneral.currModel); + ee32_read_model_names() ; + } +} + +uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count ) +{ + register Spi *spiptr; + register uint32_t result; + +// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI + + result = 0; + spiptr = SPI; + spiptr->SPI_CR = 1; // Enable + (void) spiptr->SPI_RDR; // Dump any rx data + while (count) { + result = 0; + while ((spiptr->SPI_SR & SPI_SR_TXEMPTY) == 0) { + // wait + if (++result > 10000) { + result = 0xFFFF; + break; + } + } + if (result > 10000) { + break; + } +// if ( count == 1 ) +// { +// spiptr->SPI_CR = SPI_CR_LASTXFER ; // LastXfer bit +// } + spiptr->SPI_TDR = *tx++; + result = 0; + while ((spiptr->SPI_SR & SPI_SR_RDRF) == 0) { + // wait for received + if (++result > 10000) { + result = 0x2FFFF; + break; + } + } + if (result > 10000) { + break; + } + *rx++ = spiptr->SPI_RDR; + count -= 1; + } + if (result <= 10000) { + result = 0; + } + spiptr->SPI_CR = 2; // Disable + +// Power save +// PMC->PMC_PCER0 &= ~0x00200000L ; // Disable peripheral clock to SPI + + return result ; +} // SPI i/f to EEPROM (4Mb) // Peripheral ID 21 (0x00200000) @@ -678,924 +649,251 @@ void init_spi() spi_operation( p, spi_buf, 2 ) ; } -void init_ee32() +extern "C" void SPI_IRQHandler() { - fill_file_index() ; - ee32_read_model_names() ; - Eeprom32_process_state = E32_IDLE ; + register Spi *spiptr ; + + spiptr = SPI ; + SPI->SPI_IDR = 0x07FF ; // All interrupts off + spiptr->SPI_CR = 2 ; // Disable + (void) spiptr->SPI_RDR ; // Dump any rx data + (void) spiptr->SPI_SR ; // Clear error flags + spiptr->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS ; // Stop tramsfers + Spi_complete = 1 ; // Indicate completion + +// Power save +// PMC->PMC_PCER0 &= ~0x00200000L ; // Disable peripheral clock to SPI } -uint32_t ee32_check_finished() +void end_spi() { - if ( ( Eeprom32_process_state != E32_IDLE ) - || ( General_timer ) - || ( Model_timer ) ) - { - ee32_process() ; - return 0 ; - } - return 1 ; + SPI->SPI_CR = 2 ; // Disable + SPI->SPI_IDR = 0x07FF ; // All interrupts off + NVIC_DisableIRQ(SPI_IRQn) ; } - -uint32_t ee32_process() +void eeWaitFinished() { - register uint8_t *p ; - register uint8_t *q ; - register uint32_t x ; - register uint32_t eeAddress ; + while (Eeprom32_process_state != E32_IDLE) { + ee32_process(); + // TODO perMain()? + } +} -// return 0 ; +void eeCheck(bool immediately) +{ + if (!immediately && (Eeprom32_process_state != E32_IDLE || (get_tmr10ms() - s_eeDirtyTime10ms) < WRITE_DELAY_10MS)) + return; - if ( General_timer ) - { - if ( --General_timer == 0 ) - { - - // Time to write g_eeGeneral - Ee32_general_write_pending = 1 ; - } - } - if ( Model_timer ) - { - if ( --Model_timer == 0 ) - { - - // Time to write model - Ee32_model_write_pending = 1 ; - } - } + if (Eeprom32_process_state != E32_IDLE) + eeWaitFinished(); - if ( Eeprom32_process_state == E32_IDLE ) - { - if ( Ee32_general_write_pending ) - { - Ee32_general_write_pending = 0 ; // clear flag + if (s_eeDirtyMsk & EE_GENERAL) { + s_eeDirtyMsk -= EE_GENERAL; + Eeprom32_source_address = (uint8_t *)&g_eeGeneral ; // Get data from here + Eeprom32_data_size = sizeof(g_eeGeneral) ; // This much + Eeprom32_file_index = 0 ; // This file system entry + Eeprom32_process_state = E32_BLANKCHECK ; + if (immediately) + eeWaitFinished(); + else + return; + } - // Check we can write, == block is blank + if (s_eeDirtyMsk & EE_MODEL) { + s_eeDirtyMsk -= EE_MODEL; + Eeprom32_source_address = (uint8_t *)&g_model ; // Get data from here + Eeprom32_data_size = sizeof(g_model) ; // This much + Eeprom32_file_index = g_eeGeneral.currModel + 1 ; // This file system entry + Eeprom32_process_state = E32_BLANKCHECK ; + if (immediately) + eeWaitFinished(); + } +} - Eeprom32_source_address = (uint8_t *)&g_eeGeneral ; // Get data fromm here - Eeprom32_data_size = sizeof(g_eeGeneral) ; // This much - Eeprom32_file_index = 0 ; // This file system entry - Eeprom32_process_state = E32_BLANKCHECK ; -// Writing_model = 0 ; - } - else if ( Ee32_model_write_pending ) - { - Ee32_model_write_pending = 0 ; // clear flag +void ee32_process() +{ + register uint8_t *p ; + register uint8_t *q ; + register uint32_t x ; + register uint32_t eeAddress ; - // Check we can write, == block is blank + if ( Eeprom32_process_state == E32_BLANKCHECK ) { + eeAddress = File_system[Eeprom32_file_index].block_no ^ 1 ; + eeAddress <<= 12 ; // Block start address + Eeprom32_address = eeAddress ; // Where to put new data + x = Eeprom32_data_size + sizeof( struct t_eeprom_header ) ; // Size needing to be checked + p = (uint8_t *) &Eeprom_buffer ; + read32_eeprom_data( eeAddress, p, x, 1 ) ; + Eeprom32_process_state = E32_READSENDING ; + } - Eeprom32_source_address = (uint8_t *)&g_model ; // Get data from here - Eeprom32_data_size = sizeof(g_model) ; // This much - Eeprom32_file_index = Model_dirty ; // This file system entry - Eeprom32_process_state = E32_BLANKCHECK ; -// Writing_model = Model_dirty ; - } - else if ( Ee32_model_delete_pending ) - { - Eeprom32_source_address = (uint8_t *)&g_model ; // Get data from here - Eeprom32_data_size = 0 ; // This much - Eeprom32_file_index = Ee32_model_delete_pending ; // This file system entry - Ee32_model_delete_pending = 0 ; - Eeprom32_process_state = E32_BLANKCHECK ; - } - } + if ( Eeprom32_process_state == E32_READSENDING ) + { + if ( Spi_complete ) + { + uint32_t blank = 1 ; + x = Eeprom32_data_size + sizeof( struct t_eeprom_header ) ; // Size needing to be checked + p = (uint8_t *) &Eeprom_buffer ; + while ( x ) + { + if ( *p++ != 0xFF ) + { + blank = 0 ; + break ; + } + x -= 1 ; + } + // If not blank, sort erasing here + if ( blank ) + { + Eeprom32_state_after_erase = E32_IDLE ; + Eeprom32_process_state = E32_WRITESTART ; + } + else + { + eeAddress = Eeprom32_address ; + eeprom_write_enable() ; + p = Spi_tx_buf ; + *p = 0x20 ; // Block Erase command + *(p+1) = eeAddress >> 16 ; + *(p+2) = eeAddress >> 8 ; + *(p+3) = eeAddress ; // 3 bytes address + spi_PDC_action( p, 0, 0, 4, 0 ) ; + Eeprom32_process_state = E32_ERASESENDING ; + Eeprom32_state_after_erase = E32_WRITESTART ; + } + } + } - if ( Eeprom32_process_state == E32_BLANKCHECK ) - { - eeAddress = File_system[Eeprom32_file_index].block_no ^ 1 ; - eeAddress <<= 12 ; // Block start address - Eeprom32_address = eeAddress ; // Where to put new data - x = Eeprom32_data_size + sizeof( struct t_eeprom_header ) ; // Size needing to be checked - p = (uint8_t *) &Eeprom_buffer ; - read32_eeprom_data( eeAddress, p, x, 1 ) ; - Eeprom32_process_state = E32_READSENDING ; - } + if ( Eeprom32_process_state == E32_WRITESTART ) + { + uint32_t total_size ; + p = Eeprom32_source_address; + q = (uint8_t *) &Eeprom_buffer.data; + if (p != q) { + // TODO why not memcpy + for (x = 0; x < Eeprom32_data_size; x += 1) { + *q++ = *p++; // Copy the data to temp buffer + } + } + Eeprom_buffer.header.sequence_no = + ++File_system[Eeprom32_file_index].sequence_no; + File_system[Eeprom32_file_index].size = Eeprom_buffer.header.data_size = + Eeprom32_data_size; + Eeprom_buffer.header.flags = 0; + Eeprom_buffer.header.hcsum = byte_checksum((uint8_t *) &Eeprom_buffer, 7); + total_size = Eeprom32_data_size + sizeof(struct t_eeprom_header); + eeAddress = Eeprom32_address; // Block start address + x = total_size / 256; // # sub blocks + x <<= 8; // to offset address + eeAddress += x; // Add it in + p = (uint8_t *) &Eeprom_buffer; + p += x; // Add offset + x = total_size % 256; // Size of last bit + if (x == 0) // Last bit empty + { + x = 256; + p -= x; + eeAddress -= x; + } + Eeprom32_buffer_address = p; + Eeprom32_address = eeAddress; + write32_eeprom_block(eeAddress, p, x, 1); + Eeprom32_process_state = E32_WRITESENDING ; + } - if ( Eeprom32_process_state == E32_READSENDING ) - { - if ( Spi_complete ) - { - uint32_t blank = 1 ; - x = Eeprom32_data_size + sizeof( struct t_eeprom_header ) ; // Size needing to be checked - p = (uint8_t *) &Eeprom_buffer ; - while ( x ) - { - if ( *p++ != 0xFF ) - { - blank = 0 ; - break ; - } - x -= 1 ; - } - // If not blank, sort erasing here - if ( blank ) - { - Eeprom32_state_after_erase = E32_IDLE ; - Eeprom32_process_state = E32_WRITESTART ; - } - else - { - eeAddress = Eeprom32_address ; - eeprom_write_enable() ; - p = Spi_tx_buf ; - *p = 0x20 ; // Block Erase command - *(p+1) = eeAddress >> 16 ; - *(p+2) = eeAddress >> 8 ; - *(p+3) = eeAddress ; // 3 bytes address - spi_PDC_action( p, 0, 0, 4, 0 ) ; - Eeprom32_process_state = E32_ERASESENDING ; - Eeprom32_state_after_erase = E32_WRITESTART ; - } - } - } + if ( Eeprom32_process_state == E32_WRITESENDING ) + { + if ( Spi_complete ) + { + Eeprom32_process_state = E32_WRITEWAITING ; + } + } - if ( Eeprom32_process_state == E32_WRITESTART ) - { - uint32_t total_size ; - p = Eeprom32_source_address ; - q = (uint8_t *)&Eeprom_buffer.data ; - for ( x = 0 ; x < Eeprom32_data_size ; x += 1 ) - { - *q++ = *p++ ; // Copy the data to temp buffer - } - Eeprom_buffer.header.sequence_no = ++File_system[Eeprom32_file_index].sequence_no ; - File_system[Eeprom32_file_index].size = Eeprom_buffer.header.data_size = Eeprom32_data_size ; - Eeprom_buffer.header.flags = 0 ; - Eeprom_buffer.header.hcsum = byte_checksum( (uint8_t *)&Eeprom_buffer, 7 ) ; - total_size = Eeprom32_data_size + sizeof( struct t_eeprom_header ) ; - eeAddress = Eeprom32_address ; // Block start address - x = total_size / 256 ; // # sub blocks - x <<= 8 ; // to offset address - eeAddress += x ; // Add it in - p = (uint8_t *) &Eeprom_buffer ; - p += x ; // Add offset - x = total_size % 256 ; // Size of last bit - if ( x == 0 ) // Last bit empty - { - x = 256 ; - p -= x ; - eeAddress -= x ; - } - Eeprom32_buffer_address = p ; - Eeprom32_address = eeAddress ; - write32_eeprom_block( eeAddress, p, x, 1 ) ; - Eeprom32_process_state = E32_WRITESENDING ; - } + if ( Eeprom32_process_state == E32_WRITEWAITING ) + { + x = eeprom_read_status() ; + if ( ( x & 1 ) == 0 ) + { + if ( ( Eeprom32_address & 0x0FFF ) != 0 ) // More to write + { + Eeprom32_address -= 256 ; + Eeprom32_buffer_address -= 256 ; + write32_eeprom_block( Eeprom32_address, Eeprom32_buffer_address, 256, 1 ) ; + Eeprom32_process_state = E32_WRITESENDING ; + } + else + { + // now erase the other block + File_system[Eeprom32_file_index].block_no ^= 1 ; // This is now the current block + eeAddress = Eeprom32_address ^ 0x00001000 ; // Address of block to erase + eeprom_write_enable() ; + p = Spi_tx_buf ; + *p = 0x20 ; // Block Erase command + *(p+1) = eeAddress >> 16 ; + *(p+2) = eeAddress >> 8 ; + *(p+3) = eeAddress ; // 3 bytes address + spi_PDC_action( p, 0, 0, 4, 0 ) ; + Eeprom32_process_state = E32_ERASESENDING ; + Eeprom32_state_after_erase = E32_IDLE ; + } + } + } - if ( Eeprom32_process_state == E32_WRITESENDING ) - { - if ( Spi_complete ) - { - Eeprom32_process_state = E32_WRITEWAITING ; - } - } - - if ( Eeprom32_process_state == E32_WRITEWAITING ) - { - x = eeprom_read_status() ; - if ( ( x & 1 ) == 0 ) - { - if ( ( Eeprom32_address & 0x0FFF ) != 0 ) // More to write - { - Eeprom32_address -= 256 ; - Eeprom32_buffer_address -= 256 ; - write32_eeprom_block( Eeprom32_address, Eeprom32_buffer_address, 256, 1 ) ; - Eeprom32_process_state = E32_WRITESENDING ; - } - else - { - // now erase the other block - File_system[Eeprom32_file_index].block_no ^= 1 ; // This is now the current block - eeAddress = Eeprom32_address ^ 0x00001000 ; // Address of block to erase - eeprom_write_enable() ; - p = Spi_tx_buf ; - *p = 0x20 ; // Block Erase command - *(p+1) = eeAddress >> 16 ; - *(p+2) = eeAddress >> 8 ; - *(p+3) = eeAddress ; // 3 bytes address - spi_PDC_action( p, 0, 0, 4, 0 ) ; - Eeprom32_process_state = E32_ERASESENDING ; - Eeprom32_state_after_erase = E32_IDLE ; - } - } - } - - if ( Eeprom32_process_state == E32_ERASESENDING ) - { - if ( Spi_complete ) - { - Eeprom32_process_state = E32_ERASEWAITING ; - } - } + if ( Eeprom32_process_state == E32_ERASESENDING ) + { + if ( Spi_complete ) + { + Eeprom32_process_state = E32_ERASEWAITING ; + } + } - if ( Eeprom32_process_state == E32_ERASEWAITING ) - { - x = eeprom_read_status() ; - if ( ( x & 1 ) == 0 ) - { // Command finished - Eeprom32_process_state = Eeprom32_state_after_erase ; - } - } - - if ( Eeprom32_process_state == E32_IDLE ) - { - return 0 ; // inactive - } - else - { - return 1 ; - } + if ( Eeprom32_process_state == E32_ERASEWAITING ) + { + x = eeprom_read_status() ; + if ( ( x & 1 ) == 0 ) + { // Command finished + Eeprom32_process_state = Eeprom32_state_after_erase ; + } + } } - -// Temporary eeprom handling - hence it's here - -// storage defination -//struct t_eeprom_image -//{ -// uint8_t spi_command[4] ; -// union -// { -// uint8_t bytes[2048] ; -// uint32_t words[512] ; -// } image ; -// uint32_t sequence_no ; -// uint32_t filler[3] ; -// union -// { -// uint8_t bytes[2016] ; -// uint32_t words[504] ; -// } imagex ; -//} ; - -// storage declaration -//struct t_eeprom_image E_images[2] ; - - -//void eeprom_process() -//{ -// register uint8_t *p ; -// register uint8_t *q ; -// register uint32_t block_no ; -// register uint32_t x ; - -// if ( Eeprom_image_updated ) -// { -// Eeprom_image_updated = 0 ; -// Update_timer = 100 ; // 1 second -// } -// if ( Update_timer ) -// { -// if ( --Update_timer == 0 ) -// { -// // Changed, but no changes for 2 seconds -// // Time to write changes to eeprom -// Eeprom_write_pending = 1 ; -// } -// } - -// ee32_process() ; - - -// if ( ( Eeprom_process_state == E_32ACTIVE ) || ( Eeprom_process_state == E_IDLE ) ) -// { -// if ( ee32_process() ) -// { -// Eeprom_process_state = E_32ACTIVE ; -// return ; -// } -// else -// { -// Eeprom_process_state = E_IDLE ; -// } -// } - - -// if ( Eeprom_process_state == E_IDLE ) -// { -// if ( Other_eeprom_block_blank == 0 ) -// { -// // Need to erase it -// Eeprom_process_state = E_ERASESENDING ; -// block_no = 0 ; -// if ( Current_eeprom_block == 0 ) -// { -// block_no = 1 ; -// } -// eeprom_write_enable() ; -// p = E_images[block_no].spi_command ; -// *p = 0x20 ; // Block Erase command -// *(p+1) = 0 ; -// *(p+2) = block_no << 4 ; -// *(p+3) = 0 ; // 3 bytes address -// spi_PDC_action( p, 0, 0, 4, 0 ) ; -// } -// else if ( Eeprom_write_pending ) -// { -// Eeprom_write_pending = 0 ; -// block_no = 0 ; -// if ( Current_eeprom_block == 0 ) -// { -// block_no = 1 ; -// } -// // Copy data from RAM based eeprom image - -// p = E_images[block_no].image.bytes ; -// q = eeprom ; -// for ( x = 0 ; x < 2048 ; x += 1 ) -// { -// *p++ = *q++ ; -// } -// E_images[block_no].sequence_no = Eeprom_sequence_no + 1 ; -// Eeprom_process_sub_no = 0 ; -// write_eeprom_block( block_no, Eeprom_process_sub_no, 256, 1 ) ; -// Eeprom_process_state = E_WRITESENDING ; -// Eeprom_writing_block_no = block_no ; -// } -// } - -// if ( Eeprom_process_state == E_ERASESENDING ) -// { -// if ( Spi_complete ) -// { -// Eeprom_process_state = E_ERASEWAITING ; -// } -// } - -// if ( Eeprom_process_state == E_ERASEWAITING ) -// { -// x = eeprom_read_status() ; -// if ( ( x & 1 ) == 0 ) -// { // Command finished -// Eeprom_process_state = E_IDLE ; -// Other_eeprom_block_blank = 1 ; -// } -// } - -// if ( Eeprom_process_state == E_WRITESENDING ) -// { -// if ( Spi_complete ) -// { -// Eeprom_process_state = E_WRITEWAITING ; -// } -// } - -// if ( Eeprom_process_state == E_WRITEWAITING ) -// { -// x = eeprom_read_status() ; -// if ( ( x & 1 ) == 0 ) -// { -// register uint32_t size ; -// Eeprom_process_sub_no += 1 ; -// size = 256 ; -// if ( Eeprom_process_sub_no == 8) -// { -// size = 4 ; -// } -// if ( Eeprom_process_sub_no > 8) -// { -// size = 0 ; -// } -// if ( size > 0 ) -// { -// write_eeprom_block( Eeprom_writing_block_no, Eeprom_process_sub_no, size, 1 ) ; -// Eeprom_process_state = E_WRITESENDING ; -// } -// else -// { -// Eeprom_process_state = E_IDLE ; -// Current_eeprom_block = Eeprom_writing_block_no ; -// Other_eeprom_block_blank = 0 ; -// } -// } -// } -//} - - -void init_eeprom() +void fill_file_index() { -// register uint32_t x ; -// register uint32_t y ; -// register uint8_t *p ; -// register uint8_t *q ; -// register uint32_t valid ; - -// read_eeprom_block( 0, 0 ) ; -// read_eeprom_block( 1, 0 ) ; - - // Here we should find which block is the most recent -// x = eeprom_image_blank( 0 ) ; -// y = eeprom_image_blank( 1 ) ; - -// Eeprom_process_state = E_IDLE ; -// Eeprom_process_sub_no = 0 ; -// Eeprom_write_pending = 0 ; -// if ( x ) -// { -// if ( y ) -// { // Both blank -// Other_eeprom_block_blank = 1 ; -// Current_eeprom_block = 1 ; -// Eeprom_sequence_no = 0 ; -// } -// else -// { // Block 1 is active, 0 is blank -// Other_eeprom_block_blank = 1 ; -// Current_eeprom_block = 1 ; -// Eeprom_sequence_no = E_images[1].sequence_no ; -// } -// } -// else -// { -// if ( y ) -// { // Block 0 is active, 1 is blank -// Other_eeprom_block_blank = 1 ; -// Current_eeprom_block = 0 ; -// Eeprom_sequence_no = E_images[0].sequence_no ; - -// } -// else -// { // Check sequence number and erase other block -// Other_eeprom_block_blank = 0 ; -// x = E_images[0].sequence_no ; -// y = E_images[1].sequence_no ; -// if ( y == 0xFFFFFFFF ) -// { -// y = 0 ; -// } -// if ( x == 0xFFFFFFFF ) -// { -// x = 0 ; -// } -// if ( x > y ) // Simple test, assumes no 32 bit overflow -// { -// Current_eeprom_block = 0 ; -// Eeprom_sequence_no = x ; -// } -// else -// { -// Current_eeprom_block = 1 ; -// Eeprom_sequence_no = y ; -// } -// } -// } - -// // Copy valid block to RAM eeprom image -// p = E_images[Current_eeprom_block].image.bytes ; -// q = eeprom ; -// for ( x = 0 ; x < 2048 ; x += 1 ) -// { -// *q++ = *p++ ; -// } -// disp_256( (uint32_t)eeprom, 6 ) ; -// Eeprom_process_state = E_IDLE ; - - init_ee32() ; + for (uint32_t i = 0 ; i < MAX_MODELS + 1 ; i += 1 ) + { + File_system[i].block_no = get_current_block_number( i * 2, &File_system[i].size, &File_system[i].sequence_no ) ; + } } +void ee32_read_model_names() +{ + for (uint32_t i=0; ifreeList ,sizeof(eeFs.freeList)); -//} -//static void EeFsFlush() -//{ -// eeWriteBlockCmp(&eeFs, 0,sizeof(eeFs)); -//} - -//uint16_t EeFsGetFree() -//{ -// uint16_t ret = 0; -// uint8_t i = eeFs.freeList; -// while( i ){ -// ret += BS-1; -// i = EeFsGetLink(i); -// } -// return ret; -//} -//static void EeFsFree(uint8_t blk){///free one or more blocks -// uint8_t i = blk; -// while( EeFsGetLink(i)) i = EeFsGetLink(i); -// EeFsSetLink(i,eeFs.freeList); -// eeFs.freeList = blk; //chain in front -// EeFsFlushFreelist(); -//} -//static uint8_t EeFsAlloc(){ ///alloc one block from freelist -// uint8_t ret=eeFs.freeList; -// if(ret){ -// eeFs.freeList = EeFsGetLink(ret); -// EeFsFlushFreelist(); -// EeFsSetLink(ret,0); -// } -// return ret; -//} - -//int8_t EeFsck() -//{ -// uint8_t *bufp; -// static uint8_t buffer[BLOCKS]; -// bufp = buffer; -// memset(bufp,0,BLOCKS); -// uint8_t blk ; -// int8_t ret=0; -// for(uint8_t i = 0; i <= MAXFILES; i++){ -// uint8_t *startP = i==MAXFILES ? &eeFs.freeList : &eeFs.files[i].startBlk; -// uint8_t lastBlk = 0; -// blk = *startP; -// //if(i == MAXFILES) blk = eeFs.freeList; -// // else blk = eeFs.files[i].startBlk; -// while(blk){ -// // if(blk < FIRSTBLK ) goto err_1; //bad blk index -// // if(blk >= BLOCKS ) goto err_2; //bad blk index -// // if(bufp[blk]) goto err_3; //blk double usage -// if( ( blk < FIRSTBLK ) //goto err_1; //bad blk index -// || (blk >= BLOCKS ) //goto err_2; //bad blk index -// || (bufp[blk] ))//goto err_3; //blk double usage -// { -// if(lastBlk){ -// EeFsSetLink(lastBlk,0); -// }else{ -// *startP = 0; //interrupt chain at startpos -// EeFsFlush(); -// } -// blk=0; //abort -// }else{ -// bufp[blk] = i+1; -// lastBlk = blk; -// blk = EeFsGetLink(blk); -// } -// } -// } -// for(blk = FIRSTBLK; blk < BLOCKS; blk++){ -// if(bufp[blk]==0) { //goto err_4; //unused block -// EeFsSetLink(blk,eeFs.freeList); -// eeFs.freeList = blk; //chain in front -// EeFsFlushFreelist(); -// } -// } -// // if(0){ -// //err_4: ret--; -// //err_3: ret--; -// // err_2: ret--; -// // err_1: ret--; -// // } -// return ret; -//} -//void EeFsFormat() -//{ -// if(sizeof(eeFs) != RESV){ -// extern void eeprom_RESV_mismatch(); -// eeprom_RESV_mismatch(); -// } -// memset(&eeFs,0, sizeof(eeFs)); -// eeFs.version = EEFS_VERS; -// eeFs.mySize = sizeof(eeFs); -// eeFs.freeList = 0; -// eeFs.bs = BS; -// for(uint8_t i = FIRSTBLK; i < BLOCKS; i++) EeFsSetLink(i,i+1); -// EeFsSetLink(BLOCKS-1, 0); -// eeFs.freeList = FIRSTBLK; -// EeFsFlush(); -//} -//bool EeFsOpen() -//{ -// eeprom_read_block(&eeFs,0,sizeof(eeFs)); - -// return eeFs.version == EEFS_VERS && eeFs.mySize == sizeof(eeFs); -//} - -//bool EFile::exists(uint8_t i_fileId) -//{ -// return eeFs.files[i_fileId].startBlk; -//} - -//void EFile::swap(uint8_t i_fileId1,uint8_t i_fileId2) -//{ -// DirEnt tmp = eeFs.files[i_fileId1]; -// eeFs.files[i_fileId1] = eeFs.files[i_fileId2]; -// eeFs.files[i_fileId2] = tmp;; -// EeFsFlush(); -//} - -//void EFile::rm(uint8_t i_fileId){ -// uint8_t i = eeFs.files[i_fileId].startBlk; -// memset(&eeFs.files[i_fileId], 0, sizeof(eeFs.files[i_fileId])); -// EeFsFlush(); //chained out - -// if(i) EeFsFree( i ); //chain in -//} - -//uint16_t EFile::size(){ -// return eeFs.files[m_fileId].size; -//} - - -//uint8_t EFile::openRd(uint8_t i_fileId){ -// m_fileId = i_fileId; -// m_pos = 0; -// m_currBlk = eeFs.files[m_fileId].startBlk; -// m_ofs = 0; -// m_bRlc = 0; -// m_err = ERR_NONE; //error reasons -// return eeFs.files[m_fileId].typ; -//} -//uint8_t EFile::read(uint8_t*buf,uint16_t i_len){ -// uint16_t len = eeFs.files[m_fileId].size - m_pos; -// if(len < i_len) i_len = len; -// len = i_len; -// while(len) -// { -// if(!m_currBlk) break; -// *buf++ = EeFsGetDat(m_currBlk, m_ofs++); -// if(m_ofs>=(BS-1)){ -// m_ofs=0; -// m_currBlk=EeFsGetLink(m_currBlk); -// } -// len--; -// } -// m_pos += i_len - len; -// return i_len - len; -//} -//uint16_t EFile::readRlc(uint8_t*buf,uint16_t i_len){ -// uint16_t i; -// for( i=0; i(i_len-i)) l = (uint8_t)(i_len-i); -// if(m_bRlc&0x80){ // if contains high byte -// memset(&buf[i],0,l); // write l zeros -// }else{ -// uint8_t lr = read(&buf[i],l); // read and write l bytes -// if(lr!=l) return i+lr; -// } -// i += l; -// m_bRlc -= l; -// } -// return i; -//} -//uint8_t EFile::write(uint8_t*buf,uint8_t i_len){ -// uint8_t len=i_len; -// if(!m_currBlk && m_pos==0) -// { -// eeFs.files[m_fileId].startBlk = m_currBlk = EeFsAlloc(); -// } -// while(len) -// { -// if( (int16_t)(m_stopTime10ms - get_tmr10ms()) < 0) -// { -// m_err = ERR_TMO; -// break; -// } -// if(!m_currBlk) { -// m_err = ERR_FULL; -// break; -// } -// if(m_ofs>=(BS-1)){ -// m_ofs=0; -// if( ! EeFsGetLink(m_currBlk) ){ -// EeFsSetLink(m_currBlk, EeFsAlloc()); -// } -// m_currBlk = EeFsGetLink(m_currBlk); -// } -// if(!m_currBlk) { -// m_err = ERR_FULL; -// break; -// } -// uint8_t l = BS-1-m_ofs; if(l>len) l=len; -// EeFsSetDat(m_currBlk, m_ofs, buf, l); -// buf +=l; -// m_ofs +=l; -// len -=l; -// } -// m_pos += i_len - len; -// return i_len - len; -//} -//void EFile::create(uint8_t i_fileId, uint8_t typ, uint16_t maxTme10ms){ -// openRd(i_fileId); //internal use -// eeFs.files[i_fileId].typ = typ; -// eeFs.files[i_fileId].size = 0; -// m_stopTime10ms = get_tmr10ms() + maxTme10ms; -//} -//void EFile::closeTrunc() -//{ -// uint8_t fri=0; -// eeFs.files[m_fileId].size = m_pos; -// if(m_currBlk && ( fri = EeFsGetLink(m_currBlk))) EeFsSetLink(m_currBlk, 0); -// EeFsFlush(); //chained out - -// if(fri) EeFsFree( fri ); //chain in -//} - -//uint16_t EFile::writeRlc(uint8_t i_fileId, uint8_t typ,uint8_t*buf,uint16_t i_len, uint8_t maxTme10ms){ -// create(i_fileId,typ,maxTme10ms); -// bool state0 = true; -// uint8_t cnt = 0; -// uint16_t i; - -// //RLE compression: -// //rb = read byte -// //if (rb | 0x80) write rb & 0x7F zeros -// //else write rb bytes -// for( i=0; i<=i_len; i++) -// { -// bool nst0 = buf[i] == 0; -// if( nst0 && !state0 && buf[i+1]!=0) nst0 = false ; -// if(nst0 != state0 || cnt>=0x7f || i==i_len){ -// if(state0){ -// if(cnt>0){ -// cnt|=0x80; -// if( write(&cnt,1)!=1) goto error; -// cnt=0; -// } -// }else{ -// if(cnt>0) { -// if( write(&cnt,1) !=1) goto error; -// uint8_t ret=write(&buf[i-cnt],cnt); -// if( ret !=cnt) { cnt-=ret; goto error;} -// cnt=0; -// } -// } -// state0 = nst0; -// } -// cnt++; -// } -// if(0){ -// error: -// i_len = i - (cnt & 0x7f); -// } -// closeTrunc(); -// return i_len; -//} + register uint8_t *p; + eeprom_write_enable(); + p = Spi_tx_buf; + *p = 0x39; // Unprotect sector command + *(p + 1) = 0; + *(p + 2) = 0; + *(p + 3) = 0; // 3 bytes address + + return spi_operation( p, Spi_rx_buf, 4 ) ; } diff --git a/src/eeprom_arm.h b/src/eeprom_arm.h index 40678c2e3..2262d0ec6 100644 --- a/src/eeprom_arm.h +++ b/src/eeprom_arm.h @@ -20,18 +20,33 @@ #include #include +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*/ + diff --git a/src/eeprom_avr.cpp b/src/eeprom_avr.cpp index b4dca2edd..6d90a1da7 100644 --- a/src/eeprom_avr.cpp +++ b/src/eeprom_avr.cpp @@ -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() || diff --git a/src/eeprom_avr.h b/src/eeprom_avr.h index d83c82725..d524d7cc3 100644 --- a/src/eeprom_avr.h +++ b/src/eeprom_avr.h @@ -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*/ diff --git a/src/ersky9x/vectors_sam3s.c b/src/ersky9x/vectors_sam3s.c index 99ac1ab6d..76a2e3790 100644 --- a/src/ersky9x/vectors_sam3s.c +++ b/src/ersky9x/vectors_sam3s.c @@ -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); } diff --git a/src/frsky.cpp b/src/frsky.cpp index af1d3a329..5f8938411 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -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); diff --git a/src/model_menus.cpp b/src/model_menus.cpp index c4abfeb3b..2d88f2aa9 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -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_pgOfs7*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; diff --git a/src/myeeprom.h b/src/myeeprom.h index 7536ea745..b0033febc 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -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; diff --git a/src/o9xstrings.cpp b/src/o9xstrings.cpp index bff949f26..016916225 100644 --- a/src/o9xstrings.cpp +++ b/src/o9xstrings.cpp @@ -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 diff --git a/src/o9xstrings.h b/src/o9xstrings.h index 8bbaeeca8..53b0d89fe 100644 --- a/src/o9xstrings.h +++ b/src/o9xstrings.h @@ -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[]; diff --git a/src/open9x.cpp b/src/open9x.cpp index 8d8a353de..9222bf0a5 100644 --- a/src/open9x.cpp +++ b/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 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 [-1024..1024] @@ -1171,7 +1206,7 @@ uint8_t evalSticks(uint8_t phase) if (tmp <= 1) anaCenter |= (tmp==0 ? 1<mode) { @@ -1277,30 +1312,31 @@ void perOut(uint8_t phase) { uint8_t anaCenter = evalSticks(phase); - //===========BEEP CENTER================ - anaCenter &= g_model.beepANACenter; - if(((bpanaCenter ^ anaCenter) & anaCenter)) AUDIO_POT_STICK_MIDDLE(); - bpanaCenter = anaCenter; + if (s_perout_mode == e_perout_mode_normal) { + //===========BEEP CENTER================ + anaCenter &= g_model.beepANACenter; + if(((bpanaCenter ^ anaCenter) & anaCenter)) AUDIO_POT_STICK_MIDDLE(); + bpanaCenter = anaCenter; #ifdef HELI - if(g_model.swashR.value) - { + if(g_model.swashR.value) + { uint32_t v = ((int32_t)anas[ELE_STICK]*anas[ELE_STICK] + (int32_t)anas[AIL_STICK]*anas[AIL_STICK]); uint32_t q = (int32_t)RESX*g_model.swashR.value/100; q *= q; if(v>q) { - uint16_t d = isqrt32(v); - anas[ELE_STICK] = (int32_t)anas[ELE_STICK]*g_model.swashR.value*RESX/((int32_t)d*100); - anas[AIL_STICK] = (int32_t)anas[AIL_STICK]*g_model.swashR.value*RESX/((int32_t)d*100); + uint16_t d = isqrt32(v); + anas[ELE_STICK] = (int32_t)anas[ELE_STICK]*g_model.swashR.value*RESX/((int32_t)d*100); + anas[AIL_STICK] = (int32_t)anas[AIL_STICK]*g_model.swashR.value*RESX/((int32_t)d*100); } - } + } #define REZ_SWASH_X(x) ((x) - (x)/8 - (x)/128 - (x)/512) // 1024*sin(60) ~= 886 #define REZ_SWASH_Y(x) ((x)) // 1024 => 1024 - if(g_model.swashR.type) - { + if(g_model.swashR.type) + { int16_t vp = anas[ELE_STICK]+trims[ELE_STICK]; int16_t vr = anas[AIL_STICK]+trims[AIL_STICK]; int16_t vc = 0; @@ -1313,49 +1349,50 @@ void perOut(uint8_t phase) switch (g_model.swashR.type) { - case (SWASH_TYPE_120): + case (SWASH_TYPE_120): vp = REZ_SWASH_Y(vp); vr = REZ_SWASH_X(vr); cyc_anas[0] = vc - vp; cyc_anas[1] = vc + vp/2 + vr; cyc_anas[2] = vc + vp/2 - vr; break; - case (SWASH_TYPE_120X): + case (SWASH_TYPE_120X): vp = REZ_SWASH_X(vp); vr = REZ_SWASH_Y(vr); cyc_anas[0] = vc - vr; cyc_anas[1] = vc + vr/2 + vp; cyc_anas[2] = vc + vr/2 - vp; break; - case (SWASH_TYPE_140): + case (SWASH_TYPE_140): vp = REZ_SWASH_Y(vp); vr = REZ_SWASH_Y(vr); cyc_anas[0] = vc - vp; cyc_anas[1] = vc + vp + vr; cyc_anas[2] = vc + vp - vr; break; - case (SWASH_TYPE_90): + case (SWASH_TYPE_90): vp = REZ_SWASH_Y(vp); vr = REZ_SWASH_Y(vr); cyc_anas[0] = vc - vp; cyc_anas[1] = vc + vr; cyc_anas[2] = vc - vr; break; - default: + default: break; } - } + } #endif + 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 - s_trimPtr[0] = NULL; - s_trimPtr[1] = NULL; - s_trimPtr[2] = NULL; - s_trimPtr[3] = NULL; - //========== MIXER LOOP =============== - mixWarning = 0; + mixWarning = 0; // TODO should be in a local variable on stack for (uint8_t i=0; i always on line uint8_t k = md->srcRaw-1; int16_t v = 0; - 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+1destCh) // if we've already calculated the value - take it instead - v = chans[k-MIXSRC_CH1+1] / 100; - else if (k>=MIXSRC_THR-1 && k<=MIXSRC_SWC-1) { - v = getSwitch(k-MIXSRC_THR+1+1, 0) ? +1024 : -1024; - if (v<0 && !md->swtch) - sw = false; + 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+1destCh) // if we've already calculated the value - take it instead + v = chans[k-MIXSRC_CH1+1] / 100; + else if (k>=MIXSRC_THR-1 && k<=MIXSRC_SWC-1) { + v = getSwitch(k-MIXSRC_THR+1+1, 0) ? +1024 : -1024; + if (v<0 && !md->swtch) + sw = false; + } + else { + v = getValue(k <= MIXSRC_3POS ? k : k-MAX_SWITCH); + } } - 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]; - swOn[i] = true; - if (md->delayUp) { - if (swTog) { - sDelay[i] = md->delayUp * 100; - } - if (sDelay[i]) { // perform delay - if(tick10ms) sDelay[i]--; - if (!md->swtch) { - v = -1024; + if (s_perout_mode == e_perout_mode_normal) { + swOn[i] = true; + if (md->delayUp) { + if (swTog) { + sDelay[i] = md->delayUp * 100; } - else { - continue; + if (sDelay[i]) { // perform delay + if(tick10ms) sDelay[i]--; + if (!md->swtch) { + v = -1024; + } + else { + continue; + } } } + if (md->mixWarn) mixWarning |= 1<<(md->mixWarn-1); // Mix warning } - if (md->mixWarn) mixWarning |= 1<<(md->mixWarn-1); // Mix warning } else { bool has_delay = false; @@ -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(ofs0) ? - 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(qTC_CHANNEL[2].TC_IDR = TC_IDR0_CPCS ; NVIC_DisableIRQ(TC2_IRQn) ; diff --git a/src/open9x.h b/src/open9x.h index 0bff5460a..9472f8d26 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -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 { diff --git a/src/translations/en.h b/src/translations/en.h index 59eeba8d7..3b7259a97 100644 --- a/src/translations/en.h +++ b/src/translations/en.h @@ -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"