mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 22:35:23 +03:00
commit
c647e2b220
422 changed files with 14521 additions and 7900 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -18,3 +18,9 @@ startup_stm32f10x_md_gcc.s
|
|||
docs/Manual.pdf
|
||||
README.pdf
|
||||
|
||||
# artifacts of top-level Makefile
|
||||
/downloads
|
||||
/tools
|
||||
/build
|
||||
# local changes only
|
||||
make/local.mk
|
||||
|
|
|
@ -4,7 +4,7 @@ REVISION=$(git rev-parse --short HEAD)
|
|||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
REVISION=$(git rev-parse --short HEAD)
|
||||
LAST_COMMIT_DATE=$(git log -1 --date=short --format="%cd")
|
||||
TARGET_FILE=obj/cleanflight_${TARGET}
|
||||
TARGET_FILE=obj/betaflight_${TARGET}
|
||||
TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG:=$USER/undefined}
|
||||
BUILDNAME=${BUILDNAME:=travis}
|
||||
TRAVIS_BUILD_NUMBER=${TRAVIS_BUILD_NUMBER:=undefined}
|
||||
|
|
90
.travis.yml
90
.travis.yml
|
@ -1,27 +1,59 @@
|
|||
env:
|
||||
- RUNTESTS=True
|
||||
- PUBLISHMETA=True
|
||||
- PUBLISHDOCS=True
|
||||
# - RUNTESTS=True
|
||||
# - PUBLISHMETA=True
|
||||
# - PUBLISHDOCS=True
|
||||
# - TARGET=AFROMINI
|
||||
# - TARGET=AIORACERF3
|
||||
# - TARGET=AIR32
|
||||
# - TARGET=AIRHEROF3
|
||||
# - TARGET=ALIENFLIGHTF1
|
||||
- TARGET=ALIENFLIGHTF3
|
||||
- TARGET=ALIENFLIGHTF4
|
||||
- TARGET=BETAFLIGHTF3
|
||||
- TARGET=BLUEJAYF4
|
||||
- TARGET=CC3D
|
||||
- TARGET=CC3D_OPBL
|
||||
- TARGET=CC3D_BP6
|
||||
- TARGET=CC3D_OPBL_BP6
|
||||
- TARGET=COLIBRI_RACE
|
||||
- TARGET=LUX_RACE
|
||||
- TARGET=CHEBUZZF3
|
||||
- TARGET=CJMCU
|
||||
- TARGET=EUSTM32F103RC
|
||||
- TARGET=SPRACINGF3
|
||||
# - TARGET=CHEBUZZF3
|
||||
# - TARGET=CJMCU
|
||||
# - TARGET=COLIBRI
|
||||
# - TARGET=COLIBRI_OPBL
|
||||
# - TARGET=COLIBRI_RACE
|
||||
# - TARGET=DOGE
|
||||
# - TARGET=EUSTM32F103RC
|
||||
# - TARGET=F4BY
|
||||
# - TARGET=FURYF3
|
||||
- TARGET=FURYF4
|
||||
# - TARGET=IRCFUSIONF3
|
||||
# - TARGET=ISHAPEDF3
|
||||
# - TARGET=KISSFC
|
||||
# - TARGET=LUX_RACE
|
||||
# - TARGET=MICROSCISKY
|
||||
# - TARGET=MOTOLAB
|
||||
- TARGET=NAZE
|
||||
- TARGET=NAZE32PRO
|
||||
- TARGET=OLIMEXINO
|
||||
- TARGET=RMDO
|
||||
- TARGET=PORT103R
|
||||
# - TARGET=OLIMEXINO
|
||||
# - TARGET=OMNIBUS
|
||||
# - TARGET=OMNIBUSF4
|
||||
# - TARGET=PIKOBLX
|
||||
# - TARGET=PORT103R
|
||||
# - TARGET=RACEBASE
|
||||
- TARGET=REVO
|
||||
# - TARGET=REVONANO
|
||||
# - TARGET=REVO_OPBL
|
||||
# - TARGET=RMDO
|
||||
# - TARGET=SINGULARITY
|
||||
# - TARGET=SIRINFPV
|
||||
- TARGET=SPARKY
|
||||
# - TARGET=SPARKY2
|
||||
# - TARGET=SPARKY_OPBL
|
||||
- TARGET=SPRACINGF3
|
||||
- TARGET=SPRACINGF3EVO
|
||||
# - TARGET=SPRACINGF3MINI
|
||||
- TARGET=STM32F3DISCOVERY
|
||||
- TARGET=ALIENFLIGHTF1
|
||||
- TARGET=ALIENFLIGHTF3
|
||||
|
||||
# - TARGET=VRRACE
|
||||
# - TARGET=X_RACERSPI
|
||||
# - TARGET=ZCOREF3
|
||||
# - TARGET=RCEXPLORERF3
|
||||
|
||||
# use new docker environment
|
||||
sudo: false
|
||||
|
||||
|
@ -41,18 +73,24 @@ addons:
|
|||
language: cpp
|
||||
compiler: clang
|
||||
|
||||
before_install:
|
||||
- curl --retry 10 --retry-max-time 120 -L "https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q2-update/+download/gcc-arm-none-eabi-4_9-2015q2-20150609-linux.tar.bz2" | tar xfj -
|
||||
|
||||
install:
|
||||
- export PATH=$PATH:$PWD/gcc-arm-none-eabi-4_9-2015q2/bin
|
||||
- make arm_sdk_install
|
||||
|
||||
before_script: arm-none-eabi-gcc --version
|
||||
before_script: tools/gcc-arm-none-eabi-5_4-2016q2/bin/arm-none-eabi-gcc --version
|
||||
script: ./.travis.sh
|
||||
|
||||
cache: apt
|
||||
|
||||
#notifications:
|
||||
# irc: "chat.freenode.net#cleanflight"
|
||||
# use_notice: true
|
||||
# skip_join: true
|
||||
|
||||
notifications:
|
||||
irc: "chat.freenode.net#cleanflight"
|
||||
use_notice: true
|
||||
skip_join: true
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/0c20f7a1a7e311499a88
|
||||
on_success: always # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: always # options: [always|never|change] default: always
|
||||
|
||||
|
|
185
Makefile
185
Makefile
|
@ -37,6 +37,20 @@ SERIAL_DEVICE ?= $(firstword $(wildcard /dev/ttyUSB*) no-port-found)
|
|||
# Flash size (KB). Some low-end chips actually have more flash than advertised, use this to override.
|
||||
FLASH_SIZE ?=
|
||||
|
||||
## Set verbosity level based on the V= parameter
|
||||
## V=0 Low
|
||||
## v=1 High
|
||||
export AT := @
|
||||
|
||||
ifndef V
|
||||
export V0 :=
|
||||
export V1 := $(AT)
|
||||
else ifeq ($(V), 0)
|
||||
export V0 := $(AT)
|
||||
export V1 := $(AT)
|
||||
else ifeq ($(V), 1)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# Things that need to be maintained as the source changes
|
||||
#
|
||||
|
@ -53,6 +67,25 @@ INCLUDE_DIRS = $(SRC_DIR) \
|
|||
$(ROOT)/src/main/target
|
||||
LINKER_DIR = $(ROOT)/src/main/target
|
||||
|
||||
## Build tools, so we all share the same versions
|
||||
# import macros common to all supported build systems
|
||||
include $(ROOT)/make/system-id.mk
|
||||
# developer preferences, edit these at will, they'll be gitignored
|
||||
include $(ROOT)/make/local.mk
|
||||
|
||||
# configure some directories that are relative to wherever ROOT_DIR is located
|
||||
TOOLS_DIR := $(ROOT)/tools
|
||||
BUILD_DIR := $(ROOT)/build
|
||||
DL_DIR := $(ROOT)/downloads
|
||||
|
||||
export RM := rm
|
||||
|
||||
# import macros that are OS specific
|
||||
include $(ROOT)/make/$(OSFAMILY).mk
|
||||
|
||||
# include the tools makefile
|
||||
include $(ROOT)/make/tools.mk
|
||||
|
||||
# default xtal value for F4 targets
|
||||
HSE_VALUE = 8000000
|
||||
|
||||
|
@ -122,9 +155,9 @@ endif
|
|||
|
||||
REVISION = $(shell git log -1 --format="%h")
|
||||
|
||||
FC_VER_MAJOR := $(shell grep " FC_VERSION_MAJOR" src/main/version.h | awk '{print $$3}' )
|
||||
FC_VER_MINOR := $(shell grep " FC_VERSION_MINOR" src/main/version.h | awk '{print $$3}' )
|
||||
FC_VER_PATCH := $(shell grep " FC_VERSION_PATCH" src/main/version.h | awk '{print $$3}' )
|
||||
FC_VER_MAJOR := $(shell grep " FC_VERSION_MAJOR" src/main/build/version.h | awk '{print $$3}' )
|
||||
FC_VER_MINOR := $(shell grep " FC_VERSION_MINOR" src/main/build/version.h | awk '{print $$3}' )
|
||||
FC_VER_PATCH := $(shell grep " FC_VERSION_PATCH" src/main/build/version.h | awk '{print $$3}' )
|
||||
|
||||
FC_VER := $(FC_VER_MAJOR).$(FC_VER_MINOR).$(FC_VER_PATCH)
|
||||
|
||||
|
@ -179,7 +212,6 @@ LD_SCRIPT = $(LINKER_DIR)/stm32_flash_f303_$(FLASH_SIZE)k.ld
|
|||
|
||||
ARCH_FLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -Wdouble-promotion
|
||||
DEVICE_FLAGS = -DSTM32F303xC -DSTM32F303
|
||||
TARGET_FLAGS = -D$(TARGET)
|
||||
# End F3 targets
|
||||
#
|
||||
# Start F4 targets
|
||||
|
@ -273,7 +305,6 @@ $(error Unknown MCU for F4 target)
|
|||
endif
|
||||
DEVICE_FLAGS += -DHSE_VALUE=$(HSE_VALUE)
|
||||
|
||||
TARGET_FLAGS = -D$(TARGET)
|
||||
# End F4 targets
|
||||
#
|
||||
# Start F1 targets
|
||||
|
@ -313,7 +344,6 @@ endif
|
|||
|
||||
LD_SCRIPT = $(LINKER_DIR)/stm32_flash_f103_$(FLASH_SIZE)k.ld
|
||||
ARCH_FLAGS = -mthumb -mcpu=cortex-m3
|
||||
TARGET_FLAGS := -D$(TARGET) -pedantic $(TARGET_FLAGS)
|
||||
|
||||
ifeq ($(DEVICE_FLAGS),)
|
||||
DEVICE_FLAGS = -DSTM32F10X_MD
|
||||
|
@ -332,6 +362,10 @@ ifneq ($(FLASH_SIZE),)
|
|||
DEVICE_FLAGS := $(DEVICE_FLAGS) -DFLASH_SIZE=$(FLASH_SIZE)
|
||||
endif
|
||||
|
||||
ifneq ($(HSE_VALUE),)
|
||||
DEVICE_FLAGS := $(DEVICE_FLAGS) -DHSE_VALUE=$(HSE_VALUE)
|
||||
endif
|
||||
|
||||
TARGET_DIR = $(ROOT)/src/main/target/$(BASE_TARGET)
|
||||
TARGET_DIR_SRC = $(notdir $(wildcard $(TARGET_DIR)/*.c))
|
||||
|
||||
|
@ -357,19 +391,22 @@ INCLUDE_DIRS := $(INCLUDE_DIRS) \
|
|||
VPATH := $(VPATH):$(TARGET_DIR)
|
||||
|
||||
COMMON_SRC = \
|
||||
build_config.c \
|
||||
debug.c \
|
||||
version.c \
|
||||
build/build_config.c \
|
||||
build/debug.c \
|
||||
build/version.c \
|
||||
$(TARGET_DIR_SRC) \
|
||||
main.c \
|
||||
mw.c \
|
||||
fc/mw.c \
|
||||
common/encoding.c \
|
||||
common/filter.c \
|
||||
common/maths.c \
|
||||
common/printf.c \
|
||||
common/streambuf.c \
|
||||
common/typeconversion.c \
|
||||
config/config.c \
|
||||
config/runtime_config.c \
|
||||
config/config_eeprom.c \
|
||||
config/feature.c \
|
||||
fc/runtime_config.c \
|
||||
drivers/adc.c \
|
||||
drivers/buf_writer.c \
|
||||
drivers/bus_i2c_soft.c \
|
||||
|
@ -392,9 +429,11 @@ COMMON_SRC = \
|
|||
flight/imu.c \
|
||||
flight/mixer.c \
|
||||
flight/pid.c \
|
||||
flight/pid_legacy.c \
|
||||
flight/pid_betaflight.c \
|
||||
io/beeper.c \
|
||||
io/rc_controls.c \
|
||||
io/rc_curves.c \
|
||||
fc/rc_controls.c \
|
||||
fc/rc_curves.c \
|
||||
io/serial.c \
|
||||
io/serial_4way.c \
|
||||
io/serial_4way_avrootloader.c \
|
||||
|
@ -546,10 +585,18 @@ VPATH := $(VPATH):$(STDPERIPH_DIR)/src
|
|||
# Things that might need changing to use different tools
|
||||
#
|
||||
|
||||
# Find out if ccache is installed on the system
|
||||
CCACHE := ccache
|
||||
RESULT = $(shell (which $(CCACHE) > /dev/null 2>&1; echo $$?) )
|
||||
ifneq ($(RESULT),0)
|
||||
CCACHE :=
|
||||
endif
|
||||
|
||||
# Tool names
|
||||
CC = arm-none-eabi-gcc
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
SIZE = arm-none-eabi-size
|
||||
CC := $(CCACHE) $(ARM_SDK_PREFIX)gcc
|
||||
CPP := $(CCACHE) $(ARM_SDK_PREFIX)g++
|
||||
OBJCOPY := $(ARM_SDK_PREFIX)objcopy
|
||||
SIZE := $(ARM_SDK_PREFIX)size
|
||||
|
||||
#
|
||||
# Tool options.
|
||||
|
@ -574,8 +621,10 @@ CFLAGS += $(ARCH_FLAGS) \
|
|||
-Wall -Wextra -Wunsafe-loop-optimizations -Wdouble-promotion \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-pedantic \
|
||||
$(DEVICE_FLAGS) \
|
||||
-DUSE_STDPERIPH_DRIVER \
|
||||
-D$(TARGET) \
|
||||
$(TARGET_FLAGS) \
|
||||
-D'__FORKNAME__="$(FORKNAME)"' \
|
||||
-D'__TARGET__="$(TARGET)"' \
|
||||
|
@ -631,39 +680,39 @@ CLEAN_ARTIFACTS += $(TARGET_ELF) $(TARGET_OBJS) $(TARGET_MAP)
|
|||
# It would be nice to compute these lists, but that seems to be just beyond make.
|
||||
|
||||
$(TARGET_HEX): $(TARGET_ELF)
|
||||
$(OBJCOPY) -O ihex --set-start 0x8000000 $< $@
|
||||
$(V0) $(OBJCOPY) -O ihex --set-start 0x8000000 $< $@
|
||||
|
||||
$(TARGET_BIN): $(TARGET_ELF)
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
$(V0) $(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(TARGET_ELF): $(TARGET_OBJS)
|
||||
@echo LD $(notdir $@)
|
||||
@$(CC) -o $@ $^ $(LDFLAGS)
|
||||
$(SIZE) $(TARGET_ELF)
|
||||
$(V1) echo LD $(notdir $@)
|
||||
$(V1) $(CC) -o $@ $^ $(LDFLAGS)
|
||||
$(V0) $(SIZE) $(TARGET_ELF)
|
||||
|
||||
# Compile
|
||||
$(OBJECT_DIR)/$(TARGET)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
@echo %% $(notdir $<)
|
||||
@$(CC) -c -o $@ $(CFLAGS) $<
|
||||
$(V1) mkdir -p $(dir $@)
|
||||
$(V1) echo %% $(notdir $<)
|
||||
$(V1) $(CC) -c -o $@ $(CFLAGS) $<
|
||||
|
||||
# Assemble
|
||||
$(OBJECT_DIR)/$(TARGET)/%.o: %.s
|
||||
@mkdir -p $(dir $@)
|
||||
@echo %% $(notdir $<)
|
||||
@$(CC) -c -o $@ $(ASFLAGS) $<
|
||||
$(V1) mkdir -p $(dir $@)
|
||||
$(V1) echo %% $(notdir $<)
|
||||
$(V1) $(CC) -c -o $@ $(ASFLAGS) $<
|
||||
|
||||
$(OBJECT_DIR)/$(TARGET)/%.o: %.S
|
||||
@mkdir -p $(dir $@)
|
||||
@echo %% $(notdir $<)
|
||||
@$(CC) -c -o $@ $(ASFLAGS) $<
|
||||
$(V1) mkdir -p $(dir $@)
|
||||
$(V1) echo %% $(notdir $<)
|
||||
$(V1) $(CC) -c -o $@ $(ASFLAGS) $<
|
||||
|
||||
|
||||
## all : Build all valid targets
|
||||
all: $(VALID_TARGETS)
|
||||
|
||||
$(VALID_TARGETS):
|
||||
echo "" && \
|
||||
$(V0) echo "" && \
|
||||
echo "Building $@" && \
|
||||
$(MAKE) binary hex TARGET=$@ && \
|
||||
echo "Building $@ succeeded."
|
||||
|
@ -675,22 +724,22 @@ TARGETS_CLEAN = $(addsuffix _clean,$(VALID_TARGETS) )
|
|||
|
||||
## clean : clean up temporary / machine-generated files
|
||||
clean:
|
||||
echo "Cleaning $(TARGET)"
|
||||
rm -f $(CLEAN_ARTIFACTS)
|
||||
rm -rf $(OBJECT_DIR)/$(TARGET)
|
||||
echo "Cleaning $(TARGET) succeeded."
|
||||
$(V0) echo "Cleaning $(TARGET)"
|
||||
$(V0) rm -f $(CLEAN_ARTIFACTS)
|
||||
$(V0) rm -rf $(OBJECT_DIR)/$(TARGET)
|
||||
$(V0) echo "Cleaning $(TARGET) succeeded."
|
||||
|
||||
## clean_test : clean up temporary / machine-generated files (tests)
|
||||
clean_test:
|
||||
cd src/test && $(MAKE) clean || true
|
||||
$(V0) cd src/test && $(MAKE) clean || true
|
||||
|
||||
## clean_<TARGET> : clean up one specific target
|
||||
$(CLEAN_TARGETS) :
|
||||
$(MAKE) -j TARGET=$(subst clean_,,$@) clean
|
||||
$(V0) $(MAKE) -j TARGET=$(subst clean_,,$@) clean
|
||||
|
||||
## <TARGET>_clean : clean up one specific target (alias for above)
|
||||
$(TARGETS_CLEAN) :
|
||||
$(MAKE) -j TARGET=$(subst _clean,,$@) clean
|
||||
$(V0) $(MAKE) -j TARGET=$(subst _clean,,$@) clean
|
||||
|
||||
## clean_all : clean all valid targets
|
||||
clean_all:$(CLEAN_TARGETS)
|
||||
|
@ -700,62 +749,72 @@ all_clean:$(TARGETS_CLEAN)
|
|||
|
||||
|
||||
flash_$(TARGET): $(TARGET_HEX)
|
||||
stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
|
||||
echo -n 'R' >$(SERIAL_DEVICE)
|
||||
stm32flash -w $(TARGET_HEX) -v -g 0x0 -b 115200 $(SERIAL_DEVICE)
|
||||
$(V0) stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
|
||||
$(V0) echo -n 'R' >$(SERIAL_DEVICE)
|
||||
$(V0) stm32flash -w $(TARGET_HEX) -v -g 0x0 -b 115200 $(SERIAL_DEVICE)
|
||||
|
||||
## flash : flash firmware (.hex) onto flight controller
|
||||
flash: flash_$(TARGET)
|
||||
|
||||
st-flash_$(TARGET): $(TARGET_BIN)
|
||||
st-flash --reset write $< 0x08000000
|
||||
$(V0) st-flash --reset write $< 0x08000000
|
||||
|
||||
## st-flash : flash firmware (.bin) onto flight controller
|
||||
st-flash: st-flash_$(TARGET)
|
||||
|
||||
binary:
|
||||
$(MAKE) -j $(TARGET_BIN)
|
||||
$(V0) $(MAKE) -j $(TARGET_BIN)
|
||||
|
||||
hex:
|
||||
$(MAKE) -j $(TARGET_HEX)
|
||||
$(V0) $(MAKE) -j $(TARGET_HEX)
|
||||
|
||||
unbrick_$(TARGET): $(TARGET_HEX)
|
||||
stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
|
||||
stm32flash -w $(TARGET_HEX) -v -g 0x0 -b 115200 $(SERIAL_DEVICE)
|
||||
$(V0) stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
|
||||
$(V0) stm32flash -w $(TARGET_HEX) -v -g 0x0 -b 115200 $(SERIAL_DEVICE)
|
||||
|
||||
## unbrick : unbrick flight controller
|
||||
unbrick: unbrick_$(TARGET)
|
||||
|
||||
## cppcheck : run static analysis on C source code
|
||||
cppcheck: $(CSOURCES)
|
||||
$(CPPCHECK)
|
||||
$(V0) $(CPPCHECK)
|
||||
|
||||
cppcheck-result.xml: $(CSOURCES)
|
||||
$(CPPCHECK) --xml-version=2 2> cppcheck-result.xml
|
||||
$(V0) $(CPPCHECK) --xml-version=2 2> cppcheck-result.xml
|
||||
|
||||
## mkdirs
|
||||
$(DL_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(TOOLS_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
## help : print this help message and exit
|
||||
help: Makefile
|
||||
@echo ""
|
||||
@echo "Makefile for the $(FORKNAME) firmware"
|
||||
@echo ""
|
||||
@echo "Usage:"
|
||||
@echo " make [TARGET=<target>] [OPTIONS=\"<options>\"]"
|
||||
@echo "Or:"
|
||||
@echo " make <target> [OPTIONS=\"<options>\"]"
|
||||
@echo ""
|
||||
@echo "Valid TARGET values are: $(VALID_TARGETS)"
|
||||
@echo ""
|
||||
@sed -n 's/^## //p' $<
|
||||
$(V0) @echo ""
|
||||
$(V0) @echo "Makefile for the $(FORKNAME) firmware"
|
||||
$(V0) @echo ""
|
||||
$(V0) @echo "Usage:"
|
||||
$(V0) @echo " make [V=<verbosity>] [TARGET=<target>] [OPTIONS=\"<options>\"]"
|
||||
$(V0) @echo "Or:"
|
||||
$(V0) @echo " make <target> [V=<verbosity>] [OPTIONS=\"<options>\"]"
|
||||
$(V0) @echo ""
|
||||
$(V0) @echo "Valid TARGET values are: $(VALID_TARGETS)"
|
||||
$(V0) @echo ""
|
||||
$(V0) @sed -n 's/^## //p' $<
|
||||
|
||||
## targets : print a list of all valid target platforms (for consumption by scripts)
|
||||
targets:
|
||||
@echo "Valid targets: $(VALID_TARGETS)"
|
||||
@echo "Target: $(TARGET)"
|
||||
@echo "Base target: $(BASE_TARGET)"
|
||||
$(V0) @echo "Valid targets: $(VALID_TARGETS)"
|
||||
$(V0) @echo "Target: $(TARGET)"
|
||||
$(V0) @echo "Base target: $(BASE_TARGET)"
|
||||
|
||||
## test : run the cleanflight test suite
|
||||
test:
|
||||
cd src/test && $(MAKE) test || true
|
||||
$(V0) cd src/test && $(MAKE) test || true
|
||||
|
||||
# rebuild everything when makefile changes
|
||||
$(TARGET_OBJS) : Makefile
|
||||
|
|
63
README.md
63
README.md
|
@ -61,11 +61,9 @@ If what you need is not covered then refer to the baseflight documentation. If y
|
|||
|
||||
## IRC Support and Developers Channel
|
||||
|
||||
There's a dedicated IRC channel here:
|
||||
There's a dedicated IRCgitter chat channel here:
|
||||
|
||||
irc://irc.freenode.net/#cleanflight
|
||||
|
||||
If you are using windows and don't have an IRC client installed then take a look at HydraIRC - here: http://hydrairc.com/
|
||||
https://gitter.im/betaflight/betaflight
|
||||
|
||||
Etiquette: Don't ask to ask and please wait around long enough for a reply - sometimes people are out flying, asleep or at work and can't answer immediately.
|
||||
|
||||
|
@ -79,13 +77,13 @@ Please subscribe and '+1' the videos if you find them useful.
|
|||
|
||||
## Configuration Tool
|
||||
|
||||
To configure Cleanflight you should use the Cleanflight-configurator GUI tool (Windows/OSX/Linux) that can be found here:
|
||||
To configure Betaflight you should use the Betaflight-configurator GUI tool (Windows/OSX/Linux) that can be found here:
|
||||
|
||||
https://chrome.google.com/webstore/detail/cleanflight-configurator/enacoimjcgeinfnnnpajinjgmkahmfgb
|
||||
https://chrome.google.com/webstore/detail/betaflight-configurator/kdaghagfopacdngbohiknlhcocjccjao
|
||||
|
||||
The source for it is here:
|
||||
|
||||
https://github.com/cleanflight/cleanflight-configurator
|
||||
https://github.com/betaflight/betaflight-configurator
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -97,10 +95,10 @@ Contributions are welcome and encouraged. You can contribute in many ways:
|
|||
* New features.
|
||||
* Telling us your ideas and suggestions.
|
||||
|
||||
The best place to start is the IRC channel on freenode (see above), drop in, say hi. Next place is the github issue tracker:
|
||||
The best place to start is the IRC channel on gitter (see above), drop in, say hi. Next place is the github issue tracker:
|
||||
|
||||
https://github.com/cleanflight/cleanflight/issues
|
||||
https://github.com/cleanflight/cleanflight-configurator/issues
|
||||
https://github.com/betaflight/betaflight/issues
|
||||
https://github.com/betaflight/betaflight-configurator/issues
|
||||
|
||||
Before creating new issues please check to see if there is an existing one, search first otherwise you waste peoples time when they could be coding instead!
|
||||
|
||||
|
@ -110,11 +108,48 @@ Please refer to the development section in the `docs/development` folder.
|
|||
|
||||
TravisCI is used to run automatic builds
|
||||
|
||||
https://travis-ci.org/cleanflight/cleanflight
|
||||
https://travis-ci.org/betaflight/betaflight
|
||||
|
||||
[](https://travis-ci.org/cleanflight/cleanflight)
|
||||
[](https://travis-ci.org/betaflight/betaflight)
|
||||
|
||||
## Cleanflight Releases
|
||||
https://github.com/cleanflight/cleanflight/releases
|
||||
## Betaflight Releases
|
||||
https://github.com/betaflight/betaflight/releases
|
||||
|
||||
|
||||
## Open Source / Contributors
|
||||
|
||||
Betaflight is software that is **open source** and is available free of charge without warranty to all users.
|
||||
|
||||
Betaflight is forked from Cleanflight, so thanks goes to all those whom have contributed to Cleanflight and its origins.
|
||||
|
||||
Origins for this fork (Thanks!):
|
||||
* **Alexinparis** (for MultiWii),
|
||||
* **timecop** (for Baseflight),
|
||||
* **Dominic Clifton** (for Cleanflight), and
|
||||
* **Sambas** (for the original STM32F4 port).
|
||||
|
||||
The Betaflight Configurator is forked from Cleanflight Configurator and its origins.
|
||||
|
||||
Origins for Betaflight Configurator:
|
||||
* **Dominic Clifton** (for Cleanflight configurator), and
|
||||
* **ctn** (for the original Configurator).
|
||||
|
||||
Big thanks to current and past contributors:
|
||||
* Budden, Martin (martinbudden)
|
||||
* Bardwell, Joshua (joshuabardwell)
|
||||
* Blackman, Jason (blckmn)
|
||||
* ctzsnooze
|
||||
* Höglund, Anders (andershoglund)
|
||||
* Ledvin, Peter (ledvinap) - **IO code awesomeness!**
|
||||
* kc10kevin
|
||||
* Keeble, Gary (MadmanK)
|
||||
* Keller, Michael (mikeller) - **Configurator brilliance**
|
||||
* Kravcov, Albert (skaman82) - **Configurator brilliance**
|
||||
* MJ666
|
||||
* Nathan (nathantsoi)
|
||||
* ravnav
|
||||
* sambas - **bringing us the F4**
|
||||
* savaga
|
||||
* Stålheim, Anton (KiteAnton)
|
||||
|
||||
And many many others who haven't been mentioned....
|
||||
|
|
14
Vagrantfile
vendored
14
Vagrantfile
vendored
|
@ -19,8 +19,18 @@ Vagrant.configure(2) do |config|
|
|||
# documentation for more information about their specific syntax and use.
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
apt-get remove -y binutils-arm-none-eabi gcc-arm-none-eabi
|
||||
add-apt-repository ppa:terry.guo/gcc-arm-embedded
|
||||
add-apt-repository ppa:team-gcc-arm-embedded/ppa
|
||||
apt-get update
|
||||
apt-get install -y git gcc-arm-none-eabi=4.9.3.2015q3-1trusty1
|
||||
apt-get install -y git ccache gcc-arm-embedded=5-2016q2-1~trusty1
|
||||
SHELL
|
||||
end
|
||||
|
||||
# Usage
|
||||
# On windows start a command shell in the project root directory, where the "Vagrantfile" exists.
|
||||
# "vagrant up" to start the VM. First time it takes a while.....
|
||||
# "vagrant ssh" to log into your VM.
|
||||
# "cd /vagrant" Here are the windows project directory mounted with all your files.
|
||||
# "make all" Start working, building all targets for example.
|
||||
# "exit" when done
|
||||
# vagrant halt to stop your VM
|
||||
# vagrant --help for more....
|
||||
|
|
|
@ -21,8 +21,8 @@ targets=("PUBLISHMETA=True" \
|
|||
"TARGET=DOGE" \
|
||||
"TARGET=SINGULARITY" \
|
||||
"TARGET=SIRINFPV" \
|
||||
"TARGET=X_RACERSPI")
|
||||
|
||||
"TARGET=X_RACERSPI" \
|
||||
"TARGET=RCEXPLORERF3")
|
||||
|
||||
|
||||
#fake a travis build environment
|
||||
|
|
35
make/linux.mk
Normal file
35
make/linux.mk
Normal file
|
@ -0,0 +1,35 @@
|
|||
# linux.mk
|
||||
#
|
||||
# Goals:
|
||||
# Configure an environment that will allow Taulabs GCS and firmware to be built
|
||||
# on a Linux system. The environment will support the current versions of Qt SDK
|
||||
# and the ARM toolchain installed to either the Taulabs/tools directory, their
|
||||
# respective default installation locations, or made available on the system path.
|
||||
|
||||
# Check for and find Python 2
|
||||
|
||||
# Get Python version, separate major/minor/patch, then put into wordlist
|
||||
PYTHON_VERSION_=$(wordlist 2,4,$(subst ., ,$(shell python -V 2>&1)))
|
||||
# Get major version from aforementioned list
|
||||
PYTHON_MAJOR_VERSION_=$(word 1,$(PYTHON_VERSION_))
|
||||
# Just in case Make has some weird scope stuff
|
||||
PYTHON=0
|
||||
# If the major Python version is the one we want..
|
||||
ifeq ($(PYTHON_MAJOR_VERSION_),2)
|
||||
# Then we can just use the normal Python executable
|
||||
PYTHON:=python
|
||||
else
|
||||
# However, this isn't always the case..
|
||||
# Let's look for `python2`. If `which` doesn't return a null value, then
|
||||
# it exists!
|
||||
ifneq ($(shell which python2), "")
|
||||
PYTHON:=python2
|
||||
else
|
||||
# And if it doesn't exist, let's use the default Python, and warn the user.
|
||||
# PYTHON NOT FOUND.
|
||||
PYTHON:=python
|
||||
echo "Python not found."
|
||||
endif
|
||||
endif
|
||||
|
||||
export PYTHON
|
2
make/local.mk
Normal file
2
make/local.mk
Normal file
|
@ -0,0 +1,2 @@
|
|||
# override the toolchain version, should match the output from of your version of the toolchain: $(arm-none-eabi-gcc -dumpversion)
|
||||
#GCC_REQUIRED_VERSION=5.4.1
|
35
make/macosx.mk
Normal file
35
make/macosx.mk
Normal file
|
@ -0,0 +1,35 @@
|
|||
# macosx.mk
|
||||
#
|
||||
# Goals:
|
||||
# Configure an environment that will allow Taulabs GCS and firmware to be built
|
||||
# on a Mac OSX system. The environment will support the current version of the
|
||||
# ARM toolchain installed to either their respective default installation
|
||||
# locations, the tools directory or made available on the system path.
|
||||
|
||||
# Check for and find Python 2
|
||||
|
||||
# Get Python version, separate major/minor/patch, then put into wordlist
|
||||
PYTHON_VERSION_=$(wordlist 2,4,$(subst ., ,$(shell python -V 2>&1)))
|
||||
# Get major version from aforementioned list
|
||||
PYTHON_MAJOR_VERSION_=$(word 1,$(PYTHON_VERSION_))
|
||||
# Just in case Make has some weird scope stuff
|
||||
PYTHON=0
|
||||
# If the major Python version is the one we want..
|
||||
ifeq ($(PYTHON_MAJOR_VERSION_),2)
|
||||
# Then we can just use the normal Python executable
|
||||
PYTHON:=python
|
||||
else
|
||||
# However, this isn't always the case..
|
||||
# Let's look for `python2`. If `which` doesn't return a null value, then
|
||||
# it exists!
|
||||
ifneq ($(shell which python2), "")
|
||||
PYTHON:=python2
|
||||
else
|
||||
# And if it doesn't exist, let's use the default Python, and warn the user.
|
||||
# PYTHON NOT FOUND.
|
||||
PYTHON:=python
|
||||
echo "Python not found."
|
||||
endif
|
||||
endif
|
||||
|
||||
export PYTHON
|
50
make/system-id.mk
Normal file
50
make/system-id.mk
Normal file
|
@ -0,0 +1,50 @@
|
|||
# shared.mk
|
||||
#
|
||||
# environment variables common to all operating systems supported by the make system
|
||||
|
||||
# Make sure we know a few things about the architecture
|
||||
UNAME := $(shell uname)
|
||||
ARCH := $(shell uname -m)
|
||||
ifneq (,$(filter $(ARCH), x86_64 amd64))
|
||||
X86-64 := 1
|
||||
X86_64 := 1
|
||||
AMD64 := 1
|
||||
ARCHFAMILY := x86_64
|
||||
else
|
||||
ARCHFAMILY := $(ARCH)
|
||||
endif
|
||||
|
||||
# configure some variables dependent upon what type of system this is
|
||||
|
||||
# Linux
|
||||
ifeq ($(UNAME), Linux)
|
||||
OSFAMILY := linux
|
||||
LINUX := 1
|
||||
endif
|
||||
|
||||
# Mac OSX
|
||||
ifeq ($(UNAME), Darwin)
|
||||
OSFAMILY := macosx
|
||||
MACOSX := 1
|
||||
endif
|
||||
|
||||
# Windows using MinGW shell
|
||||
ifeq (MINGW, $(findstring MINGW,$(UNAME)))
|
||||
OSFAMILY := windows
|
||||
MINGW := 1
|
||||
WINDOWS := 1
|
||||
endif
|
||||
|
||||
# Windows using Cygwin shell
|
||||
ifeq (CYGWIN ,$(findstring CYGWIN,$(UNAME)))
|
||||
OSFAMILY := windows
|
||||
WINDOWS := 1
|
||||
CYGWIN := 1
|
||||
endif
|
||||
|
||||
# report an error if we couldn't work out what OS this is running on
|
||||
ifndef OSFAMILY
|
||||
$(info uname reports $(UNAME))
|
||||
$(info uname -m reports $(ARCH))
|
||||
$(error failed to detect operating system)
|
||||
endif
|
331
make/tools.mk
Normal file
331
make/tools.mk
Normal file
|
@ -0,0 +1,331 @@
|
|||
###############################################################
|
||||
#
|
||||
# Installers for tools
|
||||
#
|
||||
# NOTE: These are not tied to the default goals
|
||||
# and must be invoked manually
|
||||
#
|
||||
###############################################################
|
||||
|
||||
##############################
|
||||
#
|
||||
# Check that environmental variables are sane
|
||||
#
|
||||
##############################
|
||||
|
||||
# Set up ARM (STM32) SDK
|
||||
ARM_SDK_DIR := $(TOOLS_DIR)/gcc-arm-none-eabi-5_4-2016q2
|
||||
# Checked below, Should match the output of $(shell arm-none-eabi-gcc -dumpversion)
|
||||
GCC_REQUIRED_VERSION := 5.4.1
|
||||
|
||||
.PHONY: arm_sdk_install
|
||||
|
||||
# source: https://launchpad.net/gcc-arm-embedded/5.0/
|
||||
ifdef LINUX
|
||||
arm_sdk_install: ARM_SDK_URL := https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2
|
||||
endif
|
||||
|
||||
ifdef MACOSX
|
||||
arm_sdk_install: ARM_SDK_URL := https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-mac.tar.bz2
|
||||
endif
|
||||
|
||||
ifdef WINDOWS
|
||||
arm_sdk_install: ARM_SDK_URL := https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q2-update/+download/gcc-arm-none-eabi-5_4-2016q2-20160622-win32.zip
|
||||
endif
|
||||
|
||||
arm_sdk_install: ARM_SDK_FILE := $(notdir $(ARM_SDK_URL))
|
||||
# order-only prereq on directory existance:
|
||||
arm_sdk_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
arm_sdk_install: arm_sdk_clean
|
||||
ifneq ($(OSFAMILY), windows)
|
||||
# download the source only if it's newer than what we already have
|
||||
$(V1) curl -L -k -o "$(DL_DIR)/$(ARM_SDK_FILE)" "$(ARM_SDK_URL)"
|
||||
|
||||
# binary only release so just extract it
|
||||
$(V1) tar -C $(TOOLS_DIR) -xjf "$(DL_DIR)/$(ARM_SDK_FILE)"
|
||||
else
|
||||
$(V1) curl -L -k -o "$(DL_DIR)/$(ARM_SDK_FILE)" "$(ARM_SDK_URL)"
|
||||
$(V1) unzip -q -d $(ARM_SDK_DIR) "$(DL_DIR)/$(ARM_SDK_FILE)"
|
||||
endif
|
||||
|
||||
.PHONY: arm_sdk_clean
|
||||
arm_sdk_clean:
|
||||
$(V1) [ ! -d "$(ARM_SDK_DIR)" ] || $(RM) -r $(ARM_SDK_DIR)
|
||||
|
||||
.PHONY: openocd_win_install
|
||||
|
||||
openocd_win_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
openocd_win_install: OPENOCD_URL := git://git.code.sf.net/p/openocd/code
|
||||
openocd_win_install: OPENOCD_REV := cf1418e9a85013bbf8dbcc2d2e9985695993d9f4
|
||||
openocd_win_install: OPENOCD_OPTIONS :=
|
||||
|
||||
ifeq ($(OPENOCD_FTDI), yes)
|
||||
openocd_win_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=$(FTD2XX_DIR)
|
||||
endif
|
||||
|
||||
openocd_win_install: openocd_win_clean libusb_win_install ftd2xx_install
|
||||
# download the source
|
||||
$(V0) @echo " DOWNLOAD $(OPENOCD_URL) @ $(OPENOCD_REV)"
|
||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
||||
$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
|
||||
$(V1) git clone --no-checkout $(OPENOCD_URL) "$(DL_DIR)/openocd-build"
|
||||
$(V1) ( \
|
||||
cd $(OPENOCD_BUILD_DIR) ; \
|
||||
git checkout -q $(OPENOCD_REV) ; \
|
||||
)
|
||||
|
||||
# apply patches
|
||||
$(V0) @echo " PATCH $(OPENOCD_BUILD_DIR)"
|
||||
$(V1) ( \
|
||||
cd $(OPENOCD_BUILD_DIR) ; \
|
||||
git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0003-freertos-cm4f-fpu-support.patch ; \
|
||||
git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0004-st-icdi-disable.patch ; \
|
||||
)
|
||||
|
||||
# build and install
|
||||
$(V0) @echo " BUILD $(OPENOCD_WIN_DIR)"
|
||||
$(V1) mkdir -p "$(OPENOCD_WIN_DIR)"
|
||||
$(V1) ( \
|
||||
cd $(OPENOCD_BUILD_DIR) ; \
|
||||
./bootstrap ; \
|
||||
./configure --enable-maintainer-mode --prefix="$(OPENOCD_WIN_DIR)" \
|
||||
--build=i686-pc-linux-gnu --host=i586-mingw32msvc \
|
||||
CPPFLAGS=-I$(LIBUSB_WIN_DIR)/include \
|
||||
LDFLAGS=-L$(LIBUSB_WIN_DIR)/lib/gcc \
|
||||
$(OPENOCD_OPTIONS) \
|
||||
--disable-werror \
|
||||
--enable-stlink ; \
|
||||
$(MAKE) ; \
|
||||
$(MAKE) install ; \
|
||||
)
|
||||
|
||||
# delete the extracted source when we're done
|
||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
||||
|
||||
.PHONY: openocd_win_clean
|
||||
openocd_win_clean:
|
||||
$(V0) @echo " CLEAN $(OPENOCD_WIN_DIR)"
|
||||
$(V1) [ ! -d "$(OPENOCD_WIN_DIR)" ] || $(RM) -r "$(OPENOCD_WIN_DIR)"
|
||||
|
||||
# Set up openocd tools
|
||||
OPENOCD_DIR := $(TOOLS_DIR)/openocd
|
||||
OPENOCD_WIN_DIR := $(TOOLS_DIR)/openocd_win
|
||||
OPENOCD_BUILD_DIR := $(DL_DIR)/openocd-build
|
||||
|
||||
.PHONY: openocd_install
|
||||
|
||||
openocd_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
openocd_install: OPENOCD_URL := git://git.code.sf.net/p/openocd/code
|
||||
openocd_install: OPENOCD_TAG := v0.9.0
|
||||
openocd_install: OPENOCD_OPTIONS := --enable-maintainer-mode --prefix="$(OPENOCD_DIR)" --enable-buspirate --enable-stlink
|
||||
|
||||
ifeq ($(OPENOCD_FTDI), yes)
|
||||
openocd_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --enable-ftdi
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
openocd_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --disable-option-checking
|
||||
endif
|
||||
|
||||
openocd_install: openocd_clean
|
||||
# download the source
|
||||
$(V0) @echo " DOWNLOAD $(OPENOCD_URL) @ $(OPENOCD_TAG)"
|
||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
||||
$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
|
||||
$(V1) git clone --no-checkout $(OPENOCD_URL) "$(OPENOCD_BUILD_DIR)"
|
||||
$(V1) ( \
|
||||
cd $(OPENOCD_BUILD_DIR) ; \
|
||||
git checkout -q tags/$(OPENOCD_TAG) ; \
|
||||
)
|
||||
|
||||
# build and install
|
||||
$(V0) @echo " BUILD $(OPENOCD_DIR)"
|
||||
$(V1) mkdir -p "$(OPENOCD_DIR)"
|
||||
$(V1) ( \
|
||||
cd $(OPENOCD_BUILD_DIR) ; \
|
||||
./bootstrap ; \
|
||||
./configure $(OPENOCD_OPTIONS) ; \
|
||||
$(MAKE) ; \
|
||||
$(MAKE) install ; \
|
||||
)
|
||||
|
||||
# delete the extracted source when we're done
|
||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
||||
|
||||
.PHONY: openocd_clean
|
||||
openocd_clean:
|
||||
$(V0) @echo " CLEAN $(OPENOCD_DIR)"
|
||||
$(V1) [ ! -d "$(OPENOCD_DIR)" ] || $(RM) -r "$(OPENOCD_DIR)"
|
||||
|
||||
STM32FLASH_DIR := $(TOOLS_DIR)/stm32flash
|
||||
|
||||
.PHONY: stm32flash_install
|
||||
stm32flash_install: STM32FLASH_URL := http://stm32flash.googlecode.com/svn/trunk
|
||||
stm32flash_install: STM32FLASH_REV := 61
|
||||
stm32flash_install: stm32flash_clean
|
||||
# download the source
|
||||
$(V0) @echo " DOWNLOAD $(STM32FLASH_URL) @ r$(STM32FLASH_REV)"
|
||||
$(V1) svn export -q -r "$(STM32FLASH_REV)" "$(STM32FLASH_URL)" "$(STM32FLASH_DIR)"
|
||||
|
||||
# build
|
||||
$(V0) @echo " BUILD $(STM32FLASH_DIR)"
|
||||
$(V1) $(MAKE) --silent -C $(STM32FLASH_DIR) all
|
||||
|
||||
.PHONY: stm32flash_clean
|
||||
stm32flash_clean:
|
||||
$(V0) @echo " CLEAN $(STM32FLASH_DIR)"
|
||||
$(V1) [ ! -d "$(STM32FLASH_DIR)" ] || $(RM) -r "$(STM32FLASH_DIR)"
|
||||
|
||||
DFUUTIL_DIR := $(TOOLS_DIR)/dfu-util
|
||||
|
||||
.PHONY: dfuutil_install
|
||||
dfuutil_install: DFUUTIL_URL := http://dfu-util.sourceforge.net/releases/dfu-util-0.8.tar.gz
|
||||
dfuutil_install: DFUUTIL_FILE := $(notdir $(DFUUTIL_URL))
|
||||
dfuutil_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
dfuutil_install: dfuutil_clean
|
||||
# download the source
|
||||
$(V0) @echo " DOWNLOAD $(DFUUTIL_URL)"
|
||||
$(V1) curl -L -k -o "$(DL_DIR)/$(DFUUTIL_FILE)" "$(DFUUTIL_URL)"
|
||||
|
||||
# extract the source
|
||||
$(V0) @echo " EXTRACT $(DFUUTIL_FILE)"
|
||||
$(V1) [ ! -d "$(DL_DIR)/dfuutil-build" ] || $(RM) -r "$(DL_DIR)/dfuutil-build"
|
||||
$(V1) mkdir -p "$(DL_DIR)/dfuutil-build"
|
||||
$(V1) tar -C $(DL_DIR)/dfuutil-build -xf "$(DL_DIR)/$(DFUUTIL_FILE)"
|
||||
|
||||
# build
|
||||
$(V0) @echo " BUILD $(DFUUTIL_DIR)"
|
||||
$(V1) mkdir -p "$(DFUUTIL_DIR)"
|
||||
$(V1) ( \
|
||||
cd $(DL_DIR)/dfuutil-build/dfu-util-0.8 ; \
|
||||
./configure --prefix="$(DFUUTIL_DIR)" ; \
|
||||
$(MAKE) ; \
|
||||
$(MAKE) install ; \
|
||||
)
|
||||
|
||||
.PHONY: dfuutil_clean
|
||||
dfuutil_clean:
|
||||
$(V0) @echo " CLEAN $(DFUUTIL_DIR)"
|
||||
$(V1) [ ! -d "$(DFUUTIL_DIR)" ] || $(RM) -r "$(DFUUTIL_DIR)"
|
||||
|
||||
# Set up uncrustify tools
|
||||
UNCRUSTIFY_DIR := $(TOOLS_DIR)/uncrustify-0.61
|
||||
UNCRUSTIFY_BUILD_DIR := $(DL_DIR)/uncrustify
|
||||
|
||||
.PHONY: uncrustify_install
|
||||
uncrustify_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
uncrustify_install: UNCRUSTIFY_URL := http://downloads.sourceforge.net/project/uncrustify/uncrustify/uncrustify-0.61/uncrustify-0.61.tar.gz
|
||||
uncrustify_install: UNCRUSTIFY_FILE := uncrustify-0.61.tar.gz
|
||||
uncrustify_install: UNCRUSTIFY_OPTIONS := prefix=$(UNCRUSTIFY_DIR)
|
||||
uncrustify_install: uncrustify_clean
|
||||
ifneq ($(OSFAMILY), windows)
|
||||
$(V0) @echo " DOWNLOAD $(UNCRUSTIFY_URL)"
|
||||
$(V1) curl -L -k -o "$(DL_DIR)/$(UNCRUSTIFY_FILE)" "$(UNCRUSTIFY_URL)"
|
||||
endif
|
||||
# extract the src
|
||||
$(V0) @echo " EXTRACT $(UNCRUSTIFY_FILE)"
|
||||
$(V1) tar -C $(TOOLS_DIR) -xf "$(DL_DIR)/$(UNCRUSTIFY_FILE)"
|
||||
|
||||
$(V0) @echo " BUILD $(UNCRUSTIFY_DIR)"
|
||||
$(V1) ( \
|
||||
cd $(UNCRUSTIFY_DIR) ; \
|
||||
./configure --prefix="$(UNCRUSTIFY_DIR)" ; \
|
||||
$(MAKE) ; \
|
||||
$(MAKE) install ; \
|
||||
)
|
||||
# delete the extracted source when we're done
|
||||
$(V1) [ ! -d "$(UNCRUSTIFY_BUILD_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_BUILD_DIR)"
|
||||
|
||||
.PHONY: uncrustify_clean
|
||||
uncrustify_clean:
|
||||
$(V0) @echo " CLEAN $(UNCRUSTIFY_DIR)"
|
||||
$(V1) [ ! -d "$(UNCRUSTIFY_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_DIR)"
|
||||
$(V0) @echo " CLEAN $(UNCRUSTIFY_BUILD_DIR)"
|
||||
$(V1) [ ! -d "$(UNCRUSTIFY_BUILD_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_BUILD_DIR)"
|
||||
|
||||
# ZIP download URL
|
||||
zip_install: ZIP_URL := http://pkgs.fedoraproject.org/repo/pkgs/zip/zip30.tar.gz/7b74551e63f8ee6aab6fbc86676c0d37/zip30.tar.gz
|
||||
|
||||
zip_install: ZIP_FILE := $(notdir $(ZIP_URL))
|
||||
|
||||
ZIP_DIR = $(TOOLS_DIR)/zip30
|
||||
|
||||
# order-only prereq on directory existance:
|
||||
zip_install : | $(DL_DIR) $(TOOLS_DIR)
|
||||
zip_install: zip_clean
|
||||
$(V1) curl -L -k -o "$(DL_DIR)/$(ZIP_FILE)" "$(ZIP_URL)"
|
||||
$(V1) tar --force-local -C $(TOOLS_DIR) -xzf "$(DL_DIR)/$(ZIP_FILE)"
|
||||
ifneq ($(OSFAMILY), windows)
|
||||
$(V1) cd "$(ZIP_DIR)" && $(MAKE) -f unix/Makefile generic_gcc
|
||||
else
|
||||
$(V1) cd "$(ZIP_DIR)" && $(MAKE) -f win32/makefile.gcc
|
||||
endif
|
||||
|
||||
.PHONY: zip_clean
|
||||
zip_clean:
|
||||
$(V1) [ ! -d "$(ZIP_DIR)" ] || $(RM) -rf $(ZIP_DIR)
|
||||
|
||||
##############################
|
||||
#
|
||||
# Set up paths to tools
|
||||
#
|
||||
##############################
|
||||
|
||||
GCC_VERSION=$(shell arm-none-eabi-gcc -dumpversion)
|
||||
ifeq ($(shell [ -d "$(ARM_SDK_DIR)" ] && echo "exists"), exists)
|
||||
ARM_SDK_PREFIX := $(ARM_SDK_DIR)/bin/arm-none-eabi-
|
||||
else ifeq (,$(findstring _install,$(MAKECMDGOALS)))
|
||||
ifeq ($(GCC_VERSION),)
|
||||
$(error **ERROR** arm-none-eabi-gcc not in the PATH. Run 'make arm_sdk_install' to install automatically in the tools folder of this repo)
|
||||
else ifneq ($(GCC_VERSION), $(GCC_REQUIRED_VERSION))
|
||||
$(error **ERROR** your arm-none-eabi-gcc is '$(GCC_VERSION)', but '$(GCC_REQUIRED_VERSION)' is expected. Override with 'GCC_REQUIRED_VERSION' in make/local.mk or run 'make arm_sdk_install' to install the right version automatically in the tools folder of this repo)
|
||||
endif
|
||||
# not installed, hope it's in the path...
|
||||
ARM_SDK_PREFIX ?= arm-none-eabi-
|
||||
endif
|
||||
|
||||
ifeq ($(shell [ -d "$(ZIP_DIR)" ] && echo "exists"), exists)
|
||||
export ZIPBIN := $(ZIP_DIR)/zip
|
||||
else
|
||||
export ZIPBIN := zip
|
||||
endif
|
||||
|
||||
ifeq ($(shell [ -d "$(OPENOCD_DIR)" ] && echo "exists"), exists)
|
||||
OPENOCD := $(OPENOCD_DIR)/bin/openocd
|
||||
else
|
||||
# not installed, hope it's in the path...
|
||||
OPENOCD ?= openocd
|
||||
endif
|
||||
|
||||
ifeq ($(shell [ -d "$(UNCRUSTIFY_DIR)" ] && echo "exists"), exists)
|
||||
UNCRUSTIFY := $(UNCRUSTIFY_DIR)/bin/uncrustify
|
||||
else
|
||||
# not installed, hope it's in the path...
|
||||
UNCRUSTIFY ?= uncrustify
|
||||
endif
|
||||
|
||||
# Google Breakpad
|
||||
DUMP_SYMBOLS_TOOL := $(TOOLS_DIR)/breakpad/$(OSFAMILY)-$(ARCHFAMILY)/dump_syms
|
||||
BREAKPAD_URL := http://dronin.tracer.nz/tools/breakpad.zip
|
||||
BREAKPAD_DL_FILE := $(DL_DIR)/$(notdir $(BREAKPAD_URL))
|
||||
BREAKPAD_DIR := $(TOOLS_DIR)/breakpad
|
||||
|
||||
.PHONY: breakpad_install
|
||||
breakpad_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
breakpad_install: breakpad_clean
|
||||
$(V0) @echo " DOWNLOAD $(BREAKPAD_URL)"
|
||||
$(V1) $(V1) curl -L -k -z "$(BREAKPAD_DL_FILE)" -o "$(BREAKPAD_DL_FILE)" "$(BREAKPAD_URL)"
|
||||
$(V0) @echo " EXTRACT $(notdir $(BREAKPAD_DL_FILE))"
|
||||
$(V1) mkdir -p "$(BREAKPAD_DIR)"
|
||||
$(V1) unzip -q -d $(BREAKPAD_DIR) "$(BREAKPAD_DL_FILE)"
|
||||
ifeq ($(OSFAMILY), windows)
|
||||
$(V1) ln -s "$(TOOLS_DIR)/breakpad/$(OSFAMILY)-i686" "$(TOOLS_DIR)/breakpad/$(OSFAMILY)-x86_64"
|
||||
endif
|
||||
|
||||
.PHONY: breakpad_clean
|
||||
breakpad_clean:
|
||||
$(V0) @echo " CLEAN $(BREAKPAD_DIR)"
|
||||
$(V1) [ ! -d "$(BREAKPAD_DIR)" ] || $(RM) -rf $(BREAKPAD_DIR)
|
||||
$(V0) @echo " CLEAN $(BREAKPAD_DL_FILE)"
|
||||
$(V1) $(RM) -f $(BREAKPAD_DL_FILE)
|
||||
|
14
make/windows.mk
Normal file
14
make/windows.mk
Normal file
|
@ -0,0 +1,14 @@
|
|||
# windows.mk
|
||||
#
|
||||
# Goals:
|
||||
# Configure an environment that will allow Taulabs GCS and firmware to be built
|
||||
# on a Windows system. The environment will support the current version of the
|
||||
# ARM toolchain installed to either their respective default installation
|
||||
# locations, the tools directory or made available on the system path.
|
||||
#
|
||||
# Requirements:
|
||||
# msysGit
|
||||
# Python
|
||||
|
||||
PYTHON := python
|
||||
export PYTHON
|
|
@ -19,11 +19,12 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "version.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef BLACKBOX
|
||||
|
||||
#include "build/version.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
#include "common/axis.h"
|
||||
#include "common/color.h"
|
||||
|
@ -52,7 +53,7 @@
|
|||
#include "io/beeper.h"
|
||||
#include "io/display.h"
|
||||
#include "io/escservo.h"
|
||||
#include "io/rc_controls.h"
|
||||
#include "fc/rc_controls.h"
|
||||
#include "io/gimbal.h"
|
||||
#include "io/gps.h"
|
||||
#include "io/ledstrip.h"
|
||||
|
@ -72,12 +73,15 @@
|
|||
#include "flight/altitudehold.h"
|
||||
#include "flight/failsafe.h"
|
||||
#include "flight/imu.h"
|
||||
#include "flight/pid.h"
|
||||
#include "flight/navigation.h"
|
||||
|
||||
#include "config/runtime_config.h"
|
||||
#include "fc/runtime_config.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/config_profile.h"
|
||||
#include "config/config_master.h"
|
||||
#include "config/feature.h"
|
||||
|
||||
#include "blackbox.h"
|
||||
#include "blackbox_io.h"
|
||||
|
@ -632,7 +636,7 @@ static void writeInterframe(void)
|
|||
arraySubInt32(deltas, blackboxCurrent->axisPID_P, blackboxLast->axisPID_P, XYZ_AXIS_COUNT);
|
||||
blackboxWriteSignedVBArray(deltas, XYZ_AXIS_COUNT);
|
||||
|
||||
/*
|
||||
/*
|
||||
* The PID I field changes very slowly, most of the time +-2, so use an encoding
|
||||
* that can pack all three fields into one byte in that situation.
|
||||
*/
|
||||
|
@ -893,6 +897,61 @@ void finishBlackbox(void)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Motors Blackbox Logging
|
||||
*/
|
||||
bool startedLoggingInTestMode = false;
|
||||
|
||||
void startInTestMode(void)
|
||||
{
|
||||
if(!startedLoggingInTestMode) {
|
||||
if (masterConfig.blackbox_device == BLACKBOX_DEVICE_SERIAL) {
|
||||
serialPort_t *sharedBlackboxAndMspPort = findSharedSerialPort(FUNCTION_BLACKBOX, FUNCTION_MSP);
|
||||
if (sharedBlackboxAndMspPort) {
|
||||
return; // When in test mode, we cannot share the MSP and serial logger port!
|
||||
}
|
||||
}
|
||||
startBlackbox();
|
||||
startedLoggingInTestMode = true;
|
||||
}
|
||||
}
|
||||
void stopInTestMode(void)
|
||||
{
|
||||
if(startedLoggingInTestMode) {
|
||||
finishBlackbox();
|
||||
startedLoggingInTestMode = false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* We are going to monitor the MSP_SET_MOTOR target variables motor_disarmed[] for values other than minthrottle
|
||||
* on reading a value (i.e. the user is testing the motors), then we enable test mode logging;
|
||||
* we monitor when the values return to minthrottle and start a delay timer (5 seconds); if
|
||||
* the test motors are left at minimum throttle for this delay timer, then we assume we are done testing and
|
||||
* shutdown the logger.
|
||||
*
|
||||
* Of course, after the 5 seconds and shutdown of the logger, the system will be re-enabled to allow the
|
||||
* test mode to trigger again; its just that the data will be in a second, third, fourth etc log file.
|
||||
*/
|
||||
bool inMotorTestMode(void) {
|
||||
static uint32_t resetTime = 0;
|
||||
uint16_t inactiveMotorCommand = (feature(FEATURE_3D) ? masterConfig.flight3DConfig.neutral3d : masterConfig.escAndServoConfig.mincommand);
|
||||
int i;
|
||||
bool atLeastOneMotorActivated = false;
|
||||
|
||||
// set disarmed motor values
|
||||
for (i = 0; i < MAX_SUPPORTED_MOTORS; i++)
|
||||
atLeastOneMotorActivated |= (motor_disarmed[i] != inactiveMotorCommand);
|
||||
|
||||
if(atLeastOneMotorActivated) {
|
||||
resetTime = millis() + 5000; // add 5 seconds
|
||||
return true;
|
||||
} else {
|
||||
// Monitor the duration at minimum
|
||||
return (millis() < resetTime);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef GPS
|
||||
static void writeGPSHomeFrame()
|
||||
{
|
||||
|
@ -1140,6 +1199,7 @@ static bool blackboxWriteSysinfo()
|
|||
BLACKBOX_PRINT_HEADER_LINE("Firmware type:%s", "Cleanflight");
|
||||
BLACKBOX_PRINT_HEADER_LINE("Firmware revision:Betaflight %s (%s) %s", FC_VERSION_STRING, shortGitRevision, targetName);
|
||||
BLACKBOX_PRINT_HEADER_LINE("Firmware date:%s %s", buildDate, buildTime);
|
||||
BLACKBOX_PRINT_HEADER_LINE("Craft name:%s", masterConfig.name);
|
||||
BLACKBOX_PRINT_HEADER_LINE("P interval:%d/%d", masterConfig.blackbox_rate_num, masterConfig.blackbox_rate_denom);
|
||||
BLACKBOX_PRINT_HEADER_LINE("minthrottle:%d", masterConfig.escAndServoConfig.minthrottle);
|
||||
BLACKBOX_PRINT_HEADER_LINE("maxthrottle:%d", masterConfig.escAndServoConfig.maxthrottle);
|
||||
|
@ -1167,6 +1227,8 @@ static bool blackboxWriteSysinfo()
|
|||
);
|
||||
|
||||
BLACKBOX_PRINT_HEADER_LINE("looptime:%d", gyro.targetLooptime);
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_sync_denom:%d", masterConfig.gyro_sync_denom);
|
||||
BLACKBOX_PRINT_HEADER_LINE("pid_process_denom:%d", masterConfig.pid_process_denom);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rcRate:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcRate8);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rcExpo:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcExpo8);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rcYawRate:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcYawRate8);
|
||||
|
@ -1207,25 +1269,47 @@ static bool blackboxWriteSysinfo()
|
|||
BLACKBOX_PRINT_HEADER_LINE("velPID:%d,%d,%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.P8[PIDVEL],
|
||||
masterConfig.profile[masterConfig.current_profile_index].pidProfile.I8[PIDVEL],
|
||||
masterConfig.profile[masterConfig.current_profile_index].pidProfile.D8[PIDVEL]);
|
||||
BLACKBOX_PRINT_HEADER_LINE("yaw_p_limit:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.yaw_p_limit);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_filter_type:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_filter_type);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_lpf_hz:%d", (int)(masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_lpf_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("yaw_lpf_hz:%d", (int)(masterConfig.profile[masterConfig.current_profile_index].pidProfile.yaw_lpf_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_average_count:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_average_count);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dynamic_pid:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.dynamic_pid);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_notch_hz:%d", (int)(masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_notch_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_notch_cutoff:%d", (int)(masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_notch_cutoff * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("deltaMethod:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.deltaMethod);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rollPitchItermIgnoreRate:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.rollPitchItermIgnoreRate);
|
||||
BLACKBOX_PRINT_HEADER_LINE("yawItermIgnoreRate:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.yawItermIgnoreRate);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_lpf_hz:%d", (int)(masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_lpf_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("yaw_p_limit:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.yaw_p_limit);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dterm_average_count:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.dterm_average_count);
|
||||
BLACKBOX_PRINT_HEADER_LINE("vbat_pid_compensation:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.vbatPidCompensation);
|
||||
BLACKBOX_PRINT_HEADER_LINE("pidAtMinThrottle:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.pidAtMinThrottle);
|
||||
|
||||
// Betaflight PID controller parameters
|
||||
BLACKBOX_PRINT_HEADER_LINE("itermThrottleGain:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.itermThrottleGain);
|
||||
BLACKBOX_PRINT_HEADER_LINE("ptermSRateWeight:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.ptermSRateWeight);
|
||||
BLACKBOX_PRINT_HEADER_LINE("dtermSetpointWeight:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.dtermSetpointWeight);
|
||||
BLACKBOX_PRINT_HEADER_LINE("yawRateAccelLimit:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.yawRateAccelLimit);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rateAccelLimit:%d", masterConfig.profile[masterConfig.current_profile_index].pidProfile.rateAccelLimit);
|
||||
// End of Betaflight controller parameters
|
||||
|
||||
BLACKBOX_PRINT_HEADER_LINE("deadband:%d", masterConfig.rcControlsConfig.deadband);
|
||||
BLACKBOX_PRINT_HEADER_LINE("yaw_deadband:%d", masterConfig.rcControlsConfig.yaw_deadband);
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_lpf:%d", masterConfig.gyro_lpf);
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_soft_type:%d", masterConfig.gyro_soft_type);
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_lowpass_hz:%d", (int)(masterConfig.gyro_soft_lpf_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_notch_hz:%d", (int)(masterConfig.gyro_soft_notch_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_notch_cutoff:%d", (int)(masterConfig.gyro_soft_notch_cutoff * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("acc_lpf_hz:%d", (int)(masterConfig.acc_lpf_hz * 100.0f));
|
||||
BLACKBOX_PRINT_HEADER_LINE("acc_hardware:%d", masterConfig.acc_hardware);
|
||||
BLACKBOX_PRINT_HEADER_LINE("baro_hardware:%d", masterConfig.baro_hardware);
|
||||
BLACKBOX_PRINT_HEADER_LINE("mag_hardware:%d", masterConfig.mag_hardware);
|
||||
BLACKBOX_PRINT_HEADER_LINE("gyro_cal_on_first_arm:%d", masterConfig.gyro_cal_on_first_arm);
|
||||
BLACKBOX_PRINT_HEADER_LINE("vbat_pid_compensation:%d", masterConfig.batteryConfig.vbatPidCompensation);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rc_smooth_interval:%d", masterConfig.rxConfig.rcSmoothInterval);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rc_interpolation:%d", masterConfig.rxConfig.rcInterpolation);
|
||||
BLACKBOX_PRINT_HEADER_LINE("rc_interpolation_interval:%d", masterConfig.rxConfig.rcInterpolationInterval);
|
||||
BLACKBOX_PRINT_HEADER_LINE("airmode_activate_throttle:%d", masterConfig.rxConfig.airModeActivateThreshold);
|
||||
BLACKBOX_PRINT_HEADER_LINE("serialrx_provider:%d", masterConfig.rxConfig.serialrx_provider);
|
||||
BLACKBOX_PRINT_HEADER_LINE("unsynced_fast_pwm:%d", masterConfig.use_unsyncedPwm);
|
||||
BLACKBOX_PRINT_HEADER_LINE("fast_pwm_protocol:%d", masterConfig.motor_pwm_protocol);
|
||||
BLACKBOX_PRINT_HEADER_LINE("motor_pwm_rate:%d", masterConfig.motor_pwm_rate);
|
||||
BLACKBOX_PRINT_HEADER_LINE("debug_mode:%d", masterConfig.debug_mode);
|
||||
BLACKBOX_PRINT_HEADER_LINE("features:%d", masterConfig.enabledFeatures);
|
||||
|
||||
default:
|
||||
|
@ -1314,7 +1398,7 @@ static void blackboxCheckAndLogFlightMode()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Use the user's num/denom settings to decide if the P-frame of the given index should be logged, allowing the user to control
|
||||
* the portion of logged loop iterations.
|
||||
*/
|
||||
|
@ -1505,7 +1589,8 @@ void handleBlackbox(void)
|
|||
break;
|
||||
case BLACKBOX_STATE_RUNNING:
|
||||
// On entry to this state, blackboxIteration, blackboxPFrameIndex and blackboxIFrameIndex are reset to 0
|
||||
if (blackboxModeActivationConditionPresent && !IS_RC_MODE_ACTIVE(BOXBLACKBOX)) {
|
||||
// Prevent the Pausing of the log on the mode switch if in Motor Test Mode
|
||||
if (blackboxModeActivationConditionPresent && !IS_RC_MODE_ACTIVE(BOXBLACKBOX) && !startedLoggingInTestMode) {
|
||||
blackboxSetState(BLACKBOX_STATE_PAUSED);
|
||||
} else {
|
||||
blackboxLogIteration();
|
||||
|
@ -1534,6 +1619,20 @@ void handleBlackbox(void)
|
|||
// Did we run out of room on the device? Stop!
|
||||
if (isBlackboxDeviceFull()) {
|
||||
blackboxSetState(BLACKBOX_STATE_STOPPED);
|
||||
// ensure we reset the test mode flag if we stop due to full memory card
|
||||
if (startedLoggingInTestMode) startedLoggingInTestMode = false;
|
||||
} else { // Only log in test mode if there is room!
|
||||
|
||||
if(masterConfig.blackbox_on_motor_test) {
|
||||
// Handle Motor Test Mode
|
||||
if(inMotorTestMode()) {
|
||||
if(blackboxState==BLACKBOX_STATE_STOPPED)
|
||||
startInTestMode();
|
||||
} else {
|
||||
if(blackboxState!=BLACKBOX_STATE_STOPPED)
|
||||
stopInTestMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include "blackbox_io.h"
|
||||
|
||||
#include "version.h"
|
||||
#include "build_config.h"
|
||||
#include "build/version.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
#include "common/axis.h"
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include "io/display.h"
|
||||
#include "io/escservo.h"
|
||||
#include "rx/rx.h"
|
||||
#include "io/rc_controls.h"
|
||||
#include "fc/rc_controls.h"
|
||||
#include "io/osd.h"
|
||||
#include "io/vtx.h"
|
||||
|
||||
|
@ -53,9 +53,11 @@
|
|||
#include "flight/altitudehold.h"
|
||||
#include "flight/failsafe.h"
|
||||
#include "flight/imu.h"
|
||||
#include "flight/pid.h"
|
||||
#include "flight/navigation.h"
|
||||
|
||||
#include "config/runtime_config.h"
|
||||
#include "fc/runtime_config.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/config_profile.h"
|
||||
#include "config/config_master.h"
|
||||
|
@ -507,7 +509,7 @@ void blackboxWriteFloat(float value)
|
|||
|
||||
/**
|
||||
* If there is data waiting to be written to the blackbox device, attempt to write (a portion of) that now.
|
||||
*
|
||||
*
|
||||
* Intended to be called regularly for the blackbox device to perform housekeeping.
|
||||
*/
|
||||
void blackboxDeviceFlush(void)
|
||||
|
@ -648,7 +650,7 @@ void blackboxDeviceClose(void)
|
|||
* of time to shut down asynchronously, we're the only ones that know when to call it.
|
||||
*/
|
||||
if (blackboxPortSharing == PORTSHARING_SHARED) {
|
||||
mspAllocateSerialPorts(&masterConfig.serialConfig);
|
||||
mspSerialAllocatePorts(&masterConfig.serialConfig);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define DEBUG16_VALUE_COUNT 4
|
||||
extern int16_t debug[DEBUG16_VALUE_COUNT];
|
||||
extern uint8_t debugMode;
|
||||
|
@ -50,5 +52,10 @@ typedef enum {
|
|||
DEBUG_MIXER,
|
||||
DEBUG_AIRMODE,
|
||||
DEBUG_PIDLOOP,
|
||||
DEBUG_NOTCH,
|
||||
DEBUG_RC_INTERPOLATION,
|
||||
DEBUG_VELOCITY,
|
||||
DEBUG_DTERM_FILTER,
|
||||
DEBUG_ANGLERATE,
|
||||
DEBUG_COUNT
|
||||
} debugType_e;
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
#define FC_VERSION_MAJOR 3 // increment when a major release is made (big new feature, etc)
|
||||
#define FC_VERSION_MINOR 0 // increment when a minor release is made (small new feature, change etc)
|
||||
#define FC_VERSION_MINOR 1 // increment when a minor release is made (small new feature, change etc)
|
||||
#define FC_VERSION_PATCH_LEVEL 0 // increment when a bug is fixed
|
||||
|
||||
#define STR_HELPER(x) #x
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "common/filter.h"
|
||||
|
@ -55,25 +56,45 @@ float pt1FilterApply4(pt1Filter_t *filter, float input, uint8_t f_cut, float dT)
|
|||
return filter->state;
|
||||
}
|
||||
|
||||
/* sets up a biquad Filter */
|
||||
void biquadFilterInit(biquadFilter_t *filter, float filterCutFreq, uint32_t refreshRate)
|
||||
{
|
||||
const float sampleRate = 1 / ((float)refreshRate * 0.000001f);
|
||||
float filterGetNotchQ(uint16_t centerFreq, uint16_t cutoff) {
|
||||
float octaves = log2f((float) centerFreq / (float) cutoff) * 2;
|
||||
return sqrtf(powf(2, octaves)) / (powf(2, octaves) - 1);
|
||||
}
|
||||
|
||||
/* sets up a biquad Filter */
|
||||
void biquadFilterInitLPF(biquadFilter_t *filter, float filterFreq, uint32_t refreshRate)
|
||||
{
|
||||
biquadFilterInit(filter, filterFreq, refreshRate, BIQUAD_Q, FILTER_LPF);
|
||||
}
|
||||
void biquadFilterInit(biquadFilter_t *filter, float filterFreq, uint32_t refreshRate, float Q, biquadFilterType_e filterType)
|
||||
{
|
||||
// setup variables
|
||||
const float omega = 2 * M_PI_FLOAT * filterCutFreq / sampleRate;
|
||||
const float sampleRate = 1 / ((float)refreshRate * 0.000001f);
|
||||
const float omega = 2 * M_PI_FLOAT * filterFreq / sampleRate;
|
||||
const float sn = sinf(omega);
|
||||
const float cs = cosf(omega);
|
||||
//this is wrong, should be hyperbolic sine
|
||||
//alpha = sn * sinf(M_LN2_FLOAT /2 * BIQUAD_BANDWIDTH * omega /sn);
|
||||
const float alpha = sn / (2 * BIQUAD_Q);
|
||||
const float alpha = sn / (2 * Q);
|
||||
|
||||
const float b0 = (1 - cs) / 2;
|
||||
const float b1 = 1 - cs;
|
||||
const float b2 = (1 - cs) / 2;
|
||||
const float a0 = 1 + alpha;
|
||||
const float a1 = -2 * cs;
|
||||
const float a2 = 1 - alpha;
|
||||
float b0, b1, b2, a0, a1, a2;
|
||||
|
||||
switch (filterType) {
|
||||
case FILTER_LPF:
|
||||
b0 = (1 - cs) / 2;
|
||||
b1 = 1 - cs;
|
||||
b2 = (1 - cs) / 2;
|
||||
a0 = 1 + alpha;
|
||||
a1 = -2 * cs;
|
||||
a2 = 1 - alpha;
|
||||
break;
|
||||
case FILTER_NOTCH:
|
||||
b0 = 1;
|
||||
b1 = -2 * cs;
|
||||
b2 = 1;
|
||||
a0 = 1 + alpha;
|
||||
a1 = -2 * cs;
|
||||
a2 = 1 - alpha;
|
||||
break;
|
||||
}
|
||||
|
||||
// precompute the coefficients
|
||||
filter->b0 = b0 / a0;
|
||||
|
@ -95,25 +116,124 @@ float biquadFilterApply(biquadFilter_t *filter, float input)
|
|||
return result;
|
||||
}
|
||||
|
||||
int32_t filterApplyAverage(int32_t input, uint8_t averageCount, int32_t averageState[DELTA_MAX_SAMPLES]) {
|
||||
int count;
|
||||
int32_t averageSum = 0;
|
||||
|
||||
for (count = averageCount-1; count > 0; count--) averageState[count] = averageState[count-1];
|
||||
averageState[0] = input;
|
||||
for (count = 0; count < averageCount; count++) averageSum += averageState[count];
|
||||
|
||||
return averageSum / averageCount;
|
||||
/*
|
||||
* FIR filter
|
||||
*/
|
||||
void firFilterInit2(firFilter_t *filter, float *buf, uint8_t bufLength, const float *coeffs, uint8_t coeffsLength)
|
||||
{
|
||||
filter->buf = buf;
|
||||
filter->bufLength = bufLength;
|
||||
filter->coeffs = coeffs;
|
||||
filter->coeffsLength = coeffsLength;
|
||||
memset(filter->buf, 0, sizeof(float) * filter->bufLength);
|
||||
}
|
||||
|
||||
float filterApplyAveragef(float input, uint8_t averageCount, float averageState[DELTA_MAX_SAMPLES]) {
|
||||
int count;
|
||||
float averageSum = 0.0f;
|
||||
|
||||
for (count = averageCount-1; count > 0; count--) averageState[count] = averageState[count-1];
|
||||
averageState[0] = input;
|
||||
for (count = 0; count < averageCount; count++) averageSum += averageState[count];
|
||||
|
||||
return averageSum / averageCount;
|
||||
/*
|
||||
* FIR filter initialisation
|
||||
* If FIR filter is just used for averaging, coeffs can be set to NULL
|
||||
*/
|
||||
void firFilterInit(firFilter_t *filter, float *buf, uint8_t bufLength, const float *coeffs)
|
||||
{
|
||||
firFilterInit2(filter, buf, bufLength, coeffs, bufLength);
|
||||
}
|
||||
|
||||
void firFilterUpdate(firFilter_t *filter, float input)
|
||||
{
|
||||
memmove(&filter->buf[1], &filter->buf[0], (filter->bufLength-1) * sizeof(input));
|
||||
filter->buf[0] = input;
|
||||
}
|
||||
|
||||
float firFilterApply(const firFilter_t *filter)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
for (int ii = 0; ii < filter->coeffsLength; ++ii) {
|
||||
ret += filter->coeffs[ii] * filter->buf[ii];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float firFilterCalcPartialAverage(const firFilter_t *filter, uint8_t count)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
for (int ii = 0; ii < count; ++ii) {
|
||||
ret += filter->buf[ii];
|
||||
}
|
||||
return ret / count;
|
||||
}
|
||||
|
||||
float firFilterCalcAverage(const firFilter_t *filter)
|
||||
{
|
||||
return firFilterCalcPartialAverage(filter, filter->coeffsLength);
|
||||
}
|
||||
|
||||
float firFilterLastInput(const firFilter_t *filter)
|
||||
{
|
||||
return filter->buf[0];
|
||||
}
|
||||
|
||||
float firFilterGet(const firFilter_t *filter, int index)
|
||||
{
|
||||
return filter->buf[index];
|
||||
}
|
||||
|
||||
/*
|
||||
* int16_t based FIR filter
|
||||
* Can be directly updated from devices that produce 16-bit data, eg gyros and accelerometers
|
||||
*/
|
||||
void firFilterInt16Init2(firFilterInt16_t *filter, int16_t *buf, uint8_t bufLength, const float *coeffs, uint8_t coeffsLength)
|
||||
{
|
||||
filter->buf = buf;
|
||||
filter->bufLength = bufLength;
|
||||
filter->coeffs = coeffs;
|
||||
filter->coeffsLength = coeffsLength;
|
||||
memset(filter->buf, 0, sizeof(int16_t) * filter->bufLength);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIR filter initialisation
|
||||
* If FIR filter is just used for averaging, coeffs can be set to NULL
|
||||
*/
|
||||
void firFilterInt16Init(firFilterInt16_t *filter, int16_t *buf, uint8_t bufLength, const float *coeffs)
|
||||
{
|
||||
firFilterInt16Init2(filter, buf, bufLength, coeffs, bufLength);
|
||||
}
|
||||
|
||||
void firFilterInt16Update(firFilterInt16_t *filter, int16_t input)
|
||||
{
|
||||
memmove(&filter->buf[1], &filter->buf[0], (filter->bufLength-1) * sizeof(input));
|
||||
filter->buf[0] = input;
|
||||
}
|
||||
|
||||
float firFilterInt16Apply(const firFilterInt16_t *filter)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
for (int ii = 0; ii < filter->coeffsLength; ++ii) {
|
||||
ret += filter->coeffs[ii] * filter->buf[ii];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float firFilterInt16CalcPartialAverage(const firFilterInt16_t *filter, uint8_t count)
|
||||
{
|
||||
float ret = 0;
|
||||
for (int ii = 0; ii < count; ++ii) {
|
||||
ret += filter->buf[ii];
|
||||
}
|
||||
return ret / count;
|
||||
}
|
||||
|
||||
float firFilterInt16CalcAverage(const firFilterInt16_t *filter)
|
||||
{
|
||||
return firFilterInt16CalcPartialAverage(filter, filter->coeffsLength);
|
||||
}
|
||||
|
||||
int16_t firFilterInt16LastInput(const firFilterInt16_t *filter)
|
||||
{
|
||||
return filter->buf[0];
|
||||
}
|
||||
|
||||
int16_t firFilterInt16Get(const firFilter_t *filter, int index)
|
||||
{
|
||||
return filter->buf[index];
|
||||
}
|
||||
|
||||
|
|
|
@ -29,14 +29,56 @@ typedef struct biquadFilter_s {
|
|||
float d1, d2;
|
||||
} biquadFilter_t;
|
||||
|
||||
typedef enum {
|
||||
FILTER_PT1 = 0,
|
||||
FILTER_BIQUAD,
|
||||
FILTER_FIR,
|
||||
} filterType_e;
|
||||
|
||||
void biquadFilterInit(biquadFilter_t *filter, float filterCutFreq, uint32_t refreshRate);
|
||||
typedef enum {
|
||||
FILTER_LPF,
|
||||
FILTER_NOTCH
|
||||
} biquadFilterType_e;
|
||||
|
||||
typedef struct firFilter_s {
|
||||
float *buf;
|
||||
const float *coeffs;
|
||||
uint8_t bufLength;
|
||||
uint8_t coeffsLength;
|
||||
} firFilter_t;
|
||||
|
||||
typedef struct firFilterInt16_s {
|
||||
int16_t *buf;
|
||||
const float *coeffs;
|
||||
uint8_t bufLength;
|
||||
uint8_t coeffsLength;
|
||||
} firFilterInt16_t;
|
||||
|
||||
|
||||
void biquadFilterInitLPF(biquadFilter_t *filter, float filterFreq, uint32_t refreshRate);
|
||||
void biquadFilterInit(biquadFilter_t *filter, float filterFreq, uint32_t refreshRate, float Q, biquadFilterType_e filterType);
|
||||
float biquadFilterApply(biquadFilter_t *filter, float input);
|
||||
float filterGetNotchQ(uint16_t centerFreq, uint16_t cutoff);
|
||||
|
||||
void pt1FilterInit(pt1Filter_t *filter, uint8_t f_cut, float dT);
|
||||
float pt1FilterApply(pt1Filter_t *filter, float input);
|
||||
float pt1FilterApply4(pt1Filter_t *filter, float input, uint8_t f_cut, float dT);
|
||||
|
||||
int32_t filterApplyAverage(int32_t input, uint8_t averageCount, int32_t averageState[DELTA_MAX_SAMPLES]);
|
||||
float filterApplyAveragef(float input, uint8_t averageCount, float averageState[DELTA_MAX_SAMPLES]);
|
||||
void firFilterInit(firFilter_t *filter, float *buf, uint8_t bufLength, const float *coeffs);
|
||||
void firFilterInit2(firFilter_t *filter, float *buf, uint8_t bufLength, const float *coeffs, uint8_t coeffsLength);
|
||||
void firFilterUpdate(firFilter_t *filter, float input);
|
||||
float firFilterApply(const firFilter_t *filter);
|
||||
float firFilterCalcPartialAverage(const firFilter_t *filter, uint8_t count);
|
||||
float firFilterCalcAverage(const firFilter_t *filter);
|
||||
float firFilterLastInput(const firFilter_t *filter);
|
||||
float firFilterGet(const firFilter_t *filter, int index);
|
||||
|
||||
void firFilterInt16Init(firFilterInt16_t *filter, int16_t *buf, uint8_t bufLength, const float *coeffs);
|
||||
void firFilterInt16Init2(firFilterInt16_t *filter, int16_t *buf, uint8_t bufLength, const float *coeffs, uint8_t coeffsLength);
|
||||
void firFilterInt16Update(firFilterInt16_t *filter, int16_t input);
|
||||
float firFilterInt16Apply(const firFilterInt16_t *filter);
|
||||
float firFilterInt16CalcPartialAverage(const firFilterInt16_t *filter, uint8_t count);
|
||||
float firFilterInt16CalcAverage(const firFilterInt16_t *filter);
|
||||
int16_t firFilterInt16LastInput(const firFilterInt16_t *filter);
|
||||
int16_t firFilterInt16Get(const firFilter_t *filter, int index);
|
||||
|
||||
|
|
|
@ -99,6 +99,13 @@ float acos_approx(float x)
|
|||
}
|
||||
#endif
|
||||
|
||||
float powerf(float base, int exp) {
|
||||
float result = base;
|
||||
for (int count = 1; count < exp; count++) result *= base;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t applyDeadband(int32_t value, int32_t deadband)
|
||||
{
|
||||
if (ABS(value) < deadband) {
|
||||
|
@ -231,7 +238,7 @@ int32_t quickMedianFilter5(int32_t * v)
|
|||
|
||||
QMF_SORT(p[0], p[1]); QMF_SORT(p[3], p[4]); QMF_SORT(p[0], p[3]);
|
||||
QMF_SORT(p[1], p[4]); QMF_SORT(p[1], p[2]); QMF_SORT(p[2], p[3]);
|
||||
QMF_SORT(p[1], p[2]);
|
||||
QMF_SORT(p[1], p[2]);
|
||||
return p[2];
|
||||
}
|
||||
|
||||
|
@ -279,7 +286,7 @@ float quickMedianFilter5f(float * v)
|
|||
|
||||
QMF_SORTF(p[0], p[1]); QMF_SORTF(p[3], p[4]); QMF_SORTF(p[0], p[3]);
|
||||
QMF_SORTF(p[1], p[4]); QMF_SORTF(p[1], p[2]); QMF_SORTF(p[2], p[3]);
|
||||
QMF_SORTF(p[1], p[2]);
|
||||
QMF_SORTF(p[1], p[2]);
|
||||
return p[2];
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef union {
|
|||
fp_angles_def angles;
|
||||
} fp_angles_t;
|
||||
|
||||
float powerf(float base, int exp);
|
||||
int32_t applyDeadband(int32_t value, int32_t deadband);
|
||||
|
||||
void devClear(stdev_t *dev);
|
||||
|
|
|
@ -36,12 +36,11 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "drivers/serial.h"
|
||||
#include "io/serial.h"
|
||||
|
||||
#include "build_config.h"
|
||||
#include "printf.h"
|
||||
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
|
@ -56,7 +55,7 @@ typedef void (*putcf) (void *, char);
|
|||
static putcf stdout_putf;
|
||||
static void *stdout_putp;
|
||||
|
||||
// print bf, padded from left to at least n characters.
|
||||
// print bf, padded from left to at least n characters.
|
||||
// padding is zero ('0') if z!=0, space (' ') otherwise
|
||||
static int putchw(void *putp, putcf putf, int n, char z, char *bf)
|
||||
{
|
||||
|
|
|
@ -102,13 +102,10 @@ For further details see source code.
|
|||
regs Kusti, 23.10.2004
|
||||
*/
|
||||
|
||||
#ifndef __TFP_PRINTF__
|
||||
#define __TFP_PRINTF__
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "drivers/serial.h"
|
||||
|
||||
void init_printf(void *putp, void (*putf) (void *, char));
|
||||
|
||||
int tfp_printf(const char *fmt, ...);
|
||||
|
@ -119,6 +116,6 @@ int tfp_format(void *putp, void (*putf) (void *, char), const char *fmt, va_list
|
|||
#define printf tfp_printf
|
||||
#define sprintf tfp_sprintf
|
||||
|
||||
void setPrintfSerialPort(serialPort_t *serialPort);
|
||||
|
||||
#endif
|
||||
struct serialPort_s;
|
||||
void setPrintfSerialPort(struct serialPort_s *serialPort);
|
||||
void printfSupportInit(void);
|
||||
|
|
106
src/main/common/streambuf.c
Normal file
106
src/main/common/streambuf.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "streambuf.h"
|
||||
|
||||
void sbufWriteU8(sbuf_t *dst, uint8_t val)
|
||||
{
|
||||
*dst->ptr++ = val;
|
||||
}
|
||||
|
||||
void sbufWriteU16(sbuf_t *dst, uint16_t val)
|
||||
{
|
||||
sbufWriteU8(dst, val >> 0);
|
||||
sbufWriteU8(dst, val >> 8);
|
||||
}
|
||||
|
||||
void sbufWriteU32(sbuf_t *dst, uint32_t val)
|
||||
{
|
||||
sbufWriteU8(dst, val >> 0);
|
||||
sbufWriteU8(dst, val >> 8);
|
||||
sbufWriteU8(dst, val >> 16);
|
||||
sbufWriteU8(dst, val >> 24);
|
||||
}
|
||||
|
||||
void sbufWriteData(sbuf_t *dst, const void *data, int len)
|
||||
{
|
||||
memcpy(dst->ptr, data, len);
|
||||
dst->ptr += len;
|
||||
}
|
||||
|
||||
void sbufWriteString(sbuf_t *dst, const char *string)
|
||||
{
|
||||
sbufWriteData(dst, string, strlen(string));
|
||||
}
|
||||
|
||||
uint8_t sbufReadU8(sbuf_t *src)
|
||||
{
|
||||
return *src->ptr++;
|
||||
}
|
||||
|
||||
uint16_t sbufReadU16(sbuf_t *src)
|
||||
{
|
||||
uint16_t ret;
|
||||
ret = sbufReadU8(src);
|
||||
ret |= sbufReadU8(src) << 8;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t sbufReadU32(sbuf_t *src)
|
||||
{
|
||||
uint32_t ret;
|
||||
ret = sbufReadU8(src);
|
||||
ret |= sbufReadU8(src) << 8;
|
||||
ret |= sbufReadU8(src) << 16;
|
||||
ret |= sbufReadU8(src) << 24;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sbufReadData(sbuf_t *src, void *data, int len)
|
||||
{
|
||||
memcpy(data, src->ptr, len);
|
||||
}
|
||||
|
||||
// reader - return bytes remaining in buffer
|
||||
// writer - return available space
|
||||
int sbufBytesRemaining(sbuf_t *buf)
|
||||
{
|
||||
return buf->end - buf->ptr;
|
||||
}
|
||||
|
||||
uint8_t* sbufPtr(sbuf_t *buf)
|
||||
{
|
||||
return buf->ptr;
|
||||
}
|
||||
|
||||
// advance buffer pointer
|
||||
// reader - skip data
|
||||
// writer - commit written data
|
||||
void sbufAdvance(sbuf_t *buf, int size)
|
||||
{
|
||||
buf->ptr += size;
|
||||
}
|
||||
|
||||
// modifies streambuf so that written data are prepared for reading
|
||||
void sbufSwitchToReader(sbuf_t *buf, uint8_t *base)
|
||||
{
|
||||
buf->end = buf->ptr;
|
||||
buf->ptr = base;
|
||||
}
|
45
src/main/common/streambuf.h
Normal file
45
src/main/common/streambuf.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// simple buffer-based serializer/deserializer without implicit size check
|
||||
// little-endian encoding implemneted now
|
||||
|
||||
typedef struct sbuf_s {
|
||||
uint8_t *ptr; // data pointer must be first (sbuff_t* is equivalent to uint8_t **)
|
||||
uint8_t *end;
|
||||
} sbuf_t;
|
||||
|
||||
void sbufWriteU8(sbuf_t *dst, uint8_t val);
|
||||
void sbufWriteU16(sbuf_t *dst, uint16_t val);
|
||||
void sbufWriteU32(sbuf_t *dst, uint32_t val);
|
||||
void sbufWriteData(sbuf_t *dst, const void *data, int len);
|
||||
void sbufWriteString(sbuf_t *dst, const char *string);
|
||||
|
||||
uint8_t sbufReadU8(sbuf_t *src);
|
||||
uint16_t sbufReadU16(sbuf_t *src);
|
||||
uint32_t sbufReadU32(sbuf_t *src);
|
||||
void sbufReadData(sbuf_t *dst, void *data, int len);
|
||||
|
||||
int sbufBytesRemaining(sbuf_t *buf);
|
||||
uint8_t* sbufPtr(sbuf_t *buf);
|
||||
void sbufAdvance(sbuf_t *buf, int size);
|
||||
|
||||
void sbufSwitchToReader(sbuf_t *buf, uint8_t * base);
|
|
@ -17,7 +17,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
#include "maths.h"
|
||||
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
|
|
|
@ -71,4 +71,15 @@ http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html
|
|||
static inline int16_t cmp16(uint16_t a, uint16_t b) { return a-b; }
|
||||
static inline int32_t cmp32(uint32_t a, uint32_t b) { return a-b; }
|
||||
|
||||
// using memcpy_fn will force memcpy function call, instead of inlining it. In most cases function call takes fewer instructions
|
||||
// than inlined version (inlining is cheaper for very small moves < 8 bytes / 2 store instructions)
|
||||
#ifdef UNIT_TEST
|
||||
// Call memcpy when building unittest - this is easier that asm symbol name mangling (symbols start with _underscore on win32)
|
||||
#include <string.h>
|
||||
static inline void memcpy_fn ( void * destination, const void * source, size_t num ) { memcpy(destination, source, num); };
|
||||
#else
|
||||
void * memcpy_fn ( void * destination, const void * source, size_t num ) asm("memcpy");
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "blackbox/blackbox_io.h"
|
||||
|
||||
|
@ -34,6 +35,7 @@
|
|||
#include "drivers/accgyro.h"
|
||||
#include "drivers/compass.h"
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/io.h"
|
||||
#include "drivers/gpio.h"
|
||||
#include "drivers/timer.h"
|
||||
#include "drivers/pwm_rx.h"
|
||||
|
@ -53,8 +55,8 @@
|
|||
#include "io/serial.h"
|
||||
#include "io/gimbal.h"
|
||||
#include "io/escservo.h"
|
||||
#include "io/rc_controls.h"
|
||||
#include "io/rc_curves.h"
|
||||
#include "fc/rc_controls.h"
|
||||
#include "fc/rc_curves.h"
|
||||
#include "io/ledstrip.h"
|
||||
#include "io/gps.h"
|
||||
#include "io/osd.h"
|
||||
|
@ -71,11 +73,14 @@
|
|||
#include "flight/altitudehold.h"
|
||||
#include "flight/navigation.h"
|
||||
|
||||
#include "config/runtime_config.h"
|
||||
#include "fc/runtime_config.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/config_eeprom.h"
|
||||
|
||||
#include "config/config_profile.h"
|
||||
#include "config/config_master.h"
|
||||
#include "config/feature.h"
|
||||
|
||||
#ifndef DEFAULT_RX_FEATURE
|
||||
#define DEFAULT_RX_FEATURE FEATURE_RX_PARALLEL_PWM
|
||||
|
@ -89,89 +94,18 @@
|
|||
#endif
|
||||
|
||||
void useRcControlsConfig(modeActivationCondition_t *modeActivationConditions, escAndServoConfig_t *escAndServoConfigToUse, pidProfile_t *pidProfileToUse);
|
||||
void targetConfiguration(void);
|
||||
|
||||
#if !defined(FLASH_SIZE)
|
||||
#error "Flash size not defined for target. (specify in KB)"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FLASH_PAGE_SIZE
|
||||
#ifdef STM32F303xC
|
||||
#define FLASH_PAGE_SIZE ((uint16_t)0x800)
|
||||
#endif
|
||||
|
||||
#ifdef STM32F10X_MD
|
||||
#define FLASH_PAGE_SIZE ((uint16_t)0x400)
|
||||
#endif
|
||||
|
||||
#ifdef STM32F10X_HD
|
||||
#define FLASH_PAGE_SIZE ((uint16_t)0x800)
|
||||
#endif
|
||||
|
||||
#if defined(STM32F40_41xxx)
|
||||
#define FLASH_PAGE_SIZE ((uint32_t)0x20000)
|
||||
#endif
|
||||
|
||||
#if defined (STM32F411xE)
|
||||
#define FLASH_PAGE_SIZE ((uint32_t)0x20000)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(FLASH_SIZE) && !defined(FLASH_PAGE_COUNT)
|
||||
#ifdef STM32F10X_MD
|
||||
#define FLASH_PAGE_COUNT 128
|
||||
#endif
|
||||
|
||||
#ifdef STM32F10X_HD
|
||||
#define FLASH_PAGE_COUNT 128
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FLASH_SIZE)
|
||||
#if defined(STM32F40_41xxx)
|
||||
#define FLASH_PAGE_COUNT 4 // just to make calculations work
|
||||
#elif defined (STM32F411xE)
|
||||
#define FLASH_PAGE_COUNT 4 // just to make calculations work
|
||||
#else
|
||||
#define FLASH_PAGE_COUNT ((FLASH_SIZE * 0x400) / FLASH_PAGE_SIZE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(FLASH_PAGE_SIZE)
|
||||
#error "Flash page size not defined for target."
|
||||
#endif
|
||||
|
||||
#if !defined(FLASH_PAGE_COUNT)
|
||||
#error "Flash page count not defined for target."
|
||||
#endif
|
||||
|
||||
#if FLASH_SIZE <= 128
|
||||
#define FLASH_TO_RESERVE_FOR_CONFIG 0x800
|
||||
#else
|
||||
#define FLASH_TO_RESERVE_FOR_CONFIG 0x1000
|
||||
#endif
|
||||
|
||||
// use the last flash pages for storage
|
||||
#ifdef CUSTOM_FLASH_MEMORY_ADDRESS
|
||||
size_t custom_flash_memory_address = 0;
|
||||
#define CONFIG_START_FLASH_ADDRESS (custom_flash_memory_address)
|
||||
#else
|
||||
// use the last flash pages for storage
|
||||
#ifndef CONFIG_START_FLASH_ADDRESS
|
||||
#define CONFIG_START_FLASH_ADDRESS (0x08000000 + (uint32_t)((FLASH_PAGE_SIZE * FLASH_PAGE_COUNT) - FLASH_TO_RESERVE_FOR_CONFIG))
|
||||
#endif
|
||||
#endif
|
||||
void targetConfiguration(master_t *config);
|
||||
|
||||
master_t masterConfig; // master config struct with data independent from profiles
|
||||
profile_t *currentProfile;
|
||||
static uint32_t activeFeaturesLatch = 0;
|
||||
|
||||
static uint8_t currentControlRateProfileIndex = 0;
|
||||
controlRateConfig_t *currentControlRateProfile;
|
||||
|
||||
static const uint8_t EEPROM_CONF_VERSION = 141;
|
||||
|
||||
void intFeatureClearAll(master_t *config);
|
||||
void intFeatureSet(uint32_t mask, master_t *config);
|
||||
void intFeatureClear(uint32_t mask, master_t *config);
|
||||
|
||||
static void resetAccelerometerTrims(flightDynamicsTrims_t *accelerometerTrims)
|
||||
{
|
||||
|
@ -180,22 +114,37 @@ static void resetAccelerometerTrims(flightDynamicsTrims_t *accelerometerTrims)
|
|||
accelerometerTrims->values.yaw = 0;
|
||||
}
|
||||
|
||||
void resetPidProfile(pidProfile_t *pidProfile)
|
||||
static void resetControlRateConfig(controlRateConfig_t *controlRateConfig)
|
||||
{
|
||||
controlRateConfig->rcRate8 = 100;
|
||||
controlRateConfig->rcYawRate8 = 100;
|
||||
controlRateConfig->rcExpo8 = 0;
|
||||
controlRateConfig->thrMid8 = 50;
|
||||
controlRateConfig->thrExpo8 = 0;
|
||||
controlRateConfig->dynThrPID = 10;
|
||||
controlRateConfig->rcYawExpo8 = 0;
|
||||
controlRateConfig->tpa_breakpoint = 1650;
|
||||
|
||||
#if (defined(STM32F10X))
|
||||
pidProfile->pidController = PID_CONTROLLER_INTEGER;
|
||||
for (uint8_t axis = 0; axis < FLIGHT_DYNAMICS_INDEX_COUNT; axis++) {
|
||||
controlRateConfig->rates[axis] = 70;
|
||||
}
|
||||
}
|
||||
|
||||
static void resetPidProfile(pidProfile_t *pidProfile)
|
||||
{
|
||||
#if defined(SKIP_PID_FLOAT)
|
||||
pidProfile->pidController = PID_CONTROLLER_LEGACY;
|
||||
#else
|
||||
pidProfile->pidController = PID_CONTROLLER_FLOAT;
|
||||
pidProfile->pidController = PID_CONTROLLER_BETAFLIGHT;
|
||||
#endif
|
||||
|
||||
pidProfile->P8[ROLL] = 45;
|
||||
pidProfile->I8[ROLL] = 40;
|
||||
pidProfile->D8[ROLL] = 18;
|
||||
pidProfile->P8[PITCH] = 50;
|
||||
pidProfile->I8[PITCH] = 40;
|
||||
pidProfile->D8[PITCH] = 18;
|
||||
pidProfile->P8[YAW] = 80;
|
||||
pidProfile->D8[ROLL] = 20;
|
||||
pidProfile->P8[PITCH] = 60;
|
||||
pidProfile->I8[PITCH] = 65;
|
||||
pidProfile->D8[PITCH] = 22;
|
||||
pidProfile->P8[YAW] = 70;
|
||||
pidProfile->I8[YAW] = 45;
|
||||
pidProfile->D8[YAW] = 20;
|
||||
pidProfile->P8[PIDALT] = 50;
|
||||
|
@ -219,12 +168,23 @@ void resetPidProfile(pidProfile_t *pidProfile)
|
|||
pidProfile->D8[PIDVEL] = 75;
|
||||
|
||||
pidProfile->yaw_p_limit = YAW_P_LIMIT_MAX;
|
||||
pidProfile->yaw_lpf_hz = 80;
|
||||
pidProfile->rollPitchItermIgnoreRate = 180;
|
||||
pidProfile->yawItermIgnoreRate = 35;
|
||||
pidProfile->yaw_lpf_hz = 0;
|
||||
pidProfile->rollPitchItermIgnoreRate = 130;
|
||||
pidProfile->yawItermIgnoreRate = 32;
|
||||
pidProfile->dterm_filter_type = FILTER_BIQUAD;
|
||||
pidProfile->dterm_lpf_hz = 100; // filtering ON by default
|
||||
pidProfile->dterm_notch_hz = 260;
|
||||
pidProfile->dterm_notch_cutoff = 160;
|
||||
pidProfile->deltaMethod = DELTA_FROM_MEASUREMENT;
|
||||
pidProfile->dynamic_pid = 1;
|
||||
pidProfile->vbatPidCompensation = 0;
|
||||
pidProfile->pidAtMinThrottle = PID_STABILISATION_ON;
|
||||
|
||||
// Betaflight PID controller parameters
|
||||
pidProfile->ptermSRateWeight = 85;
|
||||
pidProfile->dtermSetpointWeight = 150;
|
||||
pidProfile->yawRateAccelLimit = 220;
|
||||
pidProfile->rateAccelLimit = 0;
|
||||
pidProfile->itermThrottleGain = 0;
|
||||
|
||||
#ifdef GTUNE
|
||||
pidProfile->gtune_lolimP[ROLL] = 10; // [0..200] Lower limit of ROLL P during G tune.
|
||||
|
@ -239,6 +199,17 @@ void resetPidProfile(pidProfile_t *pidProfile)
|
|||
#endif
|
||||
}
|
||||
|
||||
void resetProfile(profile_t *profile)
|
||||
{
|
||||
resetPidProfile(&profile->pidProfile);
|
||||
|
||||
for (int rI = 0; rI<MAX_RATEPROFILES; rI++) {
|
||||
resetControlRateConfig(&profile->controlRateProfile[rI]);
|
||||
}
|
||||
|
||||
profile->activeRateProfile = 0;
|
||||
}
|
||||
|
||||
#ifdef GPS
|
||||
void resetGpsProfile(gpsProfile_t *gpsProfile)
|
||||
{
|
||||
|
@ -252,6 +223,7 @@ void resetGpsProfile(gpsProfile_t *gpsProfile)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef BARO
|
||||
void resetBarometerConfig(barometerConfig_t *barometerConfig)
|
||||
{
|
||||
barometerConfig->baro_sample_count = 21;
|
||||
|
@ -259,6 +231,7 @@ void resetBarometerConfig(barometerConfig_t *barometerConfig)
|
|||
barometerConfig->baro_cf_vel = 0.985f;
|
||||
barometerConfig->baro_cf_alt = 0.965f;
|
||||
}
|
||||
#endif
|
||||
|
||||
void resetSensorAlignment(sensorAlignmentConfig_t *sensorAlignmentConfig)
|
||||
{
|
||||
|
@ -271,14 +244,13 @@ void resetEscAndServoConfig(escAndServoConfig_t *escAndServoConfig)
|
|||
{
|
||||
#ifdef BRUSHED_MOTORS
|
||||
escAndServoConfig->minthrottle = 1000;
|
||||
escAndServoConfig->maxthrottle = 2000;
|
||||
#else
|
||||
escAndServoConfig->minthrottle = 1150;
|
||||
escAndServoConfig->maxthrottle = 1850;
|
||||
escAndServoConfig->minthrottle = 1070;
|
||||
#endif
|
||||
escAndServoConfig->maxthrottle = 2000;
|
||||
escAndServoConfig->mincommand = 1000;
|
||||
escAndServoConfig->servoCenterPulse = 1500;
|
||||
escAndServoConfig->escDesyncProtection = 0;
|
||||
escAndServoConfig->maxEscThrottleJumpMs = 0;
|
||||
}
|
||||
|
||||
void resetFlight3DConfig(flight3DConfig_t *flight3DConfig)
|
||||
|
@ -289,9 +261,10 @@ void resetFlight3DConfig(flight3DConfig_t *flight3DConfig)
|
|||
flight3DConfig->deadband3d_throttle = 50;
|
||||
}
|
||||
|
||||
#ifdef TELEMETRY
|
||||
void resetTelemetryConfig(telemetryConfig_t *telemetryConfig)
|
||||
{
|
||||
telemetryConfig->telemetry_inversion = 0;
|
||||
telemetryConfig->telemetry_inversion = 1;
|
||||
telemetryConfig->telemetry_switch = 0;
|
||||
telemetryConfig->gpsNoFixLatitude = 0;
|
||||
telemetryConfig->gpsNoFixLongitude = 0;
|
||||
|
@ -300,7 +273,9 @@ void resetTelemetryConfig(telemetryConfig_t *telemetryConfig)
|
|||
telemetryConfig->frsky_vfas_precision = 0;
|
||||
telemetryConfig->frsky_vfas_cell_voltage = 0;
|
||||
telemetryConfig->hottAlarmSoundInterval = 5;
|
||||
telemetryConfig->pidValuesAsTelemetry = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void resetBatteryConfig(batteryConfig_t *batteryConfig)
|
||||
{
|
||||
|
@ -311,11 +286,11 @@ void resetBatteryConfig(batteryConfig_t *batteryConfig)
|
|||
batteryConfig->vbatmincellvoltage = 33;
|
||||
batteryConfig->vbatwarningcellvoltage = 35;
|
||||
batteryConfig->vbathysteresis = 1;
|
||||
batteryConfig->vbatPidCompensation = 0;
|
||||
batteryConfig->currentMeterOffset = 0;
|
||||
batteryConfig->currentMeterScale = 400; // for Allegro ACS758LCB-100U (40mV/A)
|
||||
batteryConfig->batteryCapacity = 0;
|
||||
batteryConfig->currentMeterType = CURRENT_SENSOR_ADC;
|
||||
batteryConfig->batterynotpresentlevel = 55; // VBAT below 5.5 V will be igonored
|
||||
}
|
||||
|
||||
#ifdef SWAP_SERIAL_PORT_0_AND_1_DEFAULTS
|
||||
|
@ -333,7 +308,7 @@ void resetSerialConfig(serialConfig_t *serialConfig)
|
|||
|
||||
for (index = 0; index < SERIAL_PORT_COUNT; index++) {
|
||||
serialConfig->portConfigs[index].identifier = serialPortIdentifiers[index];
|
||||
serialConfig->portConfigs[index].msp_baudrateIndex = BAUD_115200;
|
||||
serialConfig->portConfigs[index].msp_baudrateIndex = BAUD_500000;
|
||||
serialConfig->portConfigs[index].gps_baudrateIndex = BAUD_57600;
|
||||
serialConfig->portConfigs[index].telemetry_baudrateIndex = BAUD_AUTO;
|
||||
serialConfig->portConfigs[index].blackbox_baudrateIndex = BAUD_115200;
|
||||
|
@ -349,24 +324,7 @@ void resetSerialConfig(serialConfig_t *serialConfig)
|
|||
serialConfig->reboot_character = 'R';
|
||||
}
|
||||
|
||||
static void resetControlRateConfig(controlRateConfig_t *controlRateConfig)
|
||||
{
|
||||
controlRateConfig->rcRate8 = 100;
|
||||
controlRateConfig->rcYawRate8 = 100;
|
||||
controlRateConfig->rcExpo8 = 10;
|
||||
controlRateConfig->thrMid8 = 50;
|
||||
controlRateConfig->thrExpo8 = 0;
|
||||
controlRateConfig->dynThrPID = 20;
|
||||
controlRateConfig->rcYawExpo8 = 10;
|
||||
controlRateConfig->tpa_breakpoint = 1650;
|
||||
|
||||
for (uint8_t axis = 0; axis < FLIGHT_DYNAMICS_INDEX_COUNT; axis++) {
|
||||
controlRateConfig->rates[axis] = 70;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void resetRcControlsConfig(rcControlsConfig_t *rcControlsConfig)
|
||||
void resetRcControlsConfig(rcControlsConfig_t *rcControlsConfig)
|
||||
{
|
||||
rcControlsConfig->deadband = 0;
|
||||
rcControlsConfig->yaw_deadband = 0;
|
||||
|
@ -374,7 +332,7 @@ void resetRcControlsConfig(rcControlsConfig_t *rcControlsConfig)
|
|||
rcControlsConfig->alt_hold_fast_change = 1;
|
||||
}
|
||||
|
||||
void resetMixerConfig(mixerConfig_t *mixerConfig)
|
||||
void resetMixerConfig(mixerConfig_t *mixerConfig)
|
||||
{
|
||||
mixerConfig->yaw_motor_direction = 1;
|
||||
#ifdef USE_SERVOS
|
||||
|
@ -389,7 +347,7 @@ uint8_t getCurrentProfile(void)
|
|||
return masterConfig.current_profile_index;
|
||||
}
|
||||
|
||||
static void setProfile(uint8_t profileIndex)
|
||||
void setProfile(uint8_t profileIndex)
|
||||
{
|
||||
currentProfile = &masterConfig.profile[profileIndex];
|
||||
currentControlRateProfileIndex = currentProfile->activeRateProfile;
|
||||
|
@ -419,281 +377,269 @@ uint16_t getCurrentMinthrottle(void)
|
|||
}
|
||||
|
||||
// Default settings
|
||||
static void resetConf(void)
|
||||
void createDefaultConfig(master_t *config)
|
||||
{
|
||||
// Clear all configuration
|
||||
memset(&masterConfig, 0, sizeof(master_t));
|
||||
setProfile(0);
|
||||
memset(config, 0, sizeof(master_t));
|
||||
|
||||
featureClearAll();
|
||||
featureSet(DEFAULT_RX_FEATURE | FEATURE_FAILSAFE | FEATURE_SUPEREXPO_RATES);
|
||||
intFeatureClearAll(config);
|
||||
intFeatureSet(DEFAULT_RX_FEATURE | FEATURE_FAILSAFE , config);
|
||||
#ifdef DEFAULT_FEATURES
|
||||
featureSet(DEFAULT_FEATURES);
|
||||
intFeatureSet(DEFAULT_FEATURES, config);
|
||||
#endif
|
||||
|
||||
#ifdef OSD
|
||||
resetOsdConfig();
|
||||
intFeatureSet(FEATURE_OSD, config);
|
||||
resetOsdConfig(&config->osdProfile);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HAS_VOLTAGE_DIVIDER
|
||||
// only enable the VBAT feature by default if the board has a voltage divider otherwise
|
||||
// the user may see incorrect readings and unexpected issues with pin mappings may occur.
|
||||
featureSet(FEATURE_VBAT);
|
||||
intFeatureSet(FEATURE_VBAT, config);
|
||||
#endif
|
||||
|
||||
masterConfig.version = EEPROM_CONF_VERSION;
|
||||
masterConfig.mixerMode = MIXER_QUADX;
|
||||
config->version = EEPROM_CONF_VERSION;
|
||||
config->mixerMode = MIXER_QUADX;
|
||||
|
||||
// global settings
|
||||
masterConfig.current_profile_index = 0; // default profile
|
||||
masterConfig.dcm_kp = 2500; // 1.0 * 10000
|
||||
masterConfig.dcm_ki = 0; // 0.003 * 10000
|
||||
masterConfig.gyro_lpf = 0; // 256HZ default
|
||||
config->current_profile_index = 0; // default profile
|
||||
config->dcm_kp = 2500; // 1.0 * 10000
|
||||
config->dcm_ki = 0; // 0.003 * 10000
|
||||
config->gyro_lpf = 0; // 256HZ default
|
||||
#ifdef STM32F10X
|
||||
masterConfig.gyro_sync_denom = 8;
|
||||
config->gyro_sync_denom = 8;
|
||||
config->pid_process_denom = 1;
|
||||
#elif defined(USE_GYRO_SPI_MPU6000) || defined(USE_GYRO_SPI_MPU6500)
|
||||
config->gyro_sync_denom = 1;
|
||||
config->pid_process_denom = 4;
|
||||
#else
|
||||
masterConfig.gyro_sync_denom = 4;
|
||||
config->gyro_sync_denom = 4;
|
||||
config->pid_process_denom = 2;
|
||||
#endif
|
||||
masterConfig.gyro_soft_lpf_hz = 100;
|
||||
config->gyro_soft_type = FILTER_PT1;
|
||||
config->gyro_soft_lpf_hz = 90;
|
||||
config->gyro_soft_notch_hz = 0;
|
||||
config->gyro_soft_notch_cutoff = 130;
|
||||
|
||||
masterConfig.pid_process_denom = 2;
|
||||
config->debug_mode = DEBUG_NONE;
|
||||
|
||||
masterConfig.debug_mode = 0;
|
||||
resetAccelerometerTrims(&config->accZero);
|
||||
|
||||
resetAccelerometerTrims(&masterConfig.accZero);
|
||||
resetSensorAlignment(&config->sensorAlignmentConfig);
|
||||
|
||||
resetSensorAlignment(&masterConfig.sensorAlignmentConfig);
|
||||
|
||||
masterConfig.boardAlignment.rollDegrees = 0;
|
||||
masterConfig.boardAlignment.pitchDegrees = 0;
|
||||
masterConfig.boardAlignment.yawDegrees = 0;
|
||||
masterConfig.acc_hardware = ACC_DEFAULT; // default/autodetect
|
||||
masterConfig.max_angle_inclination = 700; // 70 degrees
|
||||
masterConfig.yaw_control_direction = 1;
|
||||
masterConfig.gyroConfig.gyroMovementCalibrationThreshold = 32;
|
||||
config->boardAlignment.rollDegrees = 0;
|
||||
config->boardAlignment.pitchDegrees = 0;
|
||||
config->boardAlignment.yawDegrees = 0;
|
||||
config->acc_hardware = ACC_DEFAULT; // default/autodetect
|
||||
config->max_angle_inclination = 700; // 70 degrees
|
||||
config->yaw_control_direction = 1;
|
||||
config->gyroConfig.gyroMovementCalibrationThreshold = 32;
|
||||
|
||||
// xxx_hardware: 0:default/autodetect, 1: disable
|
||||
masterConfig.mag_hardware = 0;
|
||||
config->mag_hardware = 1;
|
||||
|
||||
masterConfig.baro_hardware = 0;
|
||||
config->baro_hardware = 1;
|
||||
|
||||
resetBatteryConfig(&masterConfig.batteryConfig);
|
||||
resetBatteryConfig(&config->batteryConfig);
|
||||
|
||||
resetTelemetryConfig(&masterConfig.telemetryConfig);
|
||||
#ifdef TELEMETRY
|
||||
resetTelemetryConfig(&config->telemetryConfig);
|
||||
#endif
|
||||
|
||||
#ifdef SERIALRX_PROVIDER
|
||||
masterConfig.rxConfig.serialrx_provider = SERIALRX_PROVIDER;
|
||||
config->rxConfig.serialrx_provider = SERIALRX_PROVIDER;
|
||||
#else
|
||||
masterConfig.rxConfig.serialrx_provider = 0;
|
||||
config->rxConfig.serialrx_provider = 0;
|
||||
#endif
|
||||
masterConfig.rxConfig.sbus_inversion = 1;
|
||||
masterConfig.rxConfig.spektrum_sat_bind = 0;
|
||||
masterConfig.rxConfig.spektrum_sat_bind_autoreset = 1;
|
||||
masterConfig.rxConfig.midrc = 1500;
|
||||
masterConfig.rxConfig.mincheck = 1100;
|
||||
masterConfig.rxConfig.maxcheck = 1900;
|
||||
masterConfig.rxConfig.rx_min_usec = 885; // any of first 4 channels below this value will trigger rx loss detection
|
||||
masterConfig.rxConfig.rx_max_usec = 2115; // any of first 4 channels above this value will trigger rx loss detection
|
||||
config->rxConfig.sbus_inversion = 1;
|
||||
config->rxConfig.spektrum_sat_bind = 0;
|
||||
config->rxConfig.spektrum_sat_bind_autoreset = 1;
|
||||
config->rxConfig.midrc = 1500;
|
||||
config->rxConfig.mincheck = 1100;
|
||||
config->rxConfig.maxcheck = 1900;
|
||||
config->rxConfig.rx_min_usec = 885; // any of first 4 channels below this value will trigger rx loss detection
|
||||
config->rxConfig.rx_max_usec = 2115; // any of first 4 channels above this value will trigger rx loss detection
|
||||
|
||||
for (int i = 0; i < MAX_SUPPORTED_RC_CHANNEL_COUNT; i++) {
|
||||
rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &masterConfig.rxConfig.failsafe_channel_configurations[i];
|
||||
rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &config->rxConfig.failsafe_channel_configurations[i];
|
||||
channelFailsafeConfiguration->mode = (i < NON_AUX_CHANNEL_COUNT) ? RX_FAILSAFE_MODE_AUTO : RX_FAILSAFE_MODE_HOLD;
|
||||
channelFailsafeConfiguration->step = (i == THROTTLE) ? CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.rx_min_usec) : CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.midrc);
|
||||
channelFailsafeConfiguration->step = (i == THROTTLE) ? CHANNEL_VALUE_TO_RXFAIL_STEP(config->rxConfig.rx_min_usec) : CHANNEL_VALUE_TO_RXFAIL_STEP(config->rxConfig.midrc);
|
||||
}
|
||||
|
||||
masterConfig.rxConfig.rssi_channel = 0;
|
||||
masterConfig.rxConfig.rssi_scale = RSSI_SCALE_DEFAULT;
|
||||
masterConfig.rxConfig.rssi_ppm_invert = 0;
|
||||
masterConfig.rxConfig.rcSmoothInterval = 0; // 0 is predefined
|
||||
masterConfig.rxConfig.fpvCamAngleDegrees = 0;
|
||||
#ifdef STM32F4
|
||||
masterConfig.rxConfig.max_aux_channel = 99;
|
||||
#else
|
||||
masterConfig.rxConfig.max_aux_channel = 6;
|
||||
#endif
|
||||
masterConfig.rxConfig.airModeActivateThreshold = 1350;
|
||||
config->rxConfig.rssi_channel = 0;
|
||||
config->rxConfig.rssi_scale = RSSI_SCALE_DEFAULT;
|
||||
config->rxConfig.rssi_ppm_invert = 0;
|
||||
config->rxConfig.rcInterpolation = RC_SMOOTHING_AUTO;
|
||||
config->rxConfig.rcInterpolationInterval = 19;
|
||||
config->rxConfig.fpvCamAngleDegrees = 0;
|
||||
config->rxConfig.max_aux_channel = MAX_AUX_CHANNELS;
|
||||
config->rxConfig.airModeActivateThreshold = 1350;
|
||||
|
||||
resetAllRxChannelRangeConfigurations(masterConfig.rxConfig.channelRanges);
|
||||
resetAllRxChannelRangeConfigurations(config->rxConfig.channelRanges);
|
||||
|
||||
masterConfig.inputFilteringMode = INPUT_FILTERING_DISABLED;
|
||||
config->inputFilteringMode = INPUT_FILTERING_DISABLED;
|
||||
|
||||
masterConfig.gyro_cal_on_first_arm = 0; // TODO - Cleanup retarded arm support
|
||||
masterConfig.disarm_kill_switch = 1;
|
||||
masterConfig.auto_disarm_delay = 5;
|
||||
masterConfig.small_angle = 25;
|
||||
config->gyro_cal_on_first_arm = 0; // TODO - Cleanup retarded arm support
|
||||
config->disarm_kill_switch = 1;
|
||||
config->auto_disarm_delay = 5;
|
||||
config->small_angle = 25;
|
||||
|
||||
resetMixerConfig(&masterConfig.mixerConfig);
|
||||
resetMixerConfig(&config->mixerConfig);
|
||||
|
||||
masterConfig.airplaneConfig.fixedwing_althold_dir = 1;
|
||||
config->airplaneConfig.fixedwing_althold_dir = 1;
|
||||
|
||||
// Motor/ESC/Servo
|
||||
resetEscAndServoConfig(&masterConfig.escAndServoConfig);
|
||||
resetFlight3DConfig(&masterConfig.flight3DConfig);
|
||||
resetEscAndServoConfig(&config->escAndServoConfig);
|
||||
resetFlight3DConfig(&config->flight3DConfig);
|
||||
|
||||
#ifdef BRUSHED_MOTORS
|
||||
masterConfig.motor_pwm_rate = BRUSHED_MOTORS_PWM_RATE;
|
||||
masterConfig.motor_pwm_protocol = PWM_TYPE_BRUSHED;
|
||||
config->motor_pwm_rate = BRUSHED_MOTORS_PWM_RATE;
|
||||
config->motor_pwm_protocol = PWM_TYPE_BRUSHED;
|
||||
config->use_unsyncedPwm = true;
|
||||
#else
|
||||
masterConfig.motor_pwm_rate = BRUSHLESS_MOTORS_PWM_RATE;
|
||||
masterConfig.motor_pwm_protocol = PWM_TYPE_ONESHOT125;
|
||||
config->motor_pwm_rate = BRUSHLESS_MOTORS_PWM_RATE;
|
||||
config->motor_pwm_protocol = PWM_TYPE_ONESHOT125;
|
||||
#endif
|
||||
masterConfig.servo_pwm_rate = 50;
|
||||
|
||||
config->servo_pwm_rate = 50;
|
||||
|
||||
#ifdef CC3D
|
||||
masterConfig.use_buzzer_p6 = 0;
|
||||
config->use_buzzer_p6 = 0;
|
||||
#endif
|
||||
|
||||
#ifdef GPS
|
||||
// gps/nav stuff
|
||||
masterConfig.gpsConfig.provider = GPS_NMEA;
|
||||
masterConfig.gpsConfig.sbasMode = SBAS_AUTO;
|
||||
masterConfig.gpsConfig.autoConfig = GPS_AUTOCONFIG_ON;
|
||||
masterConfig.gpsConfig.autoBaud = GPS_AUTOBAUD_OFF;
|
||||
config->gpsConfig.provider = GPS_NMEA;
|
||||
config->gpsConfig.sbasMode = SBAS_AUTO;
|
||||
config->gpsConfig.autoConfig = GPS_AUTOCONFIG_ON;
|
||||
config->gpsConfig.autoBaud = GPS_AUTOBAUD_OFF;
|
||||
#endif
|
||||
|
||||
resetSerialConfig(&masterConfig.serialConfig);
|
||||
resetSerialConfig(&config->serialConfig);
|
||||
|
||||
masterConfig.emf_avoidance = 0; // TODO - needs removal
|
||||
resetProfile(&config->profile[0]);
|
||||
|
||||
resetPidProfile(¤tProfile->pidProfile);
|
||||
resetRollAndPitchTrims(&config->accelerometerTrims);
|
||||
|
||||
for (int rI = 0; rI<MAX_RATEPROFILES; rI++) {
|
||||
resetControlRateConfig(&masterConfig.profile[0].controlRateProfile[rI]);
|
||||
}
|
||||
resetRollAndPitchTrims(&masterConfig.accelerometerTrims);
|
||||
config->mag_declination = 0;
|
||||
config->acc_lpf_hz = 10.0f;
|
||||
config->accDeadband.xy = 40;
|
||||
config->accDeadband.z = 40;
|
||||
config->acc_unarmedcal = 1;
|
||||
|
||||
masterConfig.mag_declination = 0;
|
||||
masterConfig.acc_lpf_hz = 10.0f;
|
||||
masterConfig.accDeadband.xy = 40;
|
||||
masterConfig.accDeadband.z = 40;
|
||||
masterConfig.acc_unarmedcal = 1;
|
||||
|
||||
resetBarometerConfig(&masterConfig.barometerConfig);
|
||||
#ifdef BARO
|
||||
resetBarometerConfig(&config->barometerConfig);
|
||||
#endif
|
||||
|
||||
// Radio
|
||||
parseRcChannels("AETR1234", &masterConfig.rxConfig);
|
||||
#ifdef RX_CHANNELS_TAER
|
||||
parseRcChannels("TAER1234", &config->rxConfig);
|
||||
#else
|
||||
parseRcChannels("AETR1234", &config->rxConfig);
|
||||
#endif
|
||||
|
||||
resetRcControlsConfig(&masterConfig.rcControlsConfig);
|
||||
resetRcControlsConfig(&config->rcControlsConfig);
|
||||
|
||||
masterConfig.throttle_correction_value = 0; // could 10 with althold or 40 for fpv
|
||||
masterConfig.throttle_correction_angle = 800; // could be 80.0 deg with atlhold or 45.0 for fpv
|
||||
config->throttle_correction_value = 0; // could 10 with althold or 40 for fpv
|
||||
config->throttle_correction_angle = 800; // could be 80.0 deg with atlhold or 45.0 for fpv
|
||||
|
||||
// Failsafe Variables
|
||||
masterConfig.failsafeConfig.failsafe_delay = 10; // 1sec
|
||||
masterConfig.failsafeConfig.failsafe_off_delay = 10; // 1sec
|
||||
masterConfig.failsafeConfig.failsafe_throttle = 1000; // default throttle off.
|
||||
masterConfig.failsafeConfig.failsafe_kill_switch = 0; // default failsafe switch action is identical to rc link loss
|
||||
masterConfig.failsafeConfig.failsafe_throttle_low_delay = 100; // default throttle low delay for "just disarm" on failsafe condition
|
||||
masterConfig.failsafeConfig.failsafe_procedure = 0; // default full failsafe procedure is 0: auto-landing
|
||||
config->failsafeConfig.failsafe_delay = 10; // 1sec
|
||||
config->failsafeConfig.failsafe_off_delay = 10; // 1sec
|
||||
config->failsafeConfig.failsafe_throttle = 1000; // default throttle off.
|
||||
config->failsafeConfig.failsafe_kill_switch = 0; // default failsafe switch action is identical to rc link loss
|
||||
config->failsafeConfig.failsafe_throttle_low_delay = 100; // default throttle low delay for "just disarm" on failsafe condition
|
||||
config->failsafeConfig.failsafe_procedure = FAILSAFE_PROCEDURE_DROP_IT;// default full failsafe procedure is 0: auto-landing
|
||||
|
||||
#ifdef USE_SERVOS
|
||||
// servos
|
||||
for (int i = 0; i < MAX_SUPPORTED_SERVOS; i++) {
|
||||
masterConfig.servoConf[i].min = DEFAULT_SERVO_MIN;
|
||||
masterConfig.servoConf[i].max = DEFAULT_SERVO_MAX;
|
||||
masterConfig.servoConf[i].middle = DEFAULT_SERVO_MIDDLE;
|
||||
masterConfig.servoConf[i].rate = 100;
|
||||
masterConfig.servoConf[i].angleAtMin = DEFAULT_SERVO_MIN_ANGLE;
|
||||
masterConfig.servoConf[i].angleAtMax = DEFAULT_SERVO_MAX_ANGLE;
|
||||
masterConfig.servoConf[i].forwardFromChannel = CHANNEL_FORWARDING_DISABLED;
|
||||
config->servoConf[i].min = DEFAULT_SERVO_MIN;
|
||||
config->servoConf[i].max = DEFAULT_SERVO_MAX;
|
||||
config->servoConf[i].middle = DEFAULT_SERVO_MIDDLE;
|
||||
config->servoConf[i].rate = 100;
|
||||
config->servoConf[i].angleAtMin = DEFAULT_SERVO_MIN_ANGLE;
|
||||
config->servoConf[i].angleAtMax = DEFAULT_SERVO_MAX_ANGLE;
|
||||
config->servoConf[i].forwardFromChannel = CHANNEL_FORWARDING_DISABLED;
|
||||
}
|
||||
|
||||
// gimbal
|
||||
masterConfig.gimbalConfig.mode = GIMBAL_MODE_NORMAL;
|
||||
config->gimbalConfig.mode = GIMBAL_MODE_NORMAL;
|
||||
#endif
|
||||
|
||||
#ifdef GPS
|
||||
resetGpsProfile(&masterConfig.gpsProfile);
|
||||
resetGpsProfile(&config->gpsProfile);
|
||||
#endif
|
||||
|
||||
// custom mixer. clear by defaults.
|
||||
for (int i = 0; i < MAX_SUPPORTED_MOTORS; i++) {
|
||||
masterConfig.customMotorMixer[i].throttle = 0.0f;
|
||||
config->customMotorMixer[i].throttle = 0.0f;
|
||||
}
|
||||
|
||||
#ifdef LED_STRIP
|
||||
applyDefaultColors(masterConfig.colors, CONFIGURABLE_COLOR_COUNT);
|
||||
applyDefaultLedStripConfig(masterConfig.ledConfigs);
|
||||
masterConfig.ledstrip_visual_beeper = 0;
|
||||
applyDefaultColors(config->colors);
|
||||
applyDefaultLedStripConfig(config->ledConfigs);
|
||||
applyDefaultModeColors(config->modeColors);
|
||||
applyDefaultSpecialColors(&(config->specialColors));
|
||||
config->ledstrip_visual_beeper = 0;
|
||||
#endif
|
||||
|
||||
#ifdef VTX
|
||||
masterConfig.vtx_band = 4; //Fatshark/Airwaves
|
||||
masterConfig.vtx_channel = 1; //CH1
|
||||
masterConfig.vtx_mode = 0; //CH+BAND mode
|
||||
masterConfig.vtx_mhz = 5740; //F0
|
||||
config->vtx_band = 4; //Fatshark/Airwaves
|
||||
config->vtx_channel = 1; //CH1
|
||||
config->vtx_mode = 0; //CH+BAND mode
|
||||
config->vtx_mhz = 5740; //F0
|
||||
#endif
|
||||
|
||||
#ifdef TRANSPONDER
|
||||
static const uint8_t defaultTransponderData[6] = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }; // Note, this is NOT a valid transponder code, it's just for testing production hardware
|
||||
|
||||
memcpy(masterConfig.transponderData, &defaultTransponderData, sizeof(defaultTransponderData));
|
||||
memcpy(config->transponderData, &defaultTransponderData, sizeof(defaultTransponderData));
|
||||
#endif
|
||||
|
||||
#ifdef BLACKBOX
|
||||
|
||||
#if defined(ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT)
|
||||
featureSet(FEATURE_BLACKBOX);
|
||||
masterConfig.blackbox_device = BLACKBOX_DEVICE_FLASH;
|
||||
intFeatureSet(FEATURE_BLACKBOX, config);
|
||||
config->blackbox_device = BLACKBOX_DEVICE_FLASH;
|
||||
#elif defined(ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT)
|
||||
featureSet(FEATURE_BLACKBOX);
|
||||
masterConfig.blackbox_device = BLACKBOX_DEVICE_SDCARD;
|
||||
intFeatureSet(FEATURE_BLACKBOX, config);
|
||||
config->blackbox_device = BLACKBOX_DEVICE_SDCARD;
|
||||
#else
|
||||
masterConfig.blackbox_device = BLACKBOX_DEVICE_SERIAL;
|
||||
config->blackbox_device = BLACKBOX_DEVICE_SERIAL;
|
||||
#endif
|
||||
|
||||
masterConfig.blackbox_rate_num = 1;
|
||||
masterConfig.blackbox_rate_denom = 1;
|
||||
|
||||
config->blackbox_rate_num = 1;
|
||||
config->blackbox_rate_denom = 1;
|
||||
config->blackbox_on_motor_test = 0; // default off
|
||||
#endif // BLACKBOX
|
||||
|
||||
#ifdef SERIALRX_UART
|
||||
if (featureConfigured(FEATURE_RX_SERIAL)) {
|
||||
masterConfig.serialConfig.portConfigs[SERIALRX_UART].functionMask = FUNCTION_RX_SERIAL;
|
||||
config->serialConfig.portConfigs[SERIALRX_UART].functionMask = FUNCTION_RX_SERIAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_CONFIG)
|
||||
targetConfiguration();
|
||||
targetConfiguration(config);
|
||||
#endif
|
||||
|
||||
|
||||
// copy first profile into remaining profile
|
||||
for (int i = 1; i < MAX_PROFILE_COUNT; i++) {
|
||||
memcpy(&masterConfig.profile[i], currentProfile, sizeof(profile_t));
|
||||
memcpy(&config->profile[i], &config->profile[0], sizeof(profile_t));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static uint8_t calculateChecksum(const uint8_t *data, uint32_t length)
|
||||
static void resetConf(void)
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
const uint8_t *byteOffset;
|
||||
createDefaultConfig(&masterConfig);
|
||||
|
||||
for (byteOffset = data; byteOffset < (data + length); byteOffset++)
|
||||
checksum ^= *byteOffset;
|
||||
return checksum;
|
||||
}
|
||||
setProfile(0);
|
||||
|
||||
static bool isEEPROMContentValid(void)
|
||||
{
|
||||
const master_t *temp = (const master_t *) CONFIG_START_FLASH_ADDRESS;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
// check version number
|
||||
if (EEPROM_CONF_VERSION != temp->version)
|
||||
return false;
|
||||
|
||||
// check size and magic numbers
|
||||
if (temp->size != sizeof(master_t) || temp->magic_be != 0xBE || temp->magic_ef != 0xEF)
|
||||
return false;
|
||||
|
||||
// verify integrity of temporary copy
|
||||
checksum = calculateChecksum((const uint8_t *) temp, sizeof(master_t));
|
||||
if (checksum != 0)
|
||||
return false;
|
||||
|
||||
// looks good, let's roll!
|
||||
return true;
|
||||
#ifdef LED_STRIP
|
||||
reevaluateLedConfig();
|
||||
#endif
|
||||
}
|
||||
|
||||
void activateControlRateConfig(void)
|
||||
|
@ -715,7 +661,7 @@ void activateConfig(void)
|
|||
¤tProfile->pidProfile
|
||||
);
|
||||
|
||||
gyroUseConfig(&masterConfig.gyroConfig, masterConfig.gyro_soft_lpf_hz);
|
||||
gyroUseConfig(&masterConfig.gyroConfig, masterConfig.gyro_soft_lpf_hz, masterConfig.gyro_soft_notch_hz, masterConfig.gyro_soft_notch_cutoff, masterConfig.gyro_soft_type);
|
||||
|
||||
#ifdef TELEMETRY
|
||||
telemetryUseConfig(&masterConfig.telemetryConfig);
|
||||
|
@ -732,10 +678,6 @@ void activateConfig(void)
|
|||
setAccelerationFilter(masterConfig.acc_lpf_hz);
|
||||
|
||||
mixerUseConfigs(
|
||||
#ifdef USE_SERVOS
|
||||
masterConfig.servoConf,
|
||||
&masterConfig.gimbalConfig,
|
||||
#endif
|
||||
&masterConfig.flight3DConfig,
|
||||
&masterConfig.escAndServoConfig,
|
||||
&masterConfig.mixerConfig,
|
||||
|
@ -743,6 +685,10 @@ void activateConfig(void)
|
|||
&masterConfig.rxConfig
|
||||
);
|
||||
|
||||
#ifdef USE_SERVOS
|
||||
servoUseConfigs(masterConfig.servoConf, &masterConfig.gimbalConfig);
|
||||
#endif
|
||||
|
||||
imuRuntimeConfig.dcm_kp = masterConfig.dcm_kp / 10000.0f;
|
||||
imuRuntimeConfig.dcm_ki = masterConfig.dcm_ki / 10000.0f;
|
||||
imuRuntimeConfig.acc_unarmedcal = masterConfig.acc_unarmedcal;
|
||||
|
@ -841,12 +787,6 @@ void validateAndFixConfig(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef STM32F303xC
|
||||
// hardware supports serial port inversion, make users life easier for those that want to connect SBus RX's
|
||||
masterConfig.telemetryConfig.telemetry_inversion = 1;
|
||||
#endif
|
||||
|
||||
|
||||
/*#if defined(LED_STRIP) && defined(TRANSPONDER) // TODO - Add transponder feature
|
||||
if ((WS2811_DMA_TC_FLAG == TRANSPONDER_DMA_TC_FLAG) && featureConfigured(FEATURE_TRANSPONDER) && featureConfigured(FEATURE_LED_STRIP)) {
|
||||
featureClear(FEATURE_LED_STRIP);
|
||||
|
@ -881,32 +821,6 @@ void validateAndFixConfig(void)
|
|||
}
|
||||
}
|
||||
|
||||
void initEEPROM(void)
|
||||
{
|
||||
}
|
||||
|
||||
void readEEPROM(void)
|
||||
{
|
||||
// Sanity check
|
||||
if (!isEEPROMContentValid())
|
||||
failureMode(FAILURE_INVALID_EEPROM_CONTENTS);
|
||||
|
||||
suspendRxSignal();
|
||||
|
||||
// Read flash
|
||||
memcpy(&masterConfig, (char *) CONFIG_START_FLASH_ADDRESS, sizeof(master_t));
|
||||
|
||||
if (masterConfig.current_profile_index > MAX_PROFILE_COUNT - 1) // sanity check
|
||||
masterConfig.current_profile_index = 0;
|
||||
|
||||
setProfile(masterConfig.current_profile_index);
|
||||
|
||||
validateAndFixConfig();
|
||||
activateConfig();
|
||||
|
||||
resumeRxSignal();
|
||||
}
|
||||
|
||||
void readEEPROMAndNotify(void)
|
||||
{
|
||||
// re-read written data
|
||||
|
@ -914,69 +828,6 @@ void readEEPROMAndNotify(void)
|
|||
beeperConfirmationBeeps(1);
|
||||
}
|
||||
|
||||
void writeEEPROM(void)
|
||||
{
|
||||
// Generate compile time error if the config does not fit in the reserved area of flash.
|
||||
BUILD_BUG_ON(sizeof(master_t) > FLASH_TO_RESERVE_FOR_CONFIG);
|
||||
|
||||
FLASH_Status status = 0;
|
||||
uint32_t wordOffset;
|
||||
int8_t attemptsRemaining = 3;
|
||||
|
||||
suspendRxSignal();
|
||||
|
||||
// prepare checksum/version constants
|
||||
masterConfig.version = EEPROM_CONF_VERSION;
|
||||
masterConfig.size = sizeof(master_t);
|
||||
masterConfig.magic_be = 0xBE;
|
||||
masterConfig.magic_ef = 0xEF;
|
||||
masterConfig.chk = 0; // erase checksum before recalculating
|
||||
masterConfig.chk = calculateChecksum((const uint8_t *) &masterConfig, sizeof(master_t));
|
||||
|
||||
// write it
|
||||
FLASH_Unlock();
|
||||
while (attemptsRemaining--) {
|
||||
#if defined(STM32F4)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
||||
#elif defined(STM32F303)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
|
||||
#elif defined(STM32F10X)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
|
||||
#endif
|
||||
for (wordOffset = 0; wordOffset < sizeof(master_t); wordOffset += 4) {
|
||||
if (wordOffset % FLASH_PAGE_SIZE == 0) {
|
||||
#if defined(STM32F40_41xxx)
|
||||
status = FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); //0x08080000 to 0x080A0000
|
||||
#elif defined (STM32F411xE)
|
||||
status = FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3); //0x08060000 to 0x08080000
|
||||
#else
|
||||
status = FLASH_ErasePage(CONFIG_START_FLASH_ADDRESS + wordOffset);
|
||||
#endif
|
||||
if (status != FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status = FLASH_ProgramWord(CONFIG_START_FLASH_ADDRESS + wordOffset,
|
||||
*(uint32_t *) ((char *) &masterConfig + wordOffset));
|
||||
if (status != FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
FLASH_Lock();
|
||||
|
||||
// Flash write failed - just die now
|
||||
if (status != FLASH_COMPLETE || !isEEPROMContentValid()) {
|
||||
failureMode(FAILURE_FLASH_WRITE_FAILED);
|
||||
}
|
||||
|
||||
resumeRxSignal();
|
||||
}
|
||||
|
||||
void ensureEEPROMContainsValidData(void)
|
||||
{
|
||||
if (isEEPROMContentValid()) {
|
||||
|
@ -1015,41 +866,6 @@ void changeControlRateProfile(uint8_t profileIndex)
|
|||
activateControlRateConfig();
|
||||
}
|
||||
|
||||
void latchActiveFeatures()
|
||||
{
|
||||
activeFeaturesLatch = masterConfig.enabledFeatures;
|
||||
}
|
||||
|
||||
bool featureConfigured(uint32_t mask)
|
||||
{
|
||||
return masterConfig.enabledFeatures & mask;
|
||||
}
|
||||
|
||||
bool feature(uint32_t mask)
|
||||
{
|
||||
return activeFeaturesLatch & mask;
|
||||
}
|
||||
|
||||
void featureSet(uint32_t mask)
|
||||
{
|
||||
masterConfig.enabledFeatures |= mask;
|
||||
}
|
||||
|
||||
void featureClear(uint32_t mask)
|
||||
{
|
||||
masterConfig.enabledFeatures &= ~(mask);
|
||||
}
|
||||
|
||||
void featureClearAll()
|
||||
{
|
||||
masterConfig.enabledFeatures = 0;
|
||||
}
|
||||
|
||||
uint32_t featureMask(void)
|
||||
{
|
||||
return masterConfig.enabledFeatures;
|
||||
}
|
||||
|
||||
void beeperOffSet(uint32_t mask)
|
||||
{
|
||||
masterConfig.beeper_off_flags |= mask;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define MAX_PROFILE_COUNT 3
|
||||
#endif
|
||||
#define MAX_RATEPROFILES 3
|
||||
#define ONESHOT_FEATURE_CHANGED_DELAY_ON_BOOT_MS 1500
|
||||
#define MAX_NAME_LENGTH 16
|
||||
|
||||
typedef enum {
|
||||
FEATURE_RX_PPM = 1 << 0,
|
||||
|
@ -44,23 +44,17 @@ typedef enum {
|
|||
FEATURE_RSSI_ADC = 1 << 15,
|
||||
FEATURE_LED_STRIP = 1 << 16,
|
||||
FEATURE_DISPLAY = 1 << 17,
|
||||
FEATURE_ONESHOT125 = 1 << 18,
|
||||
FEATURE_OSD = 1 << 18,
|
||||
FEATURE_BLACKBOX = 1 << 19,
|
||||
FEATURE_CHANNEL_FORWARDING = 1 << 20,
|
||||
FEATURE_TRANSPONDER = 1 << 21,
|
||||
FEATURE_AIRMODE = 1 << 22,
|
||||
FEATURE_SUPEREXPO_RATES = 1 << 23,
|
||||
FEATURE_OSD = 1 << 24,
|
||||
FEATURE_VTX = 1 << 25,
|
||||
//FEATURE_SUPEREXPO_RATES = 1 << 23,
|
||||
FEATURE_VTX = 1 << 24,
|
||||
FEATURE_RX_NRF24 = 1 << 25,
|
||||
FEATURE_SOFTSPI = 1 << 26,
|
||||
} features_e;
|
||||
|
||||
void latchActiveFeatures(void);
|
||||
bool featureConfigured(uint32_t mask);
|
||||
bool feature(uint32_t mask);
|
||||
void featureSet(uint32_t mask);
|
||||
void featureClear(uint32_t mask);
|
||||
void featureClearAll(void);
|
||||
uint32_t featureMask(void);
|
||||
void beeperOffSet(uint32_t mask);
|
||||
void beeperOffSetAll(uint8_t beeperCount);
|
||||
void beeperOffClear(uint32_t mask);
|
||||
|
@ -72,16 +66,17 @@ void setPreferredBeeperOffMask(uint32_t mask);
|
|||
|
||||
void copyCurrentProfileToProfileSlot(uint8_t profileSlotIndex);
|
||||
|
||||
void initEEPROM(void);
|
||||
void resetEEPROM(void);
|
||||
void readEEPROM(void);
|
||||
void readEEPROMAndNotify(void);
|
||||
void writeEEPROM();
|
||||
void ensureEEPROMContainsValidData(void);
|
||||
|
||||
void saveConfigAndNotify(void);
|
||||
void validateAndFixConfig(void);
|
||||
void activateConfig(void);
|
||||
|
||||
uint8_t getCurrentProfile(void);
|
||||
void changeProfile(uint8_t profileIndex);
|
||||
void setProfile(uint8_t profileIndex);
|
||||
|
||||
uint8_t getCurrentControlRateProfile(void);
|
||||
void changeControlRateProfile(uint8_t profileIndex);
|
||||
|
|
266
src/main/config/config_eeprom.c
Normal file
266
src/main/config/config_eeprom.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "common/color.h"
|
||||
#include "common/axis.h"
|
||||
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/accgyro.h"
|
||||
#include "drivers/compass.h"
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/timer.h"
|
||||
#include "drivers/pwm_rx.h"
|
||||
#include "drivers/serial.h"
|
||||
|
||||
#include "sensors/sensors.h"
|
||||
#include "sensors/gyro.h"
|
||||
#include "sensors/compass.h"
|
||||
#include "sensors/acceleration.h"
|
||||
#include "sensors/barometer.h"
|
||||
#include "sensors/boardalignment.h"
|
||||
#include "sensors/battery.h"
|
||||
|
||||
#include "io/beeper.h"
|
||||
#include "io/serial.h"
|
||||
#include "io/gimbal.h"
|
||||
#include "io/escservo.h"
|
||||
#include "fc/rc_controls.h"
|
||||
#include "fc/rc_curves.h"
|
||||
#include "io/ledstrip.h"
|
||||
#include "io/gps.h"
|
||||
#include "io/osd.h"
|
||||
#include "io/vtx.h"
|
||||
|
||||
#include "rx/rx.h"
|
||||
|
||||
#include "telemetry/telemetry.h"
|
||||
|
||||
#include "flight/mixer.h"
|
||||
#include "flight/pid.h"
|
||||
#include "flight/imu.h"
|
||||
#include "flight/failsafe.h"
|
||||
#include "flight/altitudehold.h"
|
||||
#include "flight/navigation.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/config_eeprom.h"
|
||||
#include "config/config_profile.h"
|
||||
#include "config/config_master.h"
|
||||
|
||||
#if !defined(FLASH_SIZE)
|
||||
#error "Flash size not defined for target. (specify in KB)"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FLASH_PAGE_SIZE
|
||||
#ifdef STM32F303xC
|
||||
#define FLASH_PAGE_SIZE ((uint16_t)0x800)
|
||||
#endif
|
||||
|
||||
#ifdef STM32F10X_MD
|
||||
#define FLASH_PAGE_SIZE ((uint16_t)0x400)
|
||||
#endif
|
||||
|
||||
#ifdef STM32F10X_HD
|
||||
#define FLASH_PAGE_SIZE ((uint16_t)0x800)
|
||||
#endif
|
||||
|
||||
#if defined(STM32F40_41xxx)
|
||||
#define FLASH_PAGE_SIZE ((uint32_t)0x20000)
|
||||
#endif
|
||||
|
||||
#if defined (STM32F411xE)
|
||||
#define FLASH_PAGE_SIZE ((uint32_t)0x20000)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(FLASH_SIZE) && !defined(FLASH_PAGE_COUNT)
|
||||
#ifdef STM32F10X_MD
|
||||
#define FLASH_PAGE_COUNT 128
|
||||
#endif
|
||||
|
||||
#ifdef STM32F10X_HD
|
||||
#define FLASH_PAGE_COUNT 128
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FLASH_SIZE)
|
||||
#if defined(STM32F40_41xxx)
|
||||
#define FLASH_PAGE_COUNT 4 // just to make calculations work
|
||||
#elif defined (STM32F411xE)
|
||||
#define FLASH_PAGE_COUNT 4 // just to make calculations work
|
||||
#else
|
||||
#define FLASH_PAGE_COUNT ((FLASH_SIZE * 0x400) / FLASH_PAGE_SIZE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(FLASH_PAGE_SIZE)
|
||||
#error "Flash page size not defined for target."
|
||||
#endif
|
||||
|
||||
#if !defined(FLASH_PAGE_COUNT)
|
||||
#error "Flash page count not defined for target."
|
||||
#endif
|
||||
|
||||
#if FLASH_SIZE <= 128
|
||||
#define FLASH_TO_RESERVE_FOR_CONFIG 0x800
|
||||
#else
|
||||
#define FLASH_TO_RESERVE_FOR_CONFIG 0x1000
|
||||
#endif
|
||||
|
||||
// use the last flash pages for storage
|
||||
#ifdef CUSTOM_FLASH_MEMORY_ADDRESS
|
||||
size_t custom_flash_memory_address = 0;
|
||||
#define CONFIG_START_FLASH_ADDRESS (custom_flash_memory_address)
|
||||
#else
|
||||
// use the last flash pages for storage
|
||||
#ifndef CONFIG_START_FLASH_ADDRESS
|
||||
#define CONFIG_START_FLASH_ADDRESS (0x08000000 + (uint32_t)((FLASH_PAGE_SIZE * FLASH_PAGE_COUNT) - FLASH_TO_RESERVE_FOR_CONFIG))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
void initEEPROM(void)
|
||||
{
|
||||
}
|
||||
|
||||
static uint8_t calculateChecksum(const uint8_t *data, uint32_t length)
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
const uint8_t *byteOffset;
|
||||
|
||||
for (byteOffset = data; byteOffset < (data + length); byteOffset++)
|
||||
checksum ^= *byteOffset;
|
||||
return checksum;
|
||||
}
|
||||
|
||||
bool isEEPROMContentValid(void)
|
||||
{
|
||||
const master_t *temp = (const master_t *) CONFIG_START_FLASH_ADDRESS;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
// check version number
|
||||
if (EEPROM_CONF_VERSION != temp->version)
|
||||
return false;
|
||||
|
||||
// check size and magic numbers
|
||||
if (temp->size != sizeof(master_t) || temp->magic_be != 0xBE || temp->magic_ef != 0xEF)
|
||||
return false;
|
||||
|
||||
// verify integrity of temporary copy
|
||||
checksum = calculateChecksum((const uint8_t *) temp, sizeof(master_t));
|
||||
if (checksum != 0)
|
||||
return false;
|
||||
|
||||
// looks good, let's roll!
|
||||
return true;
|
||||
}
|
||||
|
||||
void writeEEPROM(void)
|
||||
{
|
||||
// Generate compile time error if the config does not fit in the reserved area of flash.
|
||||
BUILD_BUG_ON(sizeof(master_t) > FLASH_TO_RESERVE_FOR_CONFIG);
|
||||
|
||||
FLASH_Status status = 0;
|
||||
uint32_t wordOffset;
|
||||
int8_t attemptsRemaining = 3;
|
||||
|
||||
suspendRxSignal();
|
||||
|
||||
// prepare checksum/version constants
|
||||
masterConfig.version = EEPROM_CONF_VERSION;
|
||||
masterConfig.size = sizeof(master_t);
|
||||
masterConfig.magic_be = 0xBE;
|
||||
masterConfig.magic_ef = 0xEF;
|
||||
masterConfig.chk = 0; // erase checksum before recalculating
|
||||
masterConfig.chk = calculateChecksum((const uint8_t *) &masterConfig, sizeof(master_t));
|
||||
|
||||
// write it
|
||||
FLASH_Unlock();
|
||||
while (attemptsRemaining--) {
|
||||
#if defined(STM32F4)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
||||
#elif defined(STM32F303)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
|
||||
#elif defined(STM32F10X)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
|
||||
#endif
|
||||
for (wordOffset = 0; wordOffset < sizeof(master_t); wordOffset += 4) {
|
||||
if (wordOffset % FLASH_PAGE_SIZE == 0) {
|
||||
#if defined(STM32F40_41xxx)
|
||||
status = FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); //0x08080000 to 0x080A0000
|
||||
#elif defined (STM32F411xE)
|
||||
status = FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3); //0x08060000 to 0x08080000
|
||||
#else
|
||||
status = FLASH_ErasePage(CONFIG_START_FLASH_ADDRESS + wordOffset);
|
||||
#endif
|
||||
if (status != FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status = FLASH_ProgramWord(CONFIG_START_FLASH_ADDRESS + wordOffset,
|
||||
*(uint32_t *) ((char *) &masterConfig + wordOffset));
|
||||
if (status != FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
FLASH_Lock();
|
||||
|
||||
// Flash write failed - just die now
|
||||
if (status != FLASH_COMPLETE || !isEEPROMContentValid()) {
|
||||
failureMode(FAILURE_FLASH_WRITE_FAILED);
|
||||
}
|
||||
|
||||
resumeRxSignal();
|
||||
}
|
||||
|
||||
void readEEPROM(void)
|
||||
{
|
||||
// Sanity check
|
||||
if (!isEEPROMContentValid())
|
||||
failureMode(FAILURE_INVALID_EEPROM_CONTENTS);
|
||||
|
||||
suspendRxSignal();
|
||||
|
||||
// Read flash
|
||||
memcpy(&masterConfig, (char *) CONFIG_START_FLASH_ADDRESS, sizeof(master_t));
|
||||
|
||||
if (masterConfig.current_profile_index > MAX_PROFILE_COUNT - 1) // sanity check
|
||||
masterConfig.current_profile_index = 0;
|
||||
|
||||
setProfile(masterConfig.current_profile_index);
|
||||
|
||||
validateAndFixConfig();
|
||||
activateConfig();
|
||||
|
||||
resumeRxSignal();
|
||||
}
|
||||
|
26
src/main/config/config_eeprom.h
Normal file
26
src/main/config/config_eeprom.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define EEPROM_CONF_VERSION 143
|
||||
|
||||
void initEEPROM(void);
|
||||
void writeEEPROM();
|
||||
void readEEPROM(void);
|
||||
bool isEEPROMContentValid(void);
|
||||
|
|
@ -25,7 +25,6 @@ typedef struct master_t {
|
|||
|
||||
uint8_t mixerMode;
|
||||
uint32_t enabledFeatures;
|
||||
uint8_t emf_avoidance; // change pll settings to avoid noise in the uhf band
|
||||
|
||||
// motor/esc/servo related stuff
|
||||
motorMixer_t customMotorMixer[MAX_SUPPORTED_MOTORS];
|
||||
|
@ -56,9 +55,12 @@ typedef struct master_t {
|
|||
int8_t yaw_control_direction; // change control direction of yaw (inverted, normal)
|
||||
uint8_t acc_hardware; // Which acc hardware to use on boards with more than one device
|
||||
uint8_t acc_for_fast_looptime; // shorten acc processing time by using 1 out of 9 samples. For combination with fast looptimes.
|
||||
uint16_t gyro_lpf; // gyro LPF setting - values are driver specific, in case of invalid number, a reasonable default ~30-40HZ is chosen.
|
||||
uint16_t gyro_lpf; // gyro LPF setting - values are driver specific, in case of invalid number, a reasonable default ~30-40HZ is chosen.
|
||||
uint8_t gyro_sync_denom; // Gyro sample divider
|
||||
uint8_t gyro_soft_lpf_hz; // Biqyad gyro lpf hz
|
||||
uint8_t gyro_soft_type; // Gyro Filter Type
|
||||
uint8_t gyro_soft_lpf_hz; // Biquad gyro lpf hz
|
||||
uint16_t gyro_soft_notch_hz; // Biquad gyro notch hz
|
||||
uint16_t gyro_soft_notch_cutoff; // Biquad gyro notch low cutoff
|
||||
uint16_t dcm_kp; // DCM filter proportional gain ( x 10000)
|
||||
uint16_t dcm_ki; // DCM filter integral gain ( x 10000)
|
||||
|
||||
|
@ -75,7 +77,7 @@ typedef struct master_t {
|
|||
|
||||
rollAndPitchTrims_t accelerometerTrims; // accelerometer trim
|
||||
|
||||
float acc_lpf_hz; // cutoff frequency for the low pass filter used on the acc z-axis for althold in Hz
|
||||
uint16_t acc_lpf_hz; // cutoff frequency for the low pass filter used on the acc z-axis for althold in Hz
|
||||
accDeadband_t accDeadband;
|
||||
barometerConfig_t barometerConfig;
|
||||
uint8_t acc_unarmedcal; // turn automatic acc compensation on/off
|
||||
|
@ -117,8 +119,10 @@ typedef struct master_t {
|
|||
telemetryConfig_t telemetryConfig;
|
||||
|
||||
#ifdef LED_STRIP
|
||||
ledConfig_t ledConfigs[MAX_LED_STRIP_LENGTH];
|
||||
hsvColor_t colors[CONFIGURABLE_COLOR_COUNT];
|
||||
ledConfig_t ledConfigs[LED_MAX_STRIP_LENGTH];
|
||||
hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT];
|
||||
modeColorIndexes_t modeColors[LED_MODE_COUNT];
|
||||
specialColorIndexes_t specialColors;
|
||||
uint8_t ledstrip_visual_beeper; // suppress LEDLOW mode if beeper is on
|
||||
#endif
|
||||
|
||||
|
@ -137,7 +141,7 @@ typedef struct master_t {
|
|||
|
||||
profile_t profile[MAX_PROFILE_COUNT];
|
||||
uint8_t current_profile_index;
|
||||
|
||||
|
||||
modeActivationCondition_t modeActivationConditions[MAX_MODE_ACTIVATION_CONDITION_COUNT];
|
||||
adjustmentRange_t adjustmentRanges[MAX_ADJUSTMENT_RANGE_COUNT];
|
||||
|
||||
|
@ -154,6 +158,7 @@ typedef struct master_t {
|
|||
uint8_t blackbox_rate_num;
|
||||
uint8_t blackbox_rate_denom;
|
||||
uint8_t blackbox_device;
|
||||
uint8_t blackbox_on_motor_test;
|
||||
#endif
|
||||
|
||||
uint32_t beeper_off_flags;
|
||||
|
@ -161,8 +166,13 @@ typedef struct master_t {
|
|||
|
||||
uint8_t magic_ef; // magic number, should be 0xEF
|
||||
uint8_t chk; // XOR checksum
|
||||
|
||||
char name[MAX_NAME_LENGTH+1];
|
||||
|
||||
} master_t;
|
||||
|
||||
extern master_t masterConfig;
|
||||
extern profile_t *currentProfile;
|
||||
extern controlRateConfig_t *currentControlRateProfile;
|
||||
|
||||
void createDefaultConfig(master_t *config);
|
||||
|
|
124
src/main/config/feature.c
Normal file
124
src/main/config/feature.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "common/color.h"
|
||||
#include "common/axis.h"
|
||||
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/accgyro.h"
|
||||
#include "drivers/compass.h"
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/timer.h"
|
||||
#include "drivers/pwm_rx.h"
|
||||
#include "drivers/serial.h"
|
||||
|
||||
#include "sensors/sensors.h"
|
||||
#include "sensors/gyro.h"
|
||||
#include "sensors/compass.h"
|
||||
#include "sensors/acceleration.h"
|
||||
#include "sensors/barometer.h"
|
||||
#include "sensors/boardalignment.h"
|
||||
#include "sensors/battery.h"
|
||||
|
||||
#include "io/beeper.h"
|
||||
#include "io/serial.h"
|
||||
#include "io/gimbal.h"
|
||||
#include "io/escservo.h"
|
||||
#include "fc/rc_controls.h"
|
||||
#include "fc/rc_curves.h"
|
||||
#include "io/ledstrip.h"
|
||||
#include "io/gps.h"
|
||||
#include "io/osd.h"
|
||||
#include "io/vtx.h"
|
||||
|
||||
#include "rx/rx.h"
|
||||
|
||||
#include "telemetry/telemetry.h"
|
||||
|
||||
#include "flight/mixer.h"
|
||||
#include "flight/pid.h"
|
||||
#include "flight/imu.h"
|
||||
#include "flight/failsafe.h"
|
||||
#include "flight/altitudehold.h"
|
||||
#include "flight/navigation.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/config_profile.h"
|
||||
#include "config/config_master.h"
|
||||
#include "config/feature.h"
|
||||
|
||||
static uint32_t activeFeaturesLatch = 0;
|
||||
|
||||
void intFeatureSet(uint32_t mask, master_t *config)
|
||||
{
|
||||
config->enabledFeatures |= mask;
|
||||
}
|
||||
|
||||
void intFeatureClear(uint32_t mask, master_t *config)
|
||||
{
|
||||
config->enabledFeatures &= ~(mask);
|
||||
}
|
||||
|
||||
void intFeatureClearAll(master_t *config)
|
||||
{
|
||||
config->enabledFeatures = 0;
|
||||
}
|
||||
|
||||
void latchActiveFeatures()
|
||||
{
|
||||
activeFeaturesLatch = masterConfig.enabledFeatures;
|
||||
}
|
||||
|
||||
bool featureConfigured(uint32_t mask)
|
||||
{
|
||||
return masterConfig.enabledFeatures & mask;
|
||||
}
|
||||
|
||||
bool feature(uint32_t mask)
|
||||
{
|
||||
return activeFeaturesLatch & mask;
|
||||
}
|
||||
|
||||
void featureSet(uint32_t mask)
|
||||
{
|
||||
intFeatureSet(mask, &masterConfig);
|
||||
}
|
||||
|
||||
void featureClear(uint32_t mask)
|
||||
{
|
||||
intFeatureClear(mask, &masterConfig);
|
||||
}
|
||||
|
||||
void featureClearAll()
|
||||
{
|
||||
intFeatureClearAll(&masterConfig);
|
||||
}
|
||||
|
||||
uint32_t featureMask(void)
|
||||
{
|
||||
return masterConfig.enabledFeatures;
|
||||
}
|
||||
|
||||
|
26
src/main/config/feature.h
Normal file
26
src/main/config/feature.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void latchActiveFeatures(void);
|
||||
bool featureConfigured(uint32_t mask);
|
||||
bool feature(uint32_t mask);
|
||||
void featureSet(uint32_t mask);
|
||||
void featureClear(uint32_t mask);
|
||||
void featureClearAll(void);
|
||||
uint32_t featureMask(void);
|
|
@ -19,8 +19,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
#include "debug.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef USE_ACC_LSM303DLHC
|
||||
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
#include "common/axis.h"
|
||||
|
@ -167,4 +170,4 @@ bool lsm303dlhcAccDetect(acc_t *acc)
|
|||
acc->read = lsm303dlhcAccRead;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "platform.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "bus_i2c.h"
|
||||
|
||||
#include "sensor.h"
|
||||
|
|
|
@ -21,15 +21,16 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
|
||||
#include "nvic.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "exti.h"
|
||||
#include "bus_i2c.h"
|
||||
|
||||
|
@ -252,7 +253,7 @@ void mpuIntExtiInit(void)
|
|||
EXTIEnable(mpuIntIO, true);
|
||||
#endif
|
||||
|
||||
mpuExtiInitDone = true;
|
||||
mpuExtiInitDone = true;
|
||||
}
|
||||
|
||||
static bool mpuReadRegisterI2C(uint8_t reg, uint8_t length, uint8_t* data)
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "io_types.h"
|
||||
#include "exti.h"
|
||||
|
||||
|
||||
// MPU6050
|
||||
#define MPU_RA_WHO_AM_I 0x75
|
||||
#define MPU_RA_WHO_AM_I_LEGACY 0x00
|
||||
|
@ -119,7 +120,7 @@
|
|||
|
||||
typedef bool (*mpuReadRegisterFunc)(uint8_t reg, uint8_t length, uint8_t* data);
|
||||
typedef bool (*mpuWriteRegisterFunc)(uint8_t reg, uint8_t data);
|
||||
typedef void(*mpuResetFuncPtr)(void);
|
||||
typedef void(*mpuResetFuncPtr)(void);
|
||||
|
||||
typedef struct mpuConfiguration_s {
|
||||
uint8_t gyroReadXRegister; // Y and Z must registers follow this, 2 words each
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
|
||||
|
@ -104,7 +105,7 @@ static void mpu6050GyroInit(uint8_t lpf)
|
|||
delay(100);
|
||||
ack = mpuConfiguration.write(MPU_RA_PWR_MGMT_1, 0x03); //PWR_MGMT_1 -- SLEEP 0; CYCLE 0; TEMP_DIS 0; CLKSEL 3 (PLL with Z Gyro reference)
|
||||
ack = mpuConfiguration.write(MPU_RA_SMPLRT_DIV, gyroMPU6xxxGetDividerDrops()); //SMPLRT_DIV -- SMPLRT_DIV = 0 Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)
|
||||
delay(15); //PLL Settling time when changing CLKSEL is max 10ms. Use 15ms to be sure
|
||||
delay(15); //PLL Settling time when changing CLKSEL is max 10ms. Use 15ms to be sure
|
||||
ack = mpuConfiguration.write(MPU_RA_CONFIG, lpf); //CONFIG -- EXT_SYNC_SET 0 (disable input pin for data sync) ; default DLPF_CFG = 0 => ACC bandwidth = 260Hz GYRO bandwidth = 256Hz)
|
||||
ack = mpuConfiguration.write(MPU_RA_GYRO_CONFIG, INV_FSR_2000DPS << 3); //GYRO_CONFIG -- FS_SEL = 3: Full scale set to 2000 deg/sec
|
||||
|
||||
|
|
|
@ -18,4 +18,4 @@
|
|||
#pragma once
|
||||
|
||||
bool mpu6050AccDetect(acc_t *acc);
|
||||
bool mpu6050GyroDetect(gyro_t *gyro);
|
||||
bool mpu6050GyroDetect(gyro_t *gyro);
|
||||
|
|
|
@ -73,21 +73,6 @@ void mpu6500GyroInit(uint8_t lpf)
|
|||
{
|
||||
mpuIntExtiInit();
|
||||
|
||||
#ifdef NAZE
|
||||
// FIXME target specific code in driver code.
|
||||
|
||||
gpio_config_t gpio;
|
||||
// MPU_INT output on rev5 hardware (PC13). rev4 was on PB13, conflicts with SPI devices
|
||||
if (hse_value == 12000000) {
|
||||
gpio.pin = Pin_13;
|
||||
gpio.speed = Speed_2MHz;
|
||||
gpio.mode = Mode_IN_FLOATING;
|
||||
gpioInit(GPIOC, &gpio);
|
||||
}
|
||||
#endif
|
||||
|
||||
mpuIntExtiInit();
|
||||
|
||||
mpuConfiguration.write(MPU_RA_PWR_MGMT_1, MPU6500_BIT_RESET);
|
||||
delay(100);
|
||||
mpuConfiguration.write(MPU_RA_SIGNAL_PATH_RESET, 0x07);
|
||||
|
@ -107,11 +92,14 @@ void mpu6500GyroInit(uint8_t lpf)
|
|||
|
||||
// Data ready interrupt configuration
|
||||
#ifdef USE_MPU9250_MAG
|
||||
mpuConfiguration.write(MPU_RA_INT_PIN_CFG, 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0); // INT_ANYRD_2CLEAR, BYPASS_EN
|
||||
mpuConfiguration.write(MPU_RA_INT_PIN_CFG, MPU6500_BIT_INT_ANYRD_2CLEAR | MPU6500_BIT_BYPASS_EN); // INT_ANYRD_2CLEAR, BYPASS_EN
|
||||
#else
|
||||
mpuConfiguration.write(MPU_RA_INT_PIN_CFG, 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0); // INT_ANYRD_2CLEAR, BYPASS_EN
|
||||
mpuConfiguration.write(MPU_RA_INT_PIN_CFG, MPU6500_BIT_INT_ANYRD_2CLEAR); // INT_ANYRD_2CLEAR
|
||||
#endif
|
||||
delay(15);
|
||||
|
||||
#ifdef USE_MPU_DATA_READY_SIGNAL
|
||||
mpuConfiguration.write(MPU_RA_INT_ENABLE, 0x01); // RAW_RDY_EN interrupt enable
|
||||
mpuConfiguration.write(MPU_RA_INT_ENABLE, MPU6500_BIT_RAW_RDY_EN); // RAW_RDY_EN interrupt enable
|
||||
#endif
|
||||
delay(15);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#define ICM20608G_WHO_AM_I_CONST (0xAF)
|
||||
|
||||
#define MPU6500_BIT_RESET (0x80)
|
||||
#define MPU6500_BIT_INT_ANYRD_2CLEAR (1 << 4)
|
||||
#define MPU6500_BIT_BYPASS_EN (1 << 0)
|
||||
#define MPU6500_BIT_I2C_IF_DIS (1 << 4)
|
||||
#define MPU6500_BIT_RAW_RDY_EN (0x01)
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ bool mpu6000SpiDetect(void)
|
|||
uint8_t in;
|
||||
uint8_t attemptsRemaining = 5;
|
||||
|
||||
#ifdef MPU6000_CS_PIN
|
||||
#ifdef MPU6000_CS_PIN
|
||||
mpuSpi6000CsPin = IOGetByTag(IO_TAG(MPU6000_CS_PIN));
|
||||
#endif
|
||||
IOInit(mpuSpi6000CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
|
||||
|
@ -205,8 +205,8 @@ bool mpu6000SpiDetect(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void mpu6000AccAndGyroInit(void) {
|
||||
|
||||
static void mpu6000AccAndGyroInit(void)
|
||||
{
|
||||
if (mpuSpi6000InitDone) {
|
||||
return;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ static void mpu6000AccAndGyroInit(void) {
|
|||
delayMicroseconds(15);
|
||||
#endif
|
||||
|
||||
spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
delayMicroseconds(1);
|
||||
|
||||
mpuSpi6000InitDone = true;
|
||||
|
|
|
@ -91,13 +91,33 @@ bool mpu6500SpiDetect(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
void mpu6500SpiAccInit(acc_t *acc)
|
||||
{
|
||||
mpu6500AccInit(acc);
|
||||
}
|
||||
|
||||
void mpu6500SpiGyroInit(uint8_t lpf)
|
||||
{
|
||||
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_SLOW);
|
||||
delayMicroseconds(1);
|
||||
|
||||
mpu6500GyroInit(lpf);
|
||||
|
||||
// Disable Primary I2C Interface
|
||||
mpu6500WriteRegister(MPU_RA_USER_CTRL, MPU6500_BIT_I2C_IF_DIS);
|
||||
delay(100);
|
||||
|
||||
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
|
||||
bool mpu6500SpiAccDetect(acc_t *acc)
|
||||
{
|
||||
if (mpuDetectionResult.sensor != MPU_65xx_SPI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
acc->init = mpu6500AccInit;
|
||||
acc->init = mpu6500SpiAccInit;
|
||||
acc->read = mpuAccRead;
|
||||
|
||||
return true;
|
||||
|
@ -109,7 +129,7 @@ bool mpu6500SpiGyroDetect(gyro_t *gyro)
|
|||
return false;
|
||||
}
|
||||
|
||||
gyro->init = mpu6500GyroInit;
|
||||
gyro->init = mpu6500SpiGyroInit;
|
||||
gyro->read = mpuGyroRead;
|
||||
gyro->intStatus = checkMPUDataReady;
|
||||
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
|
||||
bool mpu6500SpiDetect(void);
|
||||
|
||||
void mpu6500SpiAccInit(acc_t *acc);
|
||||
void mpu6500SpiGyroInit(uint8_t lpf);
|
||||
|
||||
bool mpu6500SpiAccDetect(acc_t *acc);
|
||||
bool mpu6500SpiGyroDetect(gyro_t *gyro);
|
||||
|
||||
bool mpu6500WriteRegister(uint8_t reg, uint8_t data);
|
||||
bool mpu6500ReadRegister(uint8_t reg, uint8_t length, uint8_t *data);
|
||||
bool mpu6500ReadRegister(uint8_t reg, uint8_t length, uint8_t *data);
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "light_led.h"
|
||||
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
@ -38,7 +39,7 @@
|
|||
#include "exti.h"
|
||||
#include "bus_spi.h"
|
||||
#include "gyro_sync.h"
|
||||
#include "debug.h"
|
||||
#include "light_led.h"
|
||||
|
||||
#include "sensor.h"
|
||||
#include "accgyro.h"
|
||||
|
@ -54,7 +55,7 @@ static IO_t mpuSpi9250CsPin = IO_NONE;
|
|||
#define DISABLE_MPU9250 IOHi(mpuSpi9250CsPin)
|
||||
#define ENABLE_MPU9250 IOLo(mpuSpi9250CsPin)
|
||||
|
||||
void mpu9250ResetGyro(void)
|
||||
void mpu9250ResetGyro(void)
|
||||
{
|
||||
// Device Reset
|
||||
mpu9250WriteRegister(MPU_RA_PWR_MGMT_1, MPU9250_BIT_RESET);
|
||||
|
@ -123,7 +124,7 @@ void mpu9250SpiAccInit(acc_t *acc)
|
|||
acc->acc_1G = 512 * 8;
|
||||
}
|
||||
|
||||
bool verifympu9250WriteRegister(uint8_t reg, uint8_t data)
|
||||
bool verifympu9250WriteRegister(uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t in;
|
||||
uint8_t attemptsRemaining = 20;
|
||||
|
@ -176,7 +177,7 @@ static void mpu9250AccAndGyroInit(uint8_t lpf) {
|
|||
verifympu9250WriteRegister(MPU_RA_INT_ENABLE, 0x01); //this resets register MPU_RA_PWR_MGMT_1 and won't read back correctly.
|
||||
#endif
|
||||
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
|
||||
mpuSpi9250InitDone = true; //init done
|
||||
}
|
||||
|
@ -208,7 +209,7 @@ bool mpu9250SpiDetect(void)
|
|||
}
|
||||
} while (attemptsRemaining--);
|
||||
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,17 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "adc.h"
|
||||
#include "adc_impl.h"
|
||||
|
||||
#include "common/utils.h"
|
||||
|
||||
//#define DEBUG_ADC_CHANNELS
|
||||
|
||||
#ifdef USE_ADC
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "io.h"
|
||||
#include "io_types.h"
|
||||
|
||||
typedef enum {
|
||||
ADC_BATTERY = 0,
|
||||
|
|
|
@ -17,21 +17,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "io.h"
|
||||
#include "rcc.h"
|
||||
#include "io_types.h"
|
||||
#include "rcc_types.h"
|
||||
|
||||
#if defined(STM32F4)
|
||||
#define ADC_TAG_MAP_COUNT 16
|
||||
#elif defined(STM32F3)
|
||||
#define ADC_TAG_MAP_COUNT 39
|
||||
#else
|
||||
#else
|
||||
#define ADC_TAG_MAP_COUNT 10
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum ADCDevice {
|
||||
ADCINVALID = -1,
|
||||
ADCDEV_1 = 0,
|
||||
#if defined(STM32F3)
|
||||
#if defined(STM32F3)
|
||||
ADCDEV_2,
|
||||
ADCDEV_MAX = ADCDEV_2,
|
||||
#elif defined(STM32F4)
|
||||
|
@ -65,4 +65,4 @@ extern const adcTagMap_t adcTagMap[ADC_TAG_MAP_COUNT];
|
|||
extern adc_config_t adcConfig[ADC_CHANNEL_COUNT];
|
||||
extern volatile uint16_t adcValues[ADC_CHANNEL_COUNT];
|
||||
|
||||
uint8_t adcChannelByTag(ioTag_t ioTag);
|
||||
uint8_t adcChannelByTag(ioTag_t ioTag);
|
||||
|
|
|
@ -21,12 +21,11 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
#ifdef USE_ADC
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "sensors/sensors.h" // FIXME dependency into the main code
|
||||
|
||||
#include "sensor.h"
|
||||
#include "accgyro.h"
|
||||
#include "adc.h"
|
||||
|
@ -38,13 +37,13 @@
|
|||
#define ADC_INSTANCE ADC1
|
||||
#endif
|
||||
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_APB2(ADC1), .rccDMA = RCC_AHB(DMA1), .DMAy_Channelx = DMA1_Channel1 }
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_APB2(ADC1), .rccDMA = RCC_AHB(DMA1), .DMAy_Channelx = DMA1_Channel1 }
|
||||
};
|
||||
|
||||
ADCDevice adcDeviceByInstance(ADC_TypeDef *instance)
|
||||
{
|
||||
if (instance == ADC1)
|
||||
if (instance == ADC1)
|
||||
return ADCDEV_1;
|
||||
|
||||
/* TODO -- ADC2 available on large 10x devices.
|
||||
|
@ -54,7 +53,7 @@ ADCDevice adcDeviceByInstance(ADC_TypeDef *instance)
|
|||
return ADCINVALID;
|
||||
}
|
||||
|
||||
const adcTagMap_t adcTagMap[] = {
|
||||
const adcTagMap_t adcTagMap[] = {
|
||||
{ DEFIO_TAG_E__PA0, ADC_Channel_0 }, // ADC12
|
||||
{ DEFIO_TAG_E__PA1, ADC_Channel_1 }, // ADC12
|
||||
{ DEFIO_TAG_E__PA2, ADC_Channel_2 }, // ADC12
|
||||
|
@ -64,7 +63,7 @@ const adcTagMap_t adcTagMap[] = {
|
|||
{ DEFIO_TAG_E__PA6, ADC_Channel_6 }, // ADC12
|
||||
{ DEFIO_TAG_E__PA7, ADC_Channel_7 }, // ADC12
|
||||
{ DEFIO_TAG_E__PB0, ADC_Channel_8 }, // ADC12
|
||||
{ DEFIO_TAG_E__PB1, ADC_Channel_9 }, // ADC12
|
||||
{ DEFIO_TAG_E__PB1, ADC_Channel_9 }, // ADC12
|
||||
};
|
||||
|
||||
// Driver for STM32F103CB onboard ADC
|
||||
|
@ -84,7 +83,6 @@ void adcInit(drv_adc_config_t *init)
|
|||
UNUSED(init);
|
||||
#endif
|
||||
|
||||
uint8_t i;
|
||||
uint8_t configuredAdcChannels = 0;
|
||||
|
||||
memset(&adcConfig, 0, sizeof(adcConfig));
|
||||
|
@ -117,9 +115,9 @@ void adcInit(drv_adc_config_t *init)
|
|||
if (device == ADCINVALID)
|
||||
return;
|
||||
|
||||
adcDevice_t adc = adcHardware[device];
|
||||
const adcDevice_t adc = adcHardware[device];
|
||||
|
||||
for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
for (int i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
if (!adcConfig[i].tag)
|
||||
continue;
|
||||
|
||||
|
@ -163,7 +161,7 @@ void adcInit(drv_adc_config_t *init)
|
|||
ADC_Init(adc.ADCx, &ADC_InitStructure);
|
||||
|
||||
uint8_t rank = 1;
|
||||
for (i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
for (int i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
if (!adcConfig[i].enabled) {
|
||||
continue;
|
||||
}
|
||||
|
@ -180,3 +178,4 @@ void adcInit(drv_adc_config_t *init)
|
|||
|
||||
ADC_SoftwareStartConvCmd(adc.ADCx, ENABLE);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "platform.h"
|
||||
#include "system.h"
|
||||
#include "common/utils.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#include "sensor.h"
|
||||
|
@ -32,16 +31,18 @@
|
|||
#include "io.h"
|
||||
#include "rcc.h"
|
||||
|
||||
#include "common/utils.h"
|
||||
|
||||
#ifndef ADC_INSTANCE
|
||||
#define ADC_INSTANCE ADC1
|
||||
#endif
|
||||
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_AHB(ADC12), .rccDMA = RCC_AHB(DMA1), .DMAy_Channelx = DMA1_Channel1 },
|
||||
{ .ADCx = ADC2, .rccADC = RCC_AHB(ADC12), .rccDMA = RCC_AHB(DMA2), .DMAy_Channelx = DMA2_Channel1 }
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_AHB(ADC12), .rccDMA = RCC_AHB(DMA1), .DMAy_Channelx = DMA1_Channel1 },
|
||||
{ .ADCx = ADC2, .rccADC = RCC_AHB(ADC12), .rccDMA = RCC_AHB(DMA2), .DMAy_Channelx = DMA2_Channel1 }
|
||||
};
|
||||
|
||||
const adcTagMap_t adcTagMap[] = {
|
||||
const adcTagMap_t adcTagMap[] = {
|
||||
{ DEFIO_TAG_E__PA0, ADC_Channel_1 }, // ADC1
|
||||
{ DEFIO_TAG_E__PA1, ADC_Channel_2 }, // ADC1
|
||||
{ DEFIO_TAG_E__PA2, ADC_Channel_3 }, // ADC1
|
||||
|
@ -85,7 +86,7 @@ const adcTagMap_t adcTagMap[] = {
|
|||
|
||||
ADCDevice adcDeviceByInstance(ADC_TypeDef *instance)
|
||||
{
|
||||
if (instance == ADC1)
|
||||
if (instance == ADC1)
|
||||
return ADCDEV_1;
|
||||
|
||||
if (instance == ADC2)
|
||||
|
@ -100,7 +101,6 @@ void adcInit(drv_adc_config_t *init)
|
|||
ADC_InitTypeDef ADC_InitStructure;
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
uint8_t i;
|
||||
uint8_t adcChannelCount = 0;
|
||||
|
||||
memset(&adcConfig, 0, sizeof(adcConfig));
|
||||
|
@ -133,9 +133,9 @@ void adcInit(drv_adc_config_t *init)
|
|||
if (device == ADCINVALID)
|
||||
return;
|
||||
|
||||
adcDevice_t adc = adcHardware[device];
|
||||
adcDevice_t adc = adcHardware[device];
|
||||
|
||||
for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
for (int i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
if (!adcConfig[i].tag)
|
||||
continue;
|
||||
|
||||
|
@ -203,7 +203,7 @@ void adcInit(drv_adc_config_t *init)
|
|||
ADC_Init(adc.ADCx, &ADC_InitStructure);
|
||||
|
||||
uint8_t rank = 1;
|
||||
for (i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
for (int i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
if (!adcConfig[i].enabled) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include "io_impl.h"
|
||||
#include "rcc.h"
|
||||
|
||||
#include "sensors/sensors.h" // FIXME dependency into the main code
|
||||
|
||||
#include "sensor.h"
|
||||
#include "accgyro.h"
|
||||
|
||||
|
@ -38,13 +36,13 @@
|
|||
#define ADC_INSTANCE ADC1
|
||||
#endif
|
||||
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_APB2(ADC1), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream4, .channel = DMA_Channel_0 },
|
||||
//{ .ADCx = ADC2, .rccADC = RCC_APB2(ADC2), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream1, .channel = DMA_Channel_0 }
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_APB2(ADC1), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream4, .channel = DMA_Channel_0 },
|
||||
//{ .ADCx = ADC2, .rccADC = RCC_APB2(ADC2), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream1, .channel = DMA_Channel_0 }
|
||||
};
|
||||
|
||||
/* note these could be packed up for saving space */
|
||||
const adcTagMap_t adcTagMap[] = {
|
||||
const adcTagMap_t adcTagMap[] = {
|
||||
/*
|
||||
{ DEFIO_TAG_E__PF3, ADC_Channel_9 },
|
||||
{ DEFIO_TAG_E__PF4, ADC_Channel_14 },
|
||||
|
@ -75,7 +73,7 @@ const adcTagMap_t adcTagMap[] = {
|
|||
|
||||
ADCDevice adcDeviceByInstance(ADC_TypeDef *instance)
|
||||
{
|
||||
if (instance == ADC1)
|
||||
if (instance == ADC1)
|
||||
return ADCDEV_1;
|
||||
/*
|
||||
if (instance == ADC2) // TODO add ADC2 and 3
|
||||
|
@ -128,7 +126,7 @@ void adcInit(drv_adc_config_t *init)
|
|||
if (device == ADCINVALID)
|
||||
return;
|
||||
|
||||
adcDevice_t adc = adcHardware[device];
|
||||
adcDevice_t adc = adcHardware[device];
|
||||
|
||||
for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) {
|
||||
if (!adcConfig[i].tag)
|
||||
|
|
|
@ -32,4 +32,4 @@ typedef struct baro_s {
|
|||
|
||||
#ifndef BARO_I2C_INSTANCE
|
||||
#define BARO_I2C_INSTANCE I2C_DEVICE
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "barometer.h"
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
#ifdef BARO
|
||||
|
||||
#if defined(BARO_EOC_GPIO)
|
||||
#if defined(BARO_EOC_GPIO)
|
||||
|
||||
static IO_t eocIO;
|
||||
|
||||
|
@ -49,7 +49,7 @@ void bmp085_extiHandler(extiCallbackRec_t* cb)
|
|||
isConversionComplete = true;
|
||||
}
|
||||
|
||||
bool bmp085TestEOCConnected(const bmp085Config_t *config);
|
||||
bool bmp085TestEOCConnected(const bmp085Config_t *config);
|
||||
# endif
|
||||
|
||||
typedef struct {
|
||||
|
@ -139,7 +139,7 @@ static IO_t xclrIO;
|
|||
#endif
|
||||
|
||||
|
||||
void bmp085InitXclrIO(const bmp085Config_t *config)
|
||||
void bmp085InitXclrIO(const bmp085Config_t *config)
|
||||
{
|
||||
if (!xclrIO && config && config->xclrIO) {
|
||||
xclrIO = IOGetByTag(config->xclrIO);
|
||||
|
@ -184,7 +184,7 @@ bool bmp085Detect(const bmp085Config_t *config, baro_t *baro)
|
|||
|
||||
delay(20); // datasheet says 10ms, we'll be careful and do 20.
|
||||
|
||||
ack = i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CHIP_ID__REG, 1, &data); /* read Chip Id */
|
||||
ack = i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CHIP_ID__REG, 1, &data); /* read Chip Id */
|
||||
if (ack) {
|
||||
bmp085.chip_id = BMP085_GET_BITSLICE(data, BMP085_CHIP_ID);
|
||||
bmp085.oversampling_setting = 3;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
typedef struct bmp085Config_s {
|
||||
ioTag_t xclrIO;
|
||||
ioTag_t eocIO;
|
||||
ioTag_t eocIO;
|
||||
} bmp085Config_t;
|
||||
|
||||
bool bmp085Detect(const bmp085Config_t *config, baro_t *baro);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "barometer.h"
|
||||
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "barometer.h"
|
||||
|
||||
#include "gpio.h"
|
||||
#include "system.h"
|
||||
#include "bus_i2c.h"
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
// MS5611, Standard address 0x77
|
||||
#define MS5611_ADDR 0x77
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* along with Betaflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -24,6 +25,7 @@
|
|||
|
||||
#include "barometer.h"
|
||||
#include "barometer_bmp280.h"
|
||||
#include "io.h"
|
||||
|
||||
#ifdef USE_BARO_SPI_BMP280
|
||||
#define DISABLE_BMP280 IOHi(bmp280CsPin)
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
#define I2C_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT))
|
||||
#define I2C_DEFAULT_TIMEOUT I2C_SHORT_TIMEOUT
|
||||
|
||||
#include "drivers/io.h"
|
||||
#include "drivers/rcc.h"
|
||||
#include "io_types.h"
|
||||
#include "rcc_types.h"
|
||||
|
||||
#ifndef I2C_DEVICE
|
||||
#define I2C_DEVICE I2CINVALID
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum I2CDevice {
|
||||
I2CINVALID = -1,
|
||||
|
|
|
@ -20,9 +20,10 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "bus_i2c.h"
|
||||
#include "drivers/io.h"
|
||||
#include "io.h"
|
||||
|
||||
// Software I2C driver, using same pins as hardware I2C, with hw i2c module disabled.
|
||||
// Can be configured for I2C2 pinout (SCL: PB10, SDA: PB11) or I2C1 pinout (SCL: PB6, SDA: PB7)
|
||||
|
|
|
@ -47,35 +47,39 @@ static void i2cUnstick(IO_t scl, IO_t sda);
|
|||
#define IOCFG_I2C IOCFG_AF_OD
|
||||
#endif
|
||||
|
||||
#ifndef I2C1_SCL
|
||||
#define I2C1_SCL PB8
|
||||
#ifndef I2C1_SCL
|
||||
#define I2C1_SCL PB8
|
||||
#endif
|
||||
#ifndef I2C1_SDA
|
||||
#define I2C1_SDA PB9
|
||||
#ifndef I2C1_SDA
|
||||
#define I2C1_SDA PB9
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef I2C1_SCL
|
||||
#define I2C1_SCL PB6
|
||||
|
||||
#ifndef I2C1_SCL
|
||||
#define I2C1_SCL PB6
|
||||
#endif
|
||||
#ifndef I2C1_SDA
|
||||
#define I2C1_SDA PB7
|
||||
#ifndef I2C1_SDA
|
||||
#define I2C1_SDA PB7
|
||||
#endif
|
||||
#define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF_OD, GPIO_Speed_50MHz)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef I2C2_SCL
|
||||
#define I2C2_SCL PB10
|
||||
#ifndef I2C2_SCL
|
||||
#define I2C2_SCL PB10
|
||||
#endif
|
||||
#ifndef I2C2_SDA
|
||||
|
||||
#ifndef I2C2_SDA
|
||||
#define I2C2_SDA PB11
|
||||
#endif
|
||||
|
||||
#ifdef STM32F4
|
||||
#ifndef I2C3_SCL
|
||||
#ifndef I2C3_SCL
|
||||
#define I2C3_SCL PA8
|
||||
#endif
|
||||
#ifndef I2C3_SDA
|
||||
#define I2C3_SDA PB4
|
||||
#ifndef I2C3_SDA
|
||||
#define I2C3_SDA PB4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -93,7 +97,7 @@ static i2cState_t i2cState[] = {
|
|||
{ false, false, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ false, false, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ false, false, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
};
|
||||
|
||||
void I2C1_ER_IRQHandler(void) {
|
||||
i2c_er_handler(I2CDEV_1);
|
||||
|
@ -121,7 +125,7 @@ void I2C3_EV_IRQHandler(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool i2cHandleHardwareFailure(I2CDevice device)
|
||||
static bool i2cHandleHardwareFailure(I2CDevice device)
|
||||
{
|
||||
i2cErrorCount++;
|
||||
// reinit peripheral + clock out garbage
|
||||
|
@ -129,7 +133,7 @@ static bool i2cHandleHardwareFailure(I2CDevice device)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_, uint8_t *data)
|
||||
bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_, uint8_t *data)
|
||||
{
|
||||
|
||||
if (device == I2CINVALID)
|
||||
|
@ -138,7 +142,7 @@ bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_,
|
|||
uint32_t timeout = I2C_DEFAULT_TIMEOUT;
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
i2cState_t *state;
|
||||
state = &(i2cState[device]);
|
||||
|
@ -171,12 +175,12 @@ bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_,
|
|||
return !(state->error);
|
||||
}
|
||||
|
||||
bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t data)
|
||||
bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t data)
|
||||
{
|
||||
return i2cWriteBuffer(device, addr_, reg_, 1, &data);
|
||||
}
|
||||
|
||||
bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf)
|
||||
bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf)
|
||||
{
|
||||
if (device == I2CINVALID)
|
||||
return false;
|
||||
|
@ -369,7 +373,7 @@ void i2c_ev_handler(I2CDevice device) {
|
|||
}
|
||||
}
|
||||
|
||||
void i2cInit(I2CDevice device)
|
||||
void i2cInit(I2CDevice device)
|
||||
{
|
||||
if (device == I2CINVALID)
|
||||
return;
|
||||
|
@ -392,14 +396,14 @@ void i2cInit(I2CDevice device)
|
|||
I2C_ITConfig(i2c->dev, I2C_IT_EVT | I2C_IT_ERR, DISABLE);
|
||||
|
||||
i2cUnstick(scl, sda);
|
||||
|
||||
|
||||
// Init pins
|
||||
#ifdef STM32F4
|
||||
IOConfigGPIOAF(scl, IOCFG_I2C, GPIO_AF_I2C);
|
||||
IOConfigGPIOAF(sda, IOCFG_I2C, GPIO_AF_I2C);
|
||||
#else
|
||||
IOConfigGPIO(scl, IOCFG_AF_OD);
|
||||
IOConfigGPIO(sda, IOCFG_AF_OD);
|
||||
IOConfigGPIO(scl, IOCFG_I2C);
|
||||
IOConfigGPIO(sda, IOCFG_I2C);
|
||||
#endif
|
||||
|
||||
I2C_DeInit(i2c->dev);
|
||||
|
|
|
@ -20,18 +20,19 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "gpio.h"
|
||||
#include "system.h"
|
||||
#include "drivers/io_impl.h"
|
||||
#include "io.h"
|
||||
#include "io_impl.h"
|
||||
#include "rcc.h"
|
||||
|
||||
#include "bus_i2c.h"
|
||||
|
||||
#ifndef SOFT_I2C
|
||||
|
||||
#if defined(USE_I2C_PULLUP)
|
||||
#define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_OD, GPIO_PuPd_UP)
|
||||
#define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_UP)
|
||||
#else
|
||||
#define IOCFG_I2C IOCFG_AF_OD
|
||||
#define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL)
|
||||
#endif
|
||||
|
||||
#define I2C_HIGHSPEED_TIMING 0x00500E30 // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
|
||||
|
@ -39,18 +40,18 @@
|
|||
|
||||
#define I2C_SHORT_TIMEOUT ((uint32_t)0x1000)
|
||||
#define I2C_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT))
|
||||
#define I2C_GPIO_AF GPIO_AF_4
|
||||
#define I2C_GPIO_AF GPIO_AF_4
|
||||
|
||||
#ifndef I2C1_SCL
|
||||
#define I2C1_SCL PB6
|
||||
#ifndef I2C1_SCL
|
||||
#define I2C1_SCL PB6
|
||||
#endif
|
||||
#ifndef I2C1_SDA
|
||||
#define I2C1_SDA PB7
|
||||
#ifndef I2C1_SDA
|
||||
#define I2C1_SDA PB7
|
||||
#endif
|
||||
#ifndef I2C2_SCL
|
||||
#define I2C2_SCL PF4
|
||||
#ifndef I2C2_SCL
|
||||
#define I2C2_SCL PF4
|
||||
#endif
|
||||
#ifndef I2C2_SDA
|
||||
#ifndef I2C2_SDA
|
||||
#define I2C2_SDA PA10
|
||||
#endif
|
||||
|
||||
|
@ -82,7 +83,7 @@ void i2cInit(I2CDevice device)
|
|||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2c->dev;
|
||||
|
||||
|
||||
IO_t scl = IOGetByTag(i2c->scl);
|
||||
IO_t sda = IOGetByTag(i2c->sda);
|
||||
|
||||
|
@ -108,7 +109,7 @@ void i2cInit(I2CDevice device)
|
|||
I2C_Init(I2Cx, &i2cInit);
|
||||
|
||||
I2C_StretchClockCmd(I2Cx, ENABLE);
|
||||
|
||||
|
||||
I2C_Cmd(I2Cx, ENABLE);
|
||||
}
|
||||
|
||||
|
@ -122,7 +123,7 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
addr_ <<= 1;
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
/* Test on BUSY Flag */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
|
@ -132,10 +133,10 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
|
||||
|
||||
/* Wait until TXIS flag is set */
|
||||
/* Wait until TXIS flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
|
@ -143,10 +144,10 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Send Register address */
|
||||
/* Send Register address */
|
||||
I2C_SendData(I2Cx, (uint8_t) reg);
|
||||
|
||||
/* Wait until TCR flag is set */
|
||||
/* Wait until TCR flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET)
|
||||
{
|
||||
|
@ -155,10 +156,10 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
|
||||
|
||||
/* Wait until TXIS flag is set */
|
||||
/* Wait until TXIS flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
|
@ -166,10 +167,10 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Write data to TXDR */
|
||||
/* Write data to TXDR */
|
||||
I2C_SendData(I2Cx, data);
|
||||
|
||||
/* Wait until STOPF flag is set */
|
||||
/* Wait until STOPF flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
|
@ -177,7 +178,7 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
}
|
||||
}
|
||||
|
||||
/* Clear STOPF flag */
|
||||
/* Clear STOPF flag */
|
||||
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
|
||||
|
||||
return true;
|
||||
|
@ -188,7 +189,7 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
addr_ <<= 1;
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
/* Test on BUSY Flag */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
|
@ -198,10 +199,10 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
}
|
||||
}
|
||||
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
|
||||
|
||||
/* Wait until TXIS flag is set */
|
||||
/* Wait until TXIS flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
|
@ -209,10 +210,10 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
}
|
||||
}
|
||||
|
||||
/* Send Register address */
|
||||
/* Send Register address */
|
||||
I2C_SendData(I2Cx, (uint8_t) reg);
|
||||
|
||||
/* Wait until TC flag is set */
|
||||
/* Wait until TC flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
|
@ -220,10 +221,10 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
}
|
||||
}
|
||||
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
/* Configure slave address, nbytes, reload, end mode and start or stop generation */
|
||||
I2C_TransferHandling(I2Cx, addr_, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
|
||||
|
||||
/* Wait until all data are received */
|
||||
/* Wait until all data are received */
|
||||
while (len) {
|
||||
/* Wait until RXNE flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
|
@ -233,16 +234,16 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
}
|
||||
}
|
||||
|
||||
/* Read data from RXDR */
|
||||
/* Read data from RXDR */
|
||||
*buf = I2C_ReceiveData(I2Cx);
|
||||
/* Point to the next location where the byte read will be saved */
|
||||
buf++;
|
||||
|
||||
/* Decrement the read bytes counter */
|
||||
/* Decrement the read bytes counter */
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Wait until STOPF flag is set */
|
||||
/* Wait until STOPF flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
|
@ -250,10 +251,10 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
}
|
||||
}
|
||||
|
||||
/* Clear STOPF flag */
|
||||
/* Clear STOPF flag */
|
||||
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
|
||||
|
||||
/* If all operations OK */
|
||||
/* If all operations OK */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <platform.h>
|
||||
|
||||
#include "bus_spi.h"
|
||||
#include "exti.h"
|
||||
#include "io.h"
|
||||
#include "io_impl.h"
|
||||
#include "rcc.h"
|
||||
|
@ -36,7 +37,7 @@
|
|||
#ifndef GPIO_AF_SPI3
|
||||
#define GPIO_AF_SPI3 GPIO_AF_6
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SPI1_SCK_PIN
|
||||
#define SPI1_NSS_PIN PA4
|
||||
|
@ -84,7 +85,7 @@ static spiDevice_t spiHardwareMap[] = {
|
|||
|
||||
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
|
||||
{
|
||||
if (instance == SPI1)
|
||||
if (instance == SPI1)
|
||||
return SPIDEV_1;
|
||||
|
||||
if (instance == SPI2)
|
||||
|
|
|
@ -17,9 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "io.h"
|
||||
#include "rcc.h"
|
||||
#include "io_types.h"
|
||||
#include "rcc_types.h"
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F3)
|
||||
#define SPI_IO_AF_CFG IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
|
||||
|
@ -31,8 +30,6 @@
|
|||
#define SPI_IO_AF_MOSI_CFG IO_CONFIG(GPIO_Mode_AF_PP, GPIO_Speed_50MHz)
|
||||
#define SPI_IO_AF_MISO_CFG IO_CONFIG(GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz)
|
||||
#define SPI_IO_CS_CFG IO_CONFIG(GPIO_Mode_Out_PP, GPIO_Speed_50MHz)
|
||||
#else
|
||||
#error "Unknown processor"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,4 +24,4 @@ typedef struct mag_s {
|
|||
|
||||
#ifndef MAG_I2C_INSTANCE
|
||||
#define MAG_I2C_INSTANCE I2C_DEVICE
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
@ -33,9 +32,6 @@
|
|||
#include "bus_i2c.h"
|
||||
#include "bus_spi.h"
|
||||
|
||||
#include "sensors/boardalignment.h"
|
||||
#include "sensors/sensors.h"
|
||||
|
||||
#include "sensor.h"
|
||||
#include "compass.h"
|
||||
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef USE_MAG_AK8975
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
||||
|
@ -31,9 +33,6 @@
|
|||
#include "gpio.h"
|
||||
#include "bus_i2c.h"
|
||||
|
||||
#include "sensors/boardalignment.h"
|
||||
#include "sensors/sensors.h"
|
||||
|
||||
#include "sensor.h"
|
||||
#include "compass.h"
|
||||
|
||||
|
@ -59,7 +58,7 @@
|
|||
#define AK8975_MAG_REG_CNTL 0x0a
|
||||
#define AK8975_MAG_REG_ASCT 0x0c // self test
|
||||
|
||||
bool ak8975detect(mag_t *mag)
|
||||
bool ak8975Detect(mag_t *mag)
|
||||
{
|
||||
bool ack = false;
|
||||
uint8_t sig = 0;
|
||||
|
@ -155,3 +154,4 @@ bool ak8975Read(int16_t *magData)
|
|||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x01); // start reading again
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
bool ak8975detect(mag_t *mag);
|
||||
bool ak8975Detect(mag_t *mag);
|
||||
void ak8975Init(void);
|
||||
bool ak8975Read(int16_t *magData);
|
||||
|
|
|
@ -21,7 +21,10 @@
|
|||
#include <math.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef USE_MAG_HMC5883
|
||||
|
||||
#include "build/debug.h"
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
@ -36,8 +39,6 @@
|
|||
#include "sensor.h"
|
||||
#include "compass.h"
|
||||
|
||||
#include "sensors/sensors.h"
|
||||
|
||||
#include "compass_hmc5883l.h"
|
||||
|
||||
//#define DEBUG_MAG_DATA_READY_INTERRUPT
|
||||
|
@ -271,3 +272,4 @@ bool hmc5883lRead(int16_t *magData)
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "io.h"
|
||||
#include "io_types.h"
|
||||
|
||||
typedef struct hmc5883Config_s {
|
||||
ioTag_t intTag;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "drivers/nvic.h"
|
||||
#include "drivers/dma.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
|
||||
/*
|
||||
* DMA descriptors.
|
||||
|
|
|
@ -22,13 +22,15 @@ typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channel
|
|||
#ifdef STM32F4
|
||||
|
||||
typedef enum {
|
||||
DMA1_ST1_HANDLER = 0,
|
||||
DMA1_ST0_HANDLER = 0,
|
||||
DMA1_ST1_HANDLER,
|
||||
DMA1_ST2_HANDLER,
|
||||
DMA1_ST3_HANDLER,
|
||||
DMA1_ST4_HANDLER,
|
||||
DMA1_ST5_HANDLER,
|
||||
DMA1_ST6_HANDLER,
|
||||
DMA1_ST7_HANDLER,
|
||||
DMA2_ST0_HANDLER,
|
||||
DMA2_ST1_HANDLER,
|
||||
DMA2_ST2_HANDLER,
|
||||
DMA2_ST3_HANDLER,
|
||||
|
@ -63,7 +65,7 @@ typedef struct dmaChannelDescriptor_s {
|
|||
#define DMA_IT_TEIF ((uint32_t)0x00000008)
|
||||
#define DMA_IT_DMEIF ((uint32_t)0x00000004)
|
||||
#define DMA_IT_FEIF ((uint32_t)0x00000001)
|
||||
|
||||
|
||||
#else
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "drivers/nvic.h"
|
||||
#include "drivers/dma.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
|
||||
/*
|
||||
* DMA descriptors.
|
||||
|
@ -45,12 +45,12 @@ static dmaChannelDescriptor_t dmaDescriptors[] = {
|
|||
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1Periph_DMA2),
|
||||
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1Periph_DMA2),
|
||||
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1Periph_DMA2),
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA IRQ Handlers
|
||||
*/
|
||||
DEFINE_DMA_IRQ_HANDLER(1, 0, DMA1_ST0_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_ST1_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_ST2_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_ST3_HANDLER)
|
||||
|
@ -58,12 +58,14 @@ DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_ST4_HANDLER)
|
|||
DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_ST5_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_ST6_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_ST7_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 0, DMA2_ST0_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_ST1_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_ST2_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_ST3_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_ST4_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_ST5_HANDLER)
|
||||
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 6, DMA2_ST6_HANDLER)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 7, DMA2_ST7_HANDLER)
|
||||
|
||||
void dmaInit(void)
|
||||
{
|
||||
|
|
|
@ -24,22 +24,22 @@ static uint8_t extiGroupPriority[EXTI_IRQ_GROUPS];
|
|||
|
||||
#if defined(STM32F1) || defined(STM32F4)
|
||||
static const uint8_t extiGroupIRQn[EXTI_IRQ_GROUPS] = {
|
||||
EXTI0_IRQn,
|
||||
EXTI1_IRQn,
|
||||
EXTI2_IRQn,
|
||||
EXTI3_IRQn,
|
||||
EXTI0_IRQn,
|
||||
EXTI1_IRQn,
|
||||
EXTI2_IRQn,
|
||||
EXTI3_IRQn,
|
||||
EXTI4_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI15_10_IRQn
|
||||
};
|
||||
#elif defined(STM32F3)
|
||||
static const uint8_t extiGroupIRQn[EXTI_IRQ_GROUPS] = {
|
||||
EXTI0_IRQn,
|
||||
EXTI1_IRQn,
|
||||
EXTI2_TS_IRQn,
|
||||
EXTI3_IRQn,
|
||||
EXTI0_IRQn,
|
||||
EXTI1_IRQn,
|
||||
EXTI2_TS_IRQn,
|
||||
EXTI3_IRQn,
|
||||
EXTI4_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI9_5_IRQn,
|
||||
EXTI15_10_IRQn
|
||||
};
|
||||
#else
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "drivers/io.h"
|
||||
#include "io_types.h"
|
||||
|
||||
// old EXTI interface, to be replaced
|
||||
typedef struct extiConfig_s {
|
||||
|
|
|
@ -22,9 +22,10 @@
|
|||
|
||||
#ifdef USE_FLASH_M25P16
|
||||
|
||||
#include "drivers/flash_m25p16.h"
|
||||
#include "drivers/bus_spi.h"
|
||||
#include "drivers/system.h"
|
||||
#include "flash_m25p16.h"
|
||||
#include "io.h"
|
||||
#include "bus_spi.h"
|
||||
#include "system.h"
|
||||
|
||||
#define M25P16_INSTRUCTION_RDID 0x9F
|
||||
#define M25P16_INSTRUCTION_READ_BYTES 0x03
|
||||
|
@ -43,6 +44,7 @@
|
|||
#define JEDEC_ID_MICRON_M25P16 0x202015
|
||||
#define JEDEC_ID_MICRON_N25Q064 0x20BA17
|
||||
#define JEDEC_ID_WINBOND_W25Q64 0xEF4017
|
||||
#define JEDEC_ID_MACRONIX_MX25L3206E 0xC22016
|
||||
#define JEDEC_ID_MACRONIX_MX25L6406E 0xC22017
|
||||
#define JEDEC_ID_MICRON_N25Q128 0x20ba18
|
||||
#define JEDEC_ID_WINBOND_W25Q128 0xEF4018
|
||||
|
@ -161,6 +163,10 @@ static bool m25p16_readIdentification()
|
|||
geometry.sectors = 32;
|
||||
geometry.pagesPerSector = 256;
|
||||
break;
|
||||
case JEDEC_ID_MACRONIX_MX25L3206E:
|
||||
geometry.sectors = 64;
|
||||
geometry.pagesPerSector = 256;
|
||||
break;
|
||||
case JEDEC_ID_MICRON_N25Q064:
|
||||
case JEDEC_ID_WINBOND_W25Q64:
|
||||
case JEDEC_ID_MACRONIX_MX25L6406E:
|
||||
|
@ -196,12 +202,27 @@ static bool m25p16_readIdentification()
|
|||
* Attempts to detect a connected m25p16. If found, true is returned and device capacity can be fetched with
|
||||
* m25p16_getGeometry().
|
||||
*/
|
||||
bool m25p16_init()
|
||||
bool m25p16_init(ioTag_t csTag)
|
||||
{
|
||||
|
||||
#ifdef M25P16_CS_PIN
|
||||
m25p16CsPin = IOGetByTag(IO_TAG(M25P16_CS_PIN));
|
||||
/*
|
||||
if we have already detected a flash device we can simply exit
|
||||
|
||||
TODO: change the init param in favour of flash CFG when ParamGroups work is done
|
||||
then cs pin can be specified in hardware_revision.c or config.c (dependent on revision).
|
||||
*/
|
||||
if (geometry.sectors) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (csTag) {
|
||||
m25p16CsPin = IOGetByTag(csTag);
|
||||
} else {
|
||||
#ifdef M25P16_CS_PIN
|
||||
m25p16CsPin = IOGetByTag(IO_TAG(M25P16_CS_PIN));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
IOInit(m25p16CsPin, OWNER_FLASH, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(m25p16CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "flash.h"
|
||||
#include "io_types.h"
|
||||
|
||||
#define M25P16_PAGESIZE 256
|
||||
|
||||
bool m25p16_init();
|
||||
bool m25p16_init(ioTag_t csTag);
|
||||
|
||||
void m25p16_eraseSector(uint32_t address);
|
||||
void m25p16_eraseCompletely();
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/accgyro.h"
|
||||
#include "drivers/gyro_sync.h"
|
||||
#include "sensor.h"
|
||||
#include "accgyro.h"
|
||||
#include "gyro_sync.h"
|
||||
|
||||
static uint8_t mpuDividerDrops;
|
||||
|
||||
|
|
|
@ -20,18 +20,23 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef INVERTER
|
||||
#ifdef INVERTER
|
||||
|
||||
#include "io.h"
|
||||
#include "io_impl.h"
|
||||
|
||||
#include "inverter.h"
|
||||
|
||||
static const IO_t pin = DEFIO_IO(INVERTER);
|
||||
/*
|
||||
TODO: move this to support multiple inverters on different UARTs etc
|
||||
possibly move to put it in the UART driver itself.
|
||||
*/
|
||||
static IO_t pin = IO_NONE;
|
||||
|
||||
void initInverter(void)
|
||||
{
|
||||
IOInit(pin, OWNER_INVERTER, RESOURCE_OUTPUT, 0);
|
||||
pin = IOGetByTag(IO_TAG(INVERTER));
|
||||
IOInit(pin, OWNER_INVERTER, RESOURCE_OUTPUT, 1);
|
||||
IOConfigGPIO(pin, IOCFG_OUT_PP);
|
||||
|
||||
inverterSet(false);
|
||||
|
|
|
@ -28,5 +28,3 @@ void inverterSet(bool on);
|
|||
|
||||
void initInverter(void);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -54,18 +54,17 @@ const struct ioPortDef_s ioPortDefs[] = {
|
|||
# endif
|
||||
|
||||
const char * const ownerNames[OWNER_TOTAL_COUNT] = {
|
||||
"FREE", "PWM", "PPM", "MOTOR", "SERVO", "SOFTSERIAL", "ADC", "SERIAL", "DEBUG", "TIMER",
|
||||
"SONAR", "SYSTEM", "SPI", "I2C", "SDCARD", "FLASH", "USB", "BEEPER", "OSD",
|
||||
"BARO", "MPU", "INVERTER", "LED STRIP", "LED", "RECEIVER", "TRANSMITTER"
|
||||
"FREE", "PWM", "PPM", "MOTOR", "SERVO", "SOFTSERIAL", "ADC", "SERIAL", "DEBUG", "TIMER",
|
||||
"SONAR", "SYSTEM", "SPI", "I2C", "SDCARD", "FLASH", "USB", "BEEPER", "OSD",
|
||||
"BARO", "MPU", "INVERTER", "LED STRIP", "LED", "RECEIVER", "TRANSMITTER"
|
||||
};
|
||||
|
||||
const char * const resourceNames[RESOURCE_TOTAL_COUNT] = {
|
||||
"", // NONE
|
||||
"IN", "OUT", "IN / OUT", "TIMER","UART TX","UART RX","UART TX/RX","EXTI","SCL",
|
||||
"", // NONE
|
||||
"IN", "OUT", "IN / OUT", "TIMER","UART TX","UART RX","UART TX/RX","EXTI","SCL",
|
||||
"SDA", "SCK","MOSI","MISO","CS","BATTERY","RSSI","EXT","CURRENT"
|
||||
};
|
||||
|
||||
|
||||
ioRec_t* IO_Rec(IO_t io)
|
||||
{
|
||||
return io;
|
||||
|
@ -207,8 +206,8 @@ void IOInit(IO_t io, resourceOwner_t owner, resourceType_t resource, uint8_t ind
|
|||
{
|
||||
ioRec_t *ioRec = IO_Rec(io);
|
||||
ioRec->owner = owner;
|
||||
ioRec->resource = resource;
|
||||
ioRec->index = index;
|
||||
ioRec->resource = resource;
|
||||
ioRec->index = index;
|
||||
}
|
||||
|
||||
void IORelease(IO_t io)
|
||||
|
|
|
@ -6,13 +6,7 @@
|
|||
#include <platform.h>
|
||||
#include "resource.h"
|
||||
|
||||
// IO pin identification
|
||||
// make sure that ioTag_t can't be assigned into IO_t without warning
|
||||
typedef uint8_t ioTag_t; // packet tag to specify IO pin
|
||||
typedef void* IO_t; // type specifying IO pin. Currently ioRec_t pointer, but this may change
|
||||
|
||||
// NONE initializer for IO_t variable
|
||||
#define IO_NONE ((IO_t)0)
|
||||
#include "io_types.h"
|
||||
|
||||
// preprocessor is used to convert pinid to requested C data value
|
||||
// compile-time error is generated if requested pin is not available (not set in TARGET_IO_PORTx)
|
||||
|
@ -21,19 +15,6 @@ typedef void* IO_t; // type specifying IO pin. Currently ioRec_t poin
|
|||
// expand pinid to to ioTag_t
|
||||
#define IO_TAG(pinid) DEFIO_TAG(pinid)
|
||||
|
||||
// both ioTag_t and IO_t are guarantied to be zero if pinid is NONE (no pin)
|
||||
// this simplifies initialization (globals are zeroed on start) and allows
|
||||
// omitting unused fields in structure initializers.
|
||||
// it is also possible to use IO_t and ioTag_t as boolean value
|
||||
// TODO - this may conflict with requirement to generate warning/error on IO_t - ioTag_t assignment
|
||||
// IO_t being pointer is only possibility I know of ..
|
||||
|
||||
// pin config handling
|
||||
// pin config is packed into ioConfig_t to decrease memory requirements
|
||||
// IOCFG_x macros are defined for common combinations for all CPUs; this
|
||||
// helps masking CPU differences
|
||||
|
||||
typedef uint8_t ioConfig_t; // packed IO configuration
|
||||
#if defined(STM32F1)
|
||||
|
||||
// mode is using only bits 6-2
|
||||
|
@ -52,7 +33,7 @@ typedef uint8_t ioConfig_t; // packed IO configuration
|
|||
#define IO_CONFIG(mode, speed, otype, pupd) ((mode) | ((speed) << 2) | ((otype) << 4) | ((pupd) << 5))
|
||||
|
||||
#define IOCFG_OUT_PP IO_CONFIG(GPIO_Mode_OUT, 0, GPIO_OType_PP, GPIO_PuPd_NOPULL) // TODO
|
||||
#define IOCFG_OUT_PP_25 IO_CONFIG(GPIO_Mode_OUT, GPIO_Speed_25MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
|
||||
#define IOCFG_OUT_PP_25 IO_CONFIG(GPIO_Mode_OUT, GPIO_Speed_25MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
|
||||
#define IOCFG_OUT_OD IO_CONFIG(GPIO_Mode_OUT, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL)
|
||||
#define IOCFG_AF_PP IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_PP, GPIO_PuPd_NOPULL)
|
||||
#define IOCFG_AF_PP_PD IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_PP, GPIO_PuPd_DOWN)
|
||||
|
|
|
@ -12,7 +12,7 @@ typedef struct ioRec_s {
|
|||
GPIO_TypeDef *gpio;
|
||||
uint16_t pin;
|
||||
resourceOwner_t owner;
|
||||
resourceType_t resource;
|
||||
resourceType_t resource;
|
||||
uint8_t index;
|
||||
} ioRec_t;
|
||||
|
||||
|
@ -26,7 +26,7 @@ int IO_GPIO_PortSource(IO_t io);
|
|||
|
||||
#if defined(STM32F3) || defined(STM32F4)
|
||||
int IO_EXTI_PortSourceGPIO(IO_t io);
|
||||
int IO_EXTI_PinSource(IO_t io);
|
||||
int IO_EXTI_PinSource(IO_t io);
|
||||
#endif
|
||||
|
||||
GPIO_TypeDef* IO_GPIO(IO_t io);
|
||||
|
|
28
src/main/drivers/io_types.h
Normal file
28
src/main/drivers/io_types.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// IO pin identification
|
||||
// make sure that ioTag_t can't be assigned into IO_t without warning
|
||||
typedef uint8_t ioTag_t; // packet tag to specify IO pin
|
||||
typedef void* IO_t; // type specifying IO pin. Currently ioRec_t pointer, but this may change
|
||||
|
||||
// NONE initializer for ioTag_t variables
|
||||
#define IOTAG_NONE ((ioTag_t)0)
|
||||
|
||||
// NONE initializer for IO_t variable
|
||||
#define IO_NONE ((IO_t)0)
|
||||
|
||||
// both ioTag_t and IO_t are guarantied to be zero if pinid is NONE (no pin)
|
||||
// this simplifies initialization (globals are zeroed on start) and allows
|
||||
// omitting unused fields in structure initializers.
|
||||
// it is also possible to use IO_t and ioTag_t as boolean value
|
||||
// TODO - this may conflict with requirement to generate warning/error on IO_t - ioTag_t assignment
|
||||
// IO_t being pointer is only possibility I know of ..
|
||||
|
||||
// pin config handling
|
||||
// pin config is packed into ioConfig_t to decrease memory requirements
|
||||
// IOCFG_x macros are defined for common combinations for all CPUs; this
|
||||
// helps masking CPU differences
|
||||
|
||||
typedef uint8_t ioConfig_t; // packed IO configuration
|
|
@ -27,12 +27,12 @@ static const IO_t leds[] = {
|
|||
DEFIO_IO(LED0),
|
||||
#else
|
||||
DEFIO_IO(NONE),
|
||||
#endif
|
||||
#endif
|
||||
#ifdef LED1
|
||||
DEFIO_IO(LED1),
|
||||
#else
|
||||
DEFIO_IO(NONE),
|
||||
#endif
|
||||
#endif
|
||||
#ifdef LED2
|
||||
DEFIO_IO(LED2),
|
||||
#else
|
||||
|
@ -78,15 +78,14 @@ uint8_t ledPolarity = 0
|
|||
#endif
|
||||
;
|
||||
|
||||
uint8_t ledOffset = 0;
|
||||
static uint8_t ledOffset = 0;
|
||||
|
||||
void ledInit(bool alternative_led)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
#if defined(LED0_A) || defined(LED1_A) || defined(LED2_A)
|
||||
if (alternative_led)
|
||||
if (alternative_led) {
|
||||
ledOffset = LED_NUMBER;
|
||||
}
|
||||
#else
|
||||
UNUSED(alternative_led);
|
||||
#endif
|
||||
|
@ -95,7 +94,7 @@ void ledInit(bool alternative_led)
|
|||
LED1_OFF;
|
||||
LED2_OFF;
|
||||
|
||||
for (i = 0; i < LED_NUMBER; i++) {
|
||||
for (int i = 0; i < LED_NUMBER; i++) {
|
||||
if (leds[i + ledOffset]) {
|
||||
IOInit(leds[i + ledOffset], OWNER_LED, RESOURCE_OUTPUT, RESOURCE_INDEX(i));
|
||||
IOConfigGPIO(leds[i + ledOffset], IOCFG_OUT_PP);
|
||||
|
@ -114,6 +113,6 @@ void ledToggle(int led)
|
|||
|
||||
void ledSet(int led, bool on)
|
||||
{
|
||||
bool inverted = (1 << (led + ledOffset)) & ledPolarity;
|
||||
const bool inverted = (1 << (led + ledOffset)) & ledPolarity;
|
||||
IOWrite(leds[led + ledOffset], on ? inverted : !inverted);
|
||||
}
|
||||
|
|
|
@ -30,16 +30,20 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "common/color.h"
|
||||
#include "common/colorconversion.h"
|
||||
#include "drivers/dma.h"
|
||||
#include "drivers/light_ws2811strip.h"
|
||||
|
||||
#ifdef LED_STRIP
|
||||
#include "dma.h"
|
||||
#include "light_ws2811strip.h"
|
||||
|
||||
#if defined(STM32F4)
|
||||
uint32_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE];
|
||||
#else
|
||||
uint8_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE];
|
||||
#endif
|
||||
volatile uint8_t ws2811LedDataTransferInProgress = 0;
|
||||
|
||||
static hsvColor_t ledColorBuffer[WS2811_LED_STRIP_LENGTH];
|
||||
|
|
|
@ -51,8 +51,9 @@ void setStripColors(const hsvColor_t *colors);
|
|||
|
||||
bool isWS2811LedStripReady(void);
|
||||
|
||||
#if defined(STM32F4)
|
||||
extern uint32_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE];
|
||||
#else
|
||||
extern uint8_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE];
|
||||
#endif
|
||||
extern volatile uint8_t ws2811LedDataTransferInProgress;
|
||||
|
||||
extern const hsvColor_t hsv_white;
|
||||
extern const hsvColor_t hsv_black;
|
||||
|
|
|
@ -20,15 +20,16 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#include "common/color.h"
|
||||
#include "drivers/light_ws2811strip.h"
|
||||
#include "light_ws2811strip.h"
|
||||
#include "nvic.h"
|
||||
#include "io.h"
|
||||
#include "dma.h"
|
||||
#include "rcc.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef LED_STRIP
|
||||
|
||||
static IO_t ws2811IO = IO_NONE;
|
||||
bool ws2811Initialised = false;
|
||||
|
||||
|
@ -105,6 +106,7 @@ void ws2811LedStripHardwareInit(void)
|
|||
|
||||
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
|
||||
|
||||
const hsvColor_t hsv_white = { 0, 255, 255};
|
||||
ws2811Initialised = true;
|
||||
setStripColor(&hsv_white);
|
||||
ws2811UpdateStrip();
|
||||
|
|
|
@ -20,17 +20,17 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#include "io.h"
|
||||
#include "nvic.h"
|
||||
|
||||
#include "common/color.h"
|
||||
#include "drivers/light_ws2811strip.h"
|
||||
#include "light_ws2811strip.h"
|
||||
#include "dma.h"
|
||||
#include "rcc.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#ifndef WS2811_PIN
|
||||
#define WS2811_PIN PB8 // TIM16_CH1
|
||||
#define WS2811_TIMER TIM16
|
||||
|
@ -111,6 +111,7 @@ void ws2811LedStripHardwareInit(void)
|
|||
|
||||
DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE);
|
||||
|
||||
const hsvColor_t hsv_white = { 0, 255, 255};
|
||||
ws2811Initialised = true;
|
||||
setStripColor(&hsv_white);
|
||||
ws2811UpdateStrip();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#include "common/color.h"
|
||||
#include "light_ws2811strip.h"
|
||||
#include "nvic.h"
|
||||
|
@ -29,10 +31,8 @@
|
|||
#include "rcc.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#if !defined(WS2811_PIN)
|
||||
#define WS2811_PIN PA0
|
||||
#if !defined(WS2811_PIN)
|
||||
#define WS2811_PIN PA0
|
||||
#define WS2811_TIMER TIM5
|
||||
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
|
||||
#define WS2811_DMA_STREAM DMA1_Stream2
|
||||
|
@ -50,7 +50,7 @@ static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
|
|||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
||||
ws2811LedDataTransferInProgress = 0;
|
||||
DMA_Cmd(descriptor->stream, DISABLE);
|
||||
TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE);
|
||||
TIM_DMACmd(WS2811_TIMER, timDMASource, DISABLE);
|
||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,7 @@ void ws2811LedStripHardwareInit(void)
|
|||
|
||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
||||
|
||||
const hsvColor_t hsv_white = { 0, 255, 255};
|
||||
ws2811Initialised = true;
|
||||
setStripColor(&hsv_white);
|
||||
ws2811UpdateStrip();
|
||||
|
|
35
src/main/drivers/max7456.c
Normal file → Executable file
35
src/main/drivers/max7456.c
Normal file → Executable file
|
@ -19,16 +19,17 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef USE_MAX7456
|
||||
|
||||
#include "common/printf.h"
|
||||
#include "drivers/bus_spi.h"
|
||||
#include "drivers/light_led.h"
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/nvic.h"
|
||||
#include "drivers/dma.h"
|
||||
|
||||
#include "bus_spi.h"
|
||||
#include "light_led.h"
|
||||
#include "io.h"
|
||||
#include "system.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
|
||||
#include "max7456.h"
|
||||
#include "max7456_symbols.h"
|
||||
|
@ -75,6 +76,7 @@ static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_s
|
|||
#endif
|
||||
|
||||
// Common to both channels
|
||||
DMA_StructInit(&DMA_InitStructure);
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(MAX7456_SPI_INSTANCE->DR));
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
|
@ -82,22 +84,31 @@ static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_s
|
|||
DMA_InitStructure.DMA_BufferSize = buffer_size;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
|
||||
#ifdef MAX7456_DMA_CHANNEL_RX
|
||||
// Rx Channel
|
||||
#ifdef STM32F4
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = rx_buffer ? (uint32_t)rx_buffer : (uint32_t)(dummy);
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
|
||||
#else
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = rx_buffer ? (uint32_t)rx_buffer : (uint32_t)(dummy);
|
||||
DMA_InitStructure.DMA_MemoryInc = rx_buffer ? DMA_MemoryInc_Enable : DMA_MemoryInc_Disable;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||||
#endif
|
||||
DMA_InitStructure.DMA_MemoryInc = rx_buffer ? DMA_MemoryInc_Enable : DMA_MemoryInc_Disable;
|
||||
|
||||
DMA_Init(MAX7456_DMA_CHANNEL_RX, &DMA_InitStructure);
|
||||
DMA_Cmd(MAX7456_DMA_CHANNEL_RX, ENABLE);
|
||||
#endif
|
||||
// Tx channel
|
||||
|
||||
#ifdef STM32F4
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)tx_buffer; //max7456_screen;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||
#else
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tx_buffer; //max7456_screen;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||
#endif
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
|
||||
DMA_Init(MAX7456_DMA_CHANNEL_TX, &DMA_InitStructure);
|
||||
DMA_Cmd(MAX7456_DMA_CHANNEL_TX, ENABLE);
|
||||
|
@ -147,7 +158,7 @@ void max7456_dma_irq_handler(dmaChannelDescriptor_t* descriptor) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void max7456_init(uint8_t video_system)
|
||||
void max7456_init(uint8_t video_system)
|
||||
{
|
||||
uint8_t max_screen_rows;
|
||||
uint8_t srdata = 0;
|
||||
|
@ -247,7 +258,7 @@ void max7456_draw_screen(void) {
|
|||
max7456_send(MAX7456ADD_DMM, 1);
|
||||
for (xx = 0; xx < max_screen_size; ++xx) {
|
||||
max7456_send(MAX7456ADD_DMDI, SCREEN_BUFFER[xx]);
|
||||
SCREEN_BUFFER[xx] = MAX7456_CHAR(0);
|
||||
SCREEN_BUFFER[xx] = MAX7456_CHAR(' ');
|
||||
}
|
||||
max7456_send(MAX7456ADD_DMDI, 0xFF);
|
||||
max7456_send(MAX7456ADD_DMM, 0);
|
||||
|
@ -286,7 +297,7 @@ void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) {
|
|||
max7456_send(MAX7456ADD_CMM, WRITE_NVR);
|
||||
|
||||
// wait until bit 5 in the status register returns to 0 (12ms)
|
||||
while ((spiTransferByte(MAX7456_SPI_INSTANCE, MAX7456ADD_STAT) & STATUS_REG_NVR_BUSY) != 0);
|
||||
while ((max7456_send(MAX7456ADD_STAT, 0) & STATUS_REG_NVR_BUSY) != 0x00);
|
||||
|
||||
max7456_send(VM0_REG, video_signal_type | 0x0C);
|
||||
DISABLE_MAX7456;
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
// Voltage and amperage
|
||||
#define SYM_VOLT 0x06
|
||||
#define SYM_AMP 0x9A
|
||||
#define SYM_MAH 0xA4
|
||||
#define SYM_MAH 0x07
|
||||
#define SYM_WATT 0x57
|
||||
|
||||
// Flying Mode
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
#include "pwm_rx.h"
|
||||
#include "pwm_mapping.h"
|
||||
|
||||
void pwmBrushedMotorConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, uint16_t motorPwmRate);
|
||||
void pwmBrushlessMotorConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, uint16_t motorPwmRate, uint16_t idlePulse);
|
||||
void pwmFastPwmMotorConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, uint8_t fastPwmProtocolType, uint16_t motorPwmRate, uint16_t idlePulse);
|
||||
void pwmServoConfig(const timerHardware_t *timerHardware, uint8_t servoIndex, uint16_t servoPwmRate, uint16_t servoCenterPulse);
|
||||
|
||||
/*
|
||||
Configuration maps
|
||||
|
||||
|
@ -94,14 +89,16 @@ pwmOutputConfiguration_t *pwmGetOutputConfiguration(void)
|
|||
|
||||
pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
||||
{
|
||||
int i = 0;
|
||||
const uint16_t *setup;
|
||||
|
||||
#ifndef SKIP_RX_PWM_PPM
|
||||
int channelIndex = 0;
|
||||
#endif
|
||||
|
||||
memset(&pwmOutputConfiguration, 0, sizeof(pwmOutputConfiguration));
|
||||
|
||||
|
||||
// this is pretty hacky shit, but it will do for now. array of 4 config maps, [ multiPWM multiPPM airPWM airPPM ]
|
||||
int i = 0;
|
||||
if (init->airplane)
|
||||
i = 2; // switch to air hardware config
|
||||
if (init->usePPM || init->useSerialRx)
|
||||
|
@ -112,7 +109,7 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
#else
|
||||
setup = hardwareMaps[i];
|
||||
#endif
|
||||
|
||||
TIM_TypeDef* ppmTimer = NULL;
|
||||
for (i = 0; i < USABLE_TIMER_CHANNEL_COUNT && setup[i] != 0xFFFF; i++) {
|
||||
uint8_t timerIndex = setup[i] & 0x00FF;
|
||||
uint8_t type = (setup[i] & 0xFF00) >> 8;
|
||||
|
@ -165,13 +162,13 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef RSSI_ADC_GPIO
|
||||
#ifdef RSSI_ADC_PIN
|
||||
if (init->useRSSIADC && timerHardwarePtr->tag == IO_TAG(RSSI_ADC_PIN)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CURRENT_METER_ADC_GPIO
|
||||
#ifdef CURRENT_METER_ADC_PIN
|
||||
if (init->useCurrentMeterADC && timerHardwarePtr->tag == IO_TAG(CURRENT_METER_ADC_PIN)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -180,8 +177,8 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
#ifdef SONAR
|
||||
if (init->useSonar &&
|
||||
(
|
||||
timerHardwarePtr->tag == init->sonarConfig.triggerTag ||
|
||||
timerHardwarePtr->tag == init->sonarConfig.echoTag
|
||||
timerHardwarePtr->tag == init->sonarIOConfig.triggerTag ||
|
||||
timerHardwarePtr->tag == init->sonarIOConfig.echoTag
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -238,6 +235,19 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
type = MAP_TO_SERVO_OUTPUT;
|
||||
#endif
|
||||
|
||||
#if defined(RCEXPLORERF3)
|
||||
if (timerIndex == PWM2)
|
||||
{
|
||||
type = MAP_TO_SERVO_OUTPUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SPRACINGF3EVO)
|
||||
// remap PWM6+7 as servos
|
||||
if ((timerIndex == PWM8 || timerIndex == PWM9) && timerHardwarePtr->tim == TIM3)
|
||||
type = MAP_TO_SERVO_OUTPUT;
|
||||
#endif
|
||||
|
||||
#if (defined(STM32F3DISCOVERY) && !defined(CHEBUZZF3))
|
||||
// remap PWM 5+6 or 9+10 as servos - softserial pin pairs require timer ports that use the same timer
|
||||
if (init->useSoftSerial) {
|
||||
|
@ -265,7 +275,7 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
if (init->useChannelForwarding && !init->airplane) {
|
||||
#if defined(NAZE) && defined(WS2811_TIMER)
|
||||
// if LED strip is active, PWM5-8 are unavailable, so map AUX1+AUX2 to PWM13+PWM14
|
||||
if (init->useLEDStrip) {
|
||||
if (init->useLEDStrip) {
|
||||
if (timerIndex >= PWM13 && timerIndex <= PWM14) {
|
||||
type = MAP_TO_SERVO_OUTPUT;
|
||||
}
|
||||
|
@ -294,33 +304,42 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
#endif
|
||||
|
||||
if (type == MAP_TO_PPM_INPUT) {
|
||||
#if defined(SPARKY) || defined(ALIENFLIGHTF3)
|
||||
if (init->useFastPwm || init->pwmProtocolType == PWM_TYPE_BRUSHED) {
|
||||
ppmAvoidPWMTimerClash(timerHardwarePtr, TIM2);
|
||||
}
|
||||
#endif
|
||||
#ifndef SKIP_RX_PWM_PPM
|
||||
ppmTimer = timerHardwarePtr->tim;
|
||||
ppmInConfig(timerHardwarePtr);
|
||||
#endif
|
||||
} else if (type == MAP_TO_PWM_INPUT) {
|
||||
#ifndef SKIP_RX_PWM_PPM
|
||||
pwmInConfig(timerHardwarePtr, channelIndex);
|
||||
channelIndex++;
|
||||
#endif
|
||||
} else if (type == MAP_TO_MOTOR_OUTPUT) {
|
||||
|
||||
// Check if we already configured maximum supported number of motors or output ports and skip the rest
|
||||
if (pwmOutputConfiguration.motorCount >= MAX_MOTORS || pwmOutputConfiguration.outputCount >= MAX_PWM_OUTPUT_PORTS) {
|
||||
continue;
|
||||
}
|
||||
#ifdef CC3D
|
||||
if (init->useFastPwm || init->pwmProtocolType == PWM_TYPE_BRUSHED) {
|
||||
if (!(init->pwmProtocolType == PWM_TYPE_CONVENTIONAL)) {
|
||||
// Skip it if it would cause PPM capture timer to be reconfigured or manually overflowed
|
||||
if (timerHardwarePtr->tim == TIM2)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (init->usePPM) {
|
||||
if (init->pwmProtocolType != PWM_TYPE_CONVENTIONAL && timerHardwarePtr->tim == ppmTimer) {
|
||||
ppmAvoidPWMTimerClash(timerHardwarePtr, ppmTimer, init->pwmProtocolType);
|
||||
}
|
||||
}
|
||||
|
||||
if (init->useFastPwm) {
|
||||
pwmFastPwmMotorConfig(timerHardwarePtr, pwmOutputConfiguration.motorCount, init->pwmProtocolType, init->motorPwmRate, init->idlePulse);
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_MOTOR | PWM_PF_OUTPUT_PROTOCOL_ONESHOT|PWM_PF_OUTPUT_PROTOCOL_PWM ;
|
||||
pwmFastPwmMotorConfig(timerHardwarePtr, pwmOutputConfiguration.motorCount, init->motorPwmRate, init->idlePulse, init->pwmProtocolType);
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_MOTOR | PWM_PF_OUTPUT_PROTOCOL_PWM | PWM_PF_OUTPUT_PROTOCOL_ONESHOT;
|
||||
} else if (init->pwmProtocolType == PWM_TYPE_BRUSHED) {
|
||||
pwmBrushedMotorConfig(timerHardwarePtr, pwmOutputConfiguration.motorCount, init->motorPwmRate);
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_MOTOR | PWM_PF_MOTOR_MODE_BRUSHED | PWM_PF_OUTPUT_PROTOCOL_PWM;
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_MOTOR | PWM_PF_OUTPUT_PROTOCOL_PWM | PWM_PF_MOTOR_MODE_BRUSHED;
|
||||
} else {
|
||||
pwmBrushlessMotorConfig(timerHardwarePtr, pwmOutputConfiguration.motorCount, init->motorPwmRate, init->idlePulse);
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_MOTOR | PWM_PF_OUTPUT_PROTOCOL_PWM ;
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_MOTOR | PWM_PF_OUTPUT_PROTOCOL_PWM;
|
||||
}
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].index = pwmOutputConfiguration.motorCount;
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].timerHardware = timerHardwarePtr;
|
||||
|
@ -328,6 +347,9 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
pwmOutputConfiguration.outputCount++;
|
||||
} else if (type == MAP_TO_SERVO_OUTPUT) {
|
||||
#ifdef USE_SERVOS
|
||||
if (pwmOutputConfiguration.servoCount >= MAX_SERVOS || pwmOutputConfiguration.outputCount >= MAX_PWM_OUTPUT_PORTS) {
|
||||
continue;
|
||||
}
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].index = pwmOutputConfiguration.servoCount;
|
||||
pwmServoConfig(timerHardwarePtr, pwmOutputConfiguration.servoCount, init->servoPwmRate, init->servoCenterPulse);
|
||||
pwmOutputConfiguration.portConfigurations[pwmOutputConfiguration.outputCount].flags = PWM_PF_SERVO | PWM_PF_OUTPUT_PROTOCOL_PWM;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue