diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..020bed7 Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3314159..d233804 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,7 +4,7 @@ name: Build and Deploy Docs # events but only for the master branch on: push: - branches: + branches: - main workflow_dispatch: @@ -20,9 +20,9 @@ jobs: with: submodulePath: ./docs/doxygen-awesome-css - name: Generate Documentation - uses: mattnotmitt/doxygen-action@v1.9.5 + uses: mattnotmitt/doxygen-action@edge with: - doxyfile-path: 'docs/Doxyfile' + doxyfile-path: "docs/Doxyfile" - name: Deploy uses: JamesIves/github-pages-deploy-action@v4.4.3 with: diff --git a/.gitignore b/.gitignore index 695a24e..a670baf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,5 @@ temp.errors *.ini .d/ -**/.DS_Store - docs-output/ -**/__pycache__/ \ No newline at end of file +.DS_STORE \ No newline at end of file diff --git a/README.md b/README.md index 93eb70b..33904d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # robodash -Robodash is a flexible GUI toolkit for the VEX V5 brain. It is built to provide -useful tools that take full advantage of the V5 brain's LCD display, as well as -provide a foundation to improve compatibility with templates that provide -LVGL-powered GUIs. +Robodash is a GUI toolkit for the VEX V5 brain intended to provide tools that +take full advantage of the V5 brain's LCD display, as well as provide a +foundation to improve compatibility with templates that provide LVGL-powered +GUIs. + +Get started with robodash by reading +[the docs](https://unwieldycat.github.io/robodash/). diff --git a/common.mk b/common.mk index 81dd93c..33efe87 100644 --- a/common.mk +++ b/common.mk @@ -1,317 +1,308 @@ -ARCHTUPLE=arm-none-eabi- -DEVICE=VEX EDR V5 - -MFLAGS=-mcpu=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=softfp -Os -g -CPPFLAGS=-D_POSIX_THREADS -D_UNIX98_THREAD_MUTEX_ATTRIBUTES -D_POSIX_TIMERS -D_POSIX_MONOTONIC_CLOCK -GCCFLAGS=-ffunction-sections -fdata-sections -fdiagnostics-color -funwind-tables - -# Check if the llemu files in libvgl exist. If they do, define macros that the -# llemu headers in the kernel repo can use to conditionally include the libvgl -# versions -ifneq (,$(wildcard ./include/liblvgl/llemu.h)) - CPPFLAGS += -D_PROS_INCLUDE_LIBLVGL_LLEMU_H -endif -ifneq (,$(wildcard ./include/liblvgl/llemu.hpp)) - CPPFLAGS += -D_PROS_INCLUDE_LIBLVGL_LLEMU_HPP -endif - -WARNFLAGS+=-Wno-psabi - -SPACE := $() $() -COMMA := , - -C_STANDARD?=gnu11 -CXX_STANDARD?=gnu++20 - -DEPDIR := .d -$(shell mkdir -p $(DEPDIR)) -DEPFLAGS = -MT $$@ -MMD -MP -MF $(DEPDIR)/$$*.Td -MAKEDEPFOLDER = -$(VV)mkdir -p $(DEPDIR)/$$(dir $$(patsubst $(BINDIR)/%, %, $(ROOT)/$$@)) -RENAMEDEPENDENCYFILE = -$(VV)mv -f $(DEPDIR)/$$*.Td $$(patsubst $(SRCDIR)/%, $(DEPDIR)/%.d, $(ROOT)/$$<) && touch $$@ - -LIBRARIES+=$(wildcard $(FWDIR)/*.a) -# Cannot include newlib and libc because not all of the req'd stubs are implemented -EXCLUDE_COLD_LIBRARIES+=$(FWDIR)/libc.a $(FWDIR)/libm.a -COLD_LIBRARIES=$(filter-out $(EXCLUDE_COLD_LIBRARIES), $(LIBRARIES)) -wlprefix=-Wl,$(subst $(SPACE),$(COMMA),$1) -LNK_FLAGS=--gc-sections --start-group $(strip $(LIBRARIES)) -lgcc -lstdc++ --end-group -T$(FWDIR)/v5-common.ld - -ASMFLAGS=$(MFLAGS) $(WARNFLAGS) -CFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=$(C_STANDARD) -CXXFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=$(CXX_STANDARD) -LDFLAGS=$(MFLAGS) $(WARNFLAGS) -nostdlib $(GCCFLAGS) -SIZEFLAGS=-d --common -NUMFMTFLAGS=--to=iec --format %.2f --suffix=B - -AR:=$(ARCHTUPLE)ar -# using arm-none-eabi-as generates a listing by default. This produces a super verbose output. -# Using gcc accomplishes the same thing without the extra output -AS:=$(ARCHTUPLE)gcc -CC:=$(ARCHTUPLE)gcc -CXX:=$(ARCHTUPLE)g++ -LD:=$(ARCHTUPLE)g++ -OBJCOPY:=$(ARCHTUPLE)objcopy -SIZETOOL:=$(ARCHTUPLE)size -READELF:=$(ARCHTUPLE)readelf -STRIP:=$(ARCHTUPLE)strip - -ifneq (, $(shell command -v gnumfmt 2> /dev/null)) - SIZES_NUMFMT:=| gnumfmt --field=-4 --header $(NUMFMTFLAGS) -else -ifneq (, $(shell command -v numfmt 2> /dev/null)) - SIZES_NUMFMT:=| numfmt --field=-4 --header $(NUMFMTFLAGS) -else - SIZES_NUMFMT:= -endif -endif - -ifneq (, $(shell command -v sed 2> /dev/null)) -SIZES_SED:=| sed -e 's/ dec/total/' -else -SIZES_SED:= -endif - -rwildcard=$(foreach d,$(filter-out $3,$(wildcard $1*)),$(call rwildcard,$d/,$2,$3)$(filter $(subst *,%,$2),$d)) - -# Colors -NO_COLOR=$(shell printf "%b" "\033[0m") -OK_COLOR=$(shell printf "%b" "\033[32;01m") -ERROR_COLOR=$(shell printf "%b" "\033[31;01m") -WARN_COLOR=$(shell printf "%b" "\033[33;01m") -STEP_COLOR=$(shell printf "%b" "\033[37;01m") -OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR) -DONE_STRING=$(OK_COLOR)[DONE]$(NO_COLOR) -ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR) -WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR) -ECHO=/bin/printf "%s\n" -echo=@$(ECHO) "$2$1$(NO_COLOR)" -echon=@/bin/printf "%s" "$2$1$(NO_COLOR)" - -define test_output_2 -@if test $(BUILD_VERBOSE) -eq $(or $4,1); then printf "%s\n" "$2"; fi; -@output="$$($2 2>&1)"; exit=$$?; \ -if test 0 -ne $$exit; then \ - printf "%s%s\n" "$1" "$(ERROR_STRING)"; \ - printf "%s\n" "$$output"; \ - exit $$exit; \ -elif test -n "$$output"; then \ - printf "%s%s\n" "$1" "$(WARN_STRING)"; \ - printf "%s\n" "$$output"; \ -else \ - printf "%s%s\n" "$1" "$3"; \ -fi; -endef - -define test_output -@output=$$($1 2>&1); exit=$$?; \ -if test 0 -ne $$exit; then \ - printf "%s\n" "$(ERROR_STRING)" $$?; \ - printf "%s\n" $$output; \ - exit $$exit; \ -elif test -n "$$output"; then \ - printf "%s\n" "$(WARN_STRING)"; \ - printf "%s" $$output; \ -else \ - printf "%s\n" "$2"; \ -fi; -endef - -# Makefile Verbosity -ifeq ("$(origin VERBOSE)", "command line") -BUILD_VERBOSE = $(VERBOSE) -endif -ifeq ("$(origin V)", "command line") -BUILD_VERBOSE = $(V) -endif - -ifndef BUILD_VERBOSE -BUILD_VERBOSE = 0 -endif - -# R is reduced (default messages) - build verbose = 0 -# V is verbose messages - verbosity = 1 -# VV is super verbose - verbosity = 2 -ifeq ($(BUILD_VERBOSE), 0) -R = @echo -D = @ -VV = @ -endif -ifeq ($(BUILD_VERBOSE), 1) -R = @echo -D = -VV = @ -endif -ifeq ($(BUILD_VERBOSE), 2) -R = -D = -VV = -endif - -INCLUDE=$(foreach dir,$(INCDIR) $(EXTRA_INCDIR),-iquote"$(dir)") - -ASMSRC=$(foreach asmext,$(ASMEXTS),$(call rwildcard, $(SRCDIR),*.$(asmext), $1)) -ASMOBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call ASMSRC,$1))) -CSRC=$(foreach cext,$(CEXTS),$(call rwildcard, $(SRCDIR),*.$(cext), $1)) -COBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call CSRC, $1))) -CXXSRC=$(foreach cxxext,$(CXXEXTS),$(call rwildcard, $(SRCDIR),*.$(cxxext), $1)) -CXXOBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call CXXSRC,$1))) - -GETALLOBJ=$(sort $(call ASMOBJ,$1) $(call COBJ,$1) $(call CXXOBJ,$1)) - -ARCHIVE_TEXT_LIST=$(subst $(SPACE),$(COMMA),$(notdir $(basename $(LIBRARIES)))) - -LDTIMEOBJ:=$(BINDIR)/_pros_ld_timestamp.o - -MONOLITH_BIN:=$(BINDIR)/monolith.bin -MONOLITH_ELF:=$(basename $(MONOLITH_BIN)).elf - -HOT_BIN:=$(BINDIR)/hot.package.bin -HOT_ELF:=$(basename $(HOT_BIN)).elf -COLD_BIN:=$(BINDIR)/cold.package.bin -COLD_ELF:=$(basename $(COLD_BIN)).elf - -# Check if USE_PACKAGE is defined to check for migration steps from purduesigbots/pros#87 -ifndef USE_PACKAGE -$(error Your Makefile must be migrated! Visit https://pros.cs.purdue.edu/v5/releases/kernel3.1.6.html to learn how) -endif - -DEFAULT_BIN=$(MONOLITH_BIN) -ifeq ($(USE_PACKAGE),1) -DEFAULT_BIN=$(HOT_BIN) -endif - --include $(wildcard $(FWDIR)/*.mk) - -.PHONY: all clean quick - -quick: $(DEFAULT_BIN) - -all: clean $(DEFAULT_BIN) - -clean: - @echo Cleaning project - -$Drm -rf $(BINDIR) - -$Drm -rf $(DEPDIR) - -ifeq ($(IS_LIBRARY),1) -ifeq ($(LIBNAME),libbest) -$(errror "You should rename your library! libbest is the default library name and should be changed") -endif - -LIBAR=$(BINDIR)/$(LIBNAME).a -TEMPLATE_DIR=$(ROOT)/template - -clean-template: - @echo Cleaning $(TEMPLATE_DIR) - -$Drm -rf $(TEMPLATE_DIR) - -$(LIBAR): $(call GETALLOBJ,$(EXCLUDE_SRC_FROM_LIB)) $(EXTRA_LIB_DEPS) - -$Drm -f $@ - $(call test_output_2,Creating $@ ,$(AR) rcs $@ $^, $(DONE_STRING)) - -.PHONY: library -library: $(LIBAR) - -.PHONY: template -template: clean-template $(LIBAR) - $Dpros c create-template . $(LIBNAME) $(VERSION) $(foreach file,$(TEMPLATE_FILES) $(LIBAR),--system "$(file)") --target v5 $(CREATE_TEMPLATE_FLAGS) -endif - -# if project is a library source, compile the archive and link output.elf against the archive rather than source objects -ifeq ($(IS_LIBRARY),1) -ELF_DEPS+=$(filter-out $(call GETALLOBJ,$(EXCLUDE_SRC_FROM_LIB)), $(call GETALLOBJ,$(EXCLUDE_SRCDIRS))) -LIBRARIES+=$(LIBAR) -else -ELF_DEPS+=$(call GETALLOBJ,$(EXCLUDE_SRCDIRS)) -endif - -ASSET_OBJ=$(addprefix $(BINDIR)/, $(addsuffix .o, $(ASSET_FILES)) ) -ELF_DEPS+=$(ASSET_OBJ) - -.SECONDEXPANSION: -$(ASSET_OBJ): $$(patsubst bin/%,%,$$(basename $$@)) - $(VV)mkdir -p $(BINDIR)/static - @echo "ASSET $@" - $(VV)$(OBJCOPY) -I binary -O elf32-littlearm -B arm $^ $@ - -$(MONOLITH_BIN): $(MONOLITH_ELF) $(BINDIR) - $(call test_output_2,Creating $@ for $(DEVICE) ,$(OBJCOPY) $< -O binary -R .hot_init $@,$(DONE_STRING)) - -$(MONOLITH_ELF): $(ELF_DEPS) $(LIBRARIES) $(ASSET_OBJ) - $(call _pros_ld_timestamp) - $(call test_output_2,Linking project with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(ELF_DEPS) $(LDTIMEOBJ) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS)) -o $@,$(OK_STRING)) - @echo Section sizes: - -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) - -$(COLD_BIN): $(COLD_ELF) - $(call test_output_2,Creating cold package binary for $(DEVICE) ,$(OBJCOPY) $< -O binary -R .hot_init $@,$(DONE_STRING)) - -$(COLD_ELF): $(COLD_LIBRARIES) $(ASSET_OBJ) - $(VV)mkdir -p $(dir $@) - $(call test_output_2,Creating cold package with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(call wlprefix,--gc-keep-exported --whole-archive $^ -lstdc++ --no-whole-archive) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS) -o $@),$(OK_STRING)) - $(call test_output_2,Stripping cold package ,$(OBJCOPY) --strip-symbol=install_hot_table --strip-symbol=__libc_init_array --strip-symbol=_PROS_COMPILE_DIRECTORY --strip-symbol=_PROS_COMPILE_TIMESTAMP --strip-symbol=_PROS_COMPILE_TIMESTAMP_INT $@ $@, $(DONE_STRING)) - @echo Section sizes: - -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) - -$(HOT_BIN): $(HOT_ELF) $(COLD_BIN) - $(call test_output_2,Creating $@ for $(DEVICE) ,$(OBJCOPY) $< -O binary $@,$(DONE_STRING)) - -$(HOT_ELF): $(COLD_ELF) $(ELF_DEPS) - $(call _pros_ld_timestamp) - $(call test_output_2,Linking hot project with $(COLD_ELF) and $(ARCHIVE_TEXT_LIST) ,$(LD) -nostartfiles $(LDFLAGS) $(call wlprefix,-R $<) $(filter-out $<,$^) $(LDTIMEOBJ) $(LIBRARIES) $(call wlprefix,-T$(FWDIR)/v5-hot.ld $(LNK_FLAGS) -o $@),$(OK_STRING)) - @printf "%s\n" "Section sizes:" - -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) - -define asm_rule -$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 - $(VV)mkdir -p $$(dir $$@) - $$(call test_output_2,Compiled $$< ,$(AS) -c $(ASMFLAGS) -o $$@ $$<,$(OK_STRING)) -endef -$(foreach asmext,$(ASMEXTS),$(eval $(call asm_rule,$(asmext)))) - -define c_rule -$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 -$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 $(DEPDIR)/$(basename $1).d - $(VV)mkdir -p $$(dir $$@) - $(MAKEDEPFOLDER) - $$(call test_output_2,Compiled $$< ,$(CC) -c $(INCLUDE) -iquote"$(INCDIR)/$$(dir $$*)" $(CFLAGS) $(EXTRA_CFLAGS) $(DEPFLAGS) -o $$@ $$<,$(OK_STRING)) - $(RENAMEDEPENDENCYFILE) -endef -$(foreach cext,$(CEXTS),$(eval $(call c_rule,$(cext)))) - -define cxx_rule -$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 -$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 $(DEPDIR)/$(basename %).d - $(VV)mkdir -p $$(dir $$@) - $(MAKEDEPFOLDER) - $$(call test_output_2,Compiled $$< ,$(CXX) -c $(INCLUDE) -iquote"$(INCDIR)/$$(dir $$*)" $(CXXFLAGS) $(EXTRA_CXXFLAGS) $(DEPFLAGS) -o $$@ $$<,$(OK_STRING)) - $(RENAMEDEPENDENCYFILE) -endef -$(foreach cxxext,$(CXXEXTS),$(eval $(call cxx_rule,$(cxxext)))) - -define _pros_ld_timestamp -$(VV)mkdir -p $(dir $(LDTIMEOBJ)) -@# Pipe a line of code defining _PROS_COMPILE_TOOLSTAMP and _PROS_COMPILE_DIRECTORY into GCC, -@# which allows compilation from stdin. We define _PROS_COMPILE_DIRECTORY using a command line-defined macro -@# which is the pwd | tail bit, which will truncate the path to the last 23 characters -@# -@# const int _PROS_COMPILE_TIMESTAMP_INT = $(( $(date +%s) - $(date +%z) * 3600 )) -@# char const * const _PROS_COMPILE_TIEMSTAMP = __DATE__ " " __TIME__ -@# char const * const _PROS_COMPILE_DIRECTORY = "$(shell pwd | tail -c 23)"; -@# -@# The shell command $$(($$(date +%s)+($$(date +%-z)/100*3600))) fetches the current -@# unix timestamp, and then adds the UTC timezone offset to account for time zones. - -$(call test_output_2,Adding timestamp ,echo 'const int _PROS_COMPILE_TIMESTAMP_INT = $(shell echo $$(($$(date +%s)+($$(date +%-z)/100*3600)))); char const * const _PROS_COMPILE_TIMESTAMP = __DATE__ " " __TIME__; char const * const _PROS_COMPILE_DIRECTORY = "$(wildcard $(shell pwd | tail -c 23))";' | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) -o $(LDTIMEOBJ) -,$(OK_STRING)) -endef - -# these rules are for build-compile-commands, which just print out sysroot information -cc-sysroot: - @echo | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) --verbose -o /dev/null - -cxx-sysroot: - @echo | $(CXX) -c -x c++ $(CXXFLAGS) $(EXTRA_CXXFLAGS) --verbose -o /dev/null - - -$(DEPDIR)/%.d: ; -.PRECIOUS: $(DEPDIR)/%.d - -include $(wildcard $(patsubst $(SRCDIR)/%,$(DEPDIR)/%.d,$(CSRC) $(CXXSRC))) +ARCHTUPLE=arm-none-eabi- +DEVICE=VEX EDR V5 + +MFLAGS=-mcpu=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=softfp -Os -g +CPPFLAGS=-D_POSIX_THREADS -D_UNIX98_THREAD_MUTEX_ATTRIBUTES -D_POSIX_TIMERS -D_POSIX_MONOTONIC_CLOCK +GCCFLAGS=-ffunction-sections -fdata-sections -fdiagnostics-color -funwind-tables + +# Check if the llemu files in libvgl exist. If they do, define macros that the +# llemu headers in the kernel repo can use to conditionally include the libvgl +# versions +ifneq (,$(wildcard ./include/liblvgl/llemu.h)) + CPPFLAGS += -D_PROS_INCLUDE_LIBLVGL_LLEMU_H +endif +ifneq (,$(wildcard ./include/liblvgl/llemu.hpp)) + CPPFLAGS += -D_PROS_INCLUDE_LIBLVGL_LLEMU_HPP +endif + +WARNFLAGS+=-Wno-psabi + +SPACE := $() $() +COMMA := , + +C_STANDARD?=gnu11 +CXX_STANDARD?=gnu++20 + +DEPDIR := .d +$(shell mkdir -p $(DEPDIR)) +DEPFLAGS = -MT $$@ -MMD -MP -MF $(DEPDIR)/$$*.Td +MAKEDEPFOLDER = -$(VV)mkdir -p $(DEPDIR)/$$(dir $$(patsubst $(BINDIR)/%, %, $(ROOT)/$$@)) +RENAMEDEPENDENCYFILE = -$(VV)mv -f $(DEPDIR)/$$*.Td $$(patsubst $(SRCDIR)/%, $(DEPDIR)/%.d, $(ROOT)/$$<) && touch $$@ + +LIBRARIES+=$(wildcard $(FWDIR)/*.a) +# Cannot include newlib and libc because not all of the req'd stubs are implemented +EXCLUDE_COLD_LIBRARIES+=$(FWDIR)/libc.a $(FWDIR)/libm.a +COLD_LIBRARIES=$(filter-out $(EXCLUDE_COLD_LIBRARIES), $(LIBRARIES)) +wlprefix=-Wl,$(subst $(SPACE),$(COMMA),$1) +LNK_FLAGS=--gc-sections --start-group $(strip $(LIBRARIES)) -lgcc -lstdc++ --end-group -T$(FWDIR)/v5-common.ld + +ASMFLAGS=$(MFLAGS) $(WARNFLAGS) +CFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=$(C_STANDARD) +CXXFLAGS=$(MFLAGS) $(CPPFLAGS) $(WARNFLAGS) $(GCCFLAGS) --std=$(CXX_STANDARD) +LDFLAGS=$(MFLAGS) $(WARNFLAGS) -nostdlib $(GCCFLAGS) +SIZEFLAGS=-d --common +NUMFMTFLAGS=--to=iec --format %.2f --suffix=B + +AR:=$(ARCHTUPLE)ar +# using arm-none-eabi-as generates a listing by default. This produces a super verbose output. +# Using gcc accomplishes the same thing without the extra output +AS:=$(ARCHTUPLE)gcc +CC:=$(ARCHTUPLE)gcc +CXX:=$(ARCHTUPLE)g++ +LD:=$(ARCHTUPLE)g++ +OBJCOPY:=$(ARCHTUPLE)objcopy +SIZETOOL:=$(ARCHTUPLE)size +READELF:=$(ARCHTUPLE)readelf +STRIP:=$(ARCHTUPLE)strip + +ifneq (, $(shell command -v gnumfmt 2> /dev/null)) + SIZES_NUMFMT:=| gnumfmt --field=-4 --header $(NUMFMTFLAGS) +else +ifneq (, $(shell command -v numfmt 2> /dev/null)) + SIZES_NUMFMT:=| numfmt --field=-4 --header $(NUMFMTFLAGS) +else + SIZES_NUMFMT:= +endif +endif + +ifneq (, $(shell command -v sed 2> /dev/null)) +SIZES_SED:=| sed -e 's/ dec/total/' +else +SIZES_SED:= +endif + +rwildcard=$(foreach d,$(filter-out $3,$(wildcard $1*)),$(call rwildcard,$d/,$2,$3)$(filter $(subst *,%,$2),$d)) + +# Colors +NO_COLOR=$(shell printf "%b" "\033[0m") +OK_COLOR=$(shell printf "%b" "\033[32;01m") +ERROR_COLOR=$(shell printf "%b" "\033[31;01m") +WARN_COLOR=$(shell printf "%b" "\033[33;01m") +STEP_COLOR=$(shell printf "%b" "\033[37;01m") +OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR) +DONE_STRING=$(OK_COLOR)[DONE]$(NO_COLOR) +ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR) +WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR) +ECHO=/bin/printf "%s\n" +echo=@$(ECHO) "$2$1$(NO_COLOR)" +echon=@/bin/printf "%s" "$2$1$(NO_COLOR)" + +define test_output_2 +@if test $(BUILD_VERBOSE) -eq $(or $4,1); then printf "%s\n" "$2"; fi; +@output="$$($2 2>&1)"; exit=$$?; \ +if test 0 -ne $$exit; then \ + printf "%s%s\n" "$1" "$(ERROR_STRING)"; \ + printf "%s\n" "$$output"; \ + exit $$exit; \ +elif test -n "$$output"; then \ + printf "%s%s\n" "$1" "$(WARN_STRING)"; \ + printf "%s\n" "$$output"; \ +else \ + printf "%s%s\n" "$1" "$3"; \ +fi; +endef + +define test_output +@output=$$($1 2>&1); exit=$$?; \ +if test 0 -ne $$exit; then \ + printf "%s\n" "$(ERROR_STRING)" $$?; \ + printf "%s\n" $$output; \ + exit $$exit; \ +elif test -n "$$output"; then \ + printf "%s\n" "$(WARN_STRING)"; \ + printf "%s" $$output; \ +else \ + printf "%s\n" "$2"; \ +fi; +endef + +# Makefile Verbosity +ifeq ("$(origin VERBOSE)", "command line") +BUILD_VERBOSE = $(VERBOSE) +endif +ifeq ("$(origin V)", "command line") +BUILD_VERBOSE = $(V) +endif + +ifndef BUILD_VERBOSE +BUILD_VERBOSE = 0 +endif + +# R is reduced (default messages) - build verbose = 0 +# V is verbose messages - verbosity = 1 +# VV is super verbose - verbosity = 2 +ifeq ($(BUILD_VERBOSE), 0) +R = @echo +D = @ +VV = @ +endif +ifeq ($(BUILD_VERBOSE), 1) +R = @echo +D = +VV = @ +endif +ifeq ($(BUILD_VERBOSE), 2) +R = +D = +VV = +endif + +INCLUDE=$(foreach dir,$(INCDIR) $(EXTRA_INCDIR),-iquote"$(dir)") + +ASMSRC=$(foreach asmext,$(ASMEXTS),$(call rwildcard, $(SRCDIR),*.$(asmext), $1)) +ASMOBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call ASMSRC,$1))) +CSRC=$(foreach cext,$(CEXTS),$(call rwildcard, $(SRCDIR),*.$(cext), $1)) +COBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call CSRC, $1))) +CXXSRC=$(foreach cxxext,$(CXXEXTS),$(call rwildcard, $(SRCDIR),*.$(cxxext), $1)) +CXXOBJ=$(addprefix $(BINDIR)/,$(patsubst $(SRCDIR)/%,%.o,$(call CXXSRC,$1))) + +GETALLOBJ=$(sort $(call ASMOBJ,$1) $(call COBJ,$1) $(call CXXOBJ,$1)) + +ARCHIVE_TEXT_LIST=$(subst $(SPACE),$(COMMA),$(notdir $(basename $(LIBRARIES)))) + +LDTIMEOBJ:=$(BINDIR)/_pros_ld_timestamp.o + +MONOLITH_BIN:=$(BINDIR)/monolith.bin +MONOLITH_ELF:=$(basename $(MONOLITH_BIN)).elf + +HOT_BIN:=$(BINDIR)/hot.package.bin +HOT_ELF:=$(basename $(HOT_BIN)).elf +COLD_BIN:=$(BINDIR)/cold.package.bin +COLD_ELF:=$(basename $(COLD_BIN)).elf + +# Check if USE_PACKAGE is defined to check for migration steps from purduesigbots/pros#87 +ifndef USE_PACKAGE +$(error Your Makefile must be migrated! Visit https://pros.cs.purdue.edu/v5/releases/kernel3.1.6.html to learn how) +endif + +DEFAULT_BIN=$(MONOLITH_BIN) +ifeq ($(USE_PACKAGE),1) +DEFAULT_BIN=$(HOT_BIN) +endif + +-include $(wildcard $(FWDIR)/*.mk) + +.PHONY: all clean quick + +quick: $(DEFAULT_BIN) + +all: clean $(DEFAULT_BIN) + +clean: + @echo Cleaning project + -$Drm -rf $(BINDIR) + -$Drm -rf $(DEPDIR) + +ifeq ($(IS_LIBRARY),1) +ifeq ($(LIBNAME),libbest) +$(errror "You should rename your library! libbest is the default library name and should be changed") +endif + +LIBAR=$(BINDIR)/$(LIBNAME).a +TEMPLATE_DIR=$(ROOT)/template + +clean-template: + @echo Cleaning $(TEMPLATE_DIR) + -$Drm -rf $(TEMPLATE_DIR) + +$(LIBAR): $(call GETALLOBJ,$(EXCLUDE_SRC_FROM_LIB)) $(EXTRA_LIB_DEPS) + -$Drm -f $@ + $(call test_output_2,Creating $@ ,$(AR) rcs $@ $^, $(DONE_STRING)) + +.PHONY: library +library: $(LIBAR) + +.PHONY: template +template: clean-template $(LIBAR) + $Dpros c create-template . $(LIBNAME) $(VERSION) $(foreach file,$(TEMPLATE_FILES) $(LIBAR),--system "$(file)") --target v5 $(CREATE_TEMPLATE_FLAGS) +endif + +# if project is a library source, compile the archive and link output.elf against the archive rather than source objects +ifeq ($(IS_LIBRARY),1) +ELF_DEPS+=$(filter-out $(call GETALLOBJ,$(EXCLUDE_SRC_FROM_LIB)), $(call GETALLOBJ,$(EXCLUDE_SRCDIRS))) +LIBRARIES+=$(LIBAR) +else +ELF_DEPS+=$(call GETALLOBJ,$(EXCLUDE_SRCDIRS)) +endif + +$(MONOLITH_BIN): $(MONOLITH_ELF) $(BINDIR) + $(call test_output_2,Creating $@ for $(DEVICE) ,$(OBJCOPY) $< -O binary -R .hot_init $@,$(DONE_STRING)) + +$(MONOLITH_ELF): $(ELF_DEPS) $(LIBRARIES) + $(call _pros_ld_timestamp) + $(call test_output_2,Linking project with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(ELF_DEPS) $(LDTIMEOBJ) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS)) -o $@,$(OK_STRING)) + @echo Section sizes: + -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) + +$(COLD_BIN): $(COLD_ELF) + $(call test_output_2,Creating cold package binary for $(DEVICE) ,$(OBJCOPY) $< -O binary -R .hot_init $@,$(DONE_STRING)) + +$(COLD_ELF): $(COLD_LIBRARIES) + $(VV)mkdir -p $(dir $@) + $(call test_output_2,Creating cold package with $(ARCHIVE_TEXT_LIST) ,$(LD) $(LDFLAGS) $(call wlprefix,--gc-keep-exported --whole-archive $^ -lstdc++ --no-whole-archive) $(call wlprefix,-T$(FWDIR)/v5.ld $(LNK_FLAGS) -o $@),$(OK_STRING)) + $(call test_output_2,Stripping cold package ,$(OBJCOPY) --strip-symbol=install_hot_table --strip-symbol=__libc_init_array --strip-symbol=_PROS_COMPILE_DIRECTORY --strip-symbol=_PROS_COMPILE_TIMESTAMP --strip-symbol=_PROS_COMPILE_TIMESTAMP_INT $@ $@, $(DONE_STRING)) + @echo Section sizes: + -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) + +$(HOT_BIN): $(HOT_ELF) $(COLD_BIN) + $(call test_output_2,Creating $@ for $(DEVICE) ,$(OBJCOPY) $< -O binary $@,$(DONE_STRING)) + +$(HOT_ELF): $(COLD_ELF) $(ELF_DEPS) + $(call _pros_ld_timestamp) + $(call test_output_2,Linking hot project with $(COLD_ELF) and $(ARCHIVE_TEXT_LIST) ,$(LD) -nostartfiles $(LDFLAGS) $(call wlprefix,-R $<) $(filter-out $<,$^) $(LDTIMEOBJ) $(LIBRARIES) $(call wlprefix,-T$(FWDIR)/v5-hot.ld $(LNK_FLAGS) -o $@),$(OK_STRING)) + @printf "%s\n" "Section sizes:" + -$(VV)$(SIZETOOL) $(SIZEFLAGS) $@ $(SIZES_SED) $(SIZES_NUMFMT) + +define asm_rule +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 + $(VV)mkdir -p $$(dir $$@) + $$(call test_output_2,Compiled $$< ,$(AS) -c $(ASMFLAGS) -o $$@ $$<,$(OK_STRING)) +endef +$(foreach asmext,$(ASMEXTS),$(eval $(call asm_rule,$(asmext)))) + +define c_rule +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 $(DEPDIR)/$(basename $1).d + $(VV)mkdir -p $$(dir $$@) + $(MAKEDEPFOLDER) + $$(call test_output_2,Compiled $$< ,$(CC) -c $(INCLUDE) -iquote"$(INCDIR)/$$(dir $$*)" $(CFLAGS) $(EXTRA_CFLAGS) $(DEPFLAGS) -o $$@ $$<,$(OK_STRING)) + $(RENAMEDEPENDENCYFILE) +endef +$(foreach cext,$(CEXTS),$(eval $(call c_rule,$(cext)))) + +define cxx_rule +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 +$(BINDIR)/%.$1.o: $(SRCDIR)/%.$1 $(DEPDIR)/$(basename %).d + $(VV)mkdir -p $$(dir $$@) + $(MAKEDEPFOLDER) + $$(call test_output_2,Compiled $$< ,$(CXX) -c $(INCLUDE) -iquote"$(INCDIR)/$$(dir $$*)" $(CXXFLAGS) $(EXTRA_CXXFLAGS) $(DEPFLAGS) -o $$@ $$<,$(OK_STRING)) + $(RENAMEDEPENDENCYFILE) +endef +$(foreach cxxext,$(CXXEXTS),$(eval $(call cxx_rule,$(cxxext)))) + +define _pros_ld_timestamp +$(VV)mkdir -p $(dir $(LDTIMEOBJ)) +@# Pipe a line of code defining _PROS_COMPILE_TOOLSTAMP and _PROS_COMPILE_DIRECTORY into GCC, +@# which allows compilation from stdin. We define _PROS_COMPILE_DIRECTORY using a command line-defined macro +@# which is the pwd | tail bit, which will truncate the path to the last 23 characters +@# +@# const int _PROS_COMPILE_TIMESTAMP_INT = $(( $(date +%s) - $(date +%z) * 3600 )) +@# char const * const _PROS_COMPILE_TIEMSTAMP = __DATE__ " " __TIME__ +@# char const * const _PROS_COMPILE_DIRECTORY = "$(shell pwd | tail -c 23)"; +@# +@# The shell command $$(($$(date +%s)+($$(date +%-z)/100*3600))) fetches the current +@# unix timestamp, and then adds the UTC timezone offset to account for time zones. + +$(call test_output_2,Adding timestamp ,echo 'const int _PROS_COMPILE_TIMESTAMP_INT = $(shell echo $$(($$(date +%s)+($$(date +%-z)/100*3600)))); char const * const _PROS_COMPILE_TIMESTAMP = __DATE__ " " __TIME__; char const * const _PROS_COMPILE_DIRECTORY = "$(wildcard $(shell pwd | tail -c 23))";' | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) -o $(LDTIMEOBJ) -,$(OK_STRING)) +endef + +# these rules are for build-compile-commands, which just print out sysroot information +cc-sysroot: + @echo | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) --verbose -o /dev/null - +cxx-sysroot: + @echo | $(CXX) -c -x c++ $(CXXFLAGS) $(EXTRA_CXXFLAGS) --verbose -o /dev/null - + +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +include $(wildcard $(patsubst $(SRCDIR)/%,$(DEPDIR)/%.d,$(CSRC) $(CXXSRC))) diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..6c9628b Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/Doxyfile b/docs/Doxyfile index a1273d3..a4fa6b3 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -943,7 +943,12 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = include/robodash/ docs/pages/ README.md +INPUT = include/robodash/ \ + docs/pages/installing.md \ + docs/pages/usage.md \ + docs/pages/ui.md \ + docs/pages/ \ + README.md # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1264,7 +1269,7 @@ VERBATIM_HEADERS = YES # classes, structs, unions or interfaces. # The default value is: YES. -ALPHABETICAL_INDEX = YES +ALPHABETICAL_INDEX = NO # The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) # that should be ignored while generating the index headers. The IGNORE_PREFIX diff --git a/docs/assets/alert.png b/docs/assets/alert.png new file mode 100644 index 0000000..0203c09 Binary files /dev/null and b/docs/assets/alert.png differ diff --git a/docs/assets/alert_button.png b/docs/assets/alert_button.png new file mode 100644 index 0000000..2ac95e5 Binary files /dev/null and b/docs/assets/alert_button.png differ diff --git a/docs/assets/view_button.png b/docs/assets/view_button.png new file mode 100644 index 0000000..bc4075e Binary files /dev/null and b/docs/assets/view_button.png differ diff --git a/docs/assets/view_selector.png b/docs/assets/view_selector.png new file mode 100644 index 0000000..c32d2ad Binary files /dev/null and b/docs/assets/view_selector.png differ diff --git a/docs/doxygen-awesome-css b/docs/doxygen-awesome-css index df83fbf..df88fe4 160000 --- a/docs/doxygen-awesome-css +++ b/docs/doxygen-awesome-css @@ -1 +1 @@ -Subproject commit df83fbf22cfff76b875c13d324baf584c74e96d0 +Subproject commit df88fe4fdd97714fadfd3ef17de0b4401f804052 diff --git a/docs/pages/installing.md b/docs/pages/installing.md index 6402bd1..598fd6e 100644 --- a/docs/pages/installing.md +++ b/docs/pages/installing.md @@ -26,3 +26,11 @@ commands below in the Integrated Terminal. `pros c apply robodash@x.x.x`. 4. `#include "robodash/api.hpp"` in your project's `main.h` file + +
+ +| Previous | Next | +|:---------|--------------------:| +| | [Usage](@ref usage) | + +
diff --git a/docs/pages/ui.md b/docs/pages/ui.md new file mode 100644 index 0000000..8385098 --- /dev/null +++ b/docs/pages/ui.md @@ -0,0 +1,38 @@ +@page ui User Interface + +The user interface of robodash is designed to be minimally intrusive on the +content on screen. In the top right of the screen, no matter which view is +active, a button is present to open a pane to change the current view. + +@image html view_button.png + +Upon opening the view switcher, a list of views are displayed on the right. +Tapping on any one of these will set them as the active view, and close the +switcher UI. If you do not wish to switch the active view, you can click the X +button or tap away. + +@image html view_selector.png + +# Alerts + +Some views may encounter an error and request attention by sending an alert. +Alerts are placed front and center on screen. + +@image html alert.png + +Tapping the alert will dismiss the alert and focus the view that sent it. +Tapping away from the alert will hide the alert, where you can later view it by +clicking the bell icon to reopen the alert menu. + +@image html alert_button.png + +If multiple alerts appear, you can view the remaining ones in this menu as well. +The alert button will dissapear once all alerts are dismissed. + +
+ +| Previous | Next | +| :------------------ | ---: | +| [Usage](@ref usage) | | + +
diff --git a/docs/pages/usage.md b/docs/pages/usage.md index 33ddb6d..f9e9055 100644 --- a/docs/pages/usage.md +++ b/docs/pages/usage.md @@ -2,49 +2,57 @@ Robodash has two parts: the core, and the toolkit. -- The core library is the view management system and provides functions to - create your own views. Creating your own views requires knowledge of LVGL. - Compatible with C and C++. +- The core library is the system that enables interoperability between templates + by providing a view-management system for LVGL. This API requires knowledge of + LVGL. Compatible with C and C++. -- The toolkit is the set of provided class-based UI tools, like the autonomous - selector or console. These require no knowledge of LVGL and require minimal +- The toolkit is the set of provided class-based UI tools intended for end users + of the library. These require no knowledge of LVGL and require minimal configuration. Only compatible with C++. ## Toolkit All of the tools provided by Robodash are class-based, and are designed to be as -simple as possible to use. The following snippet utilizes the autonomous -selector and the screen console. +simple as possible to use. The following example utilizes the autonomous +selector and the on-screen console. ```cpp -rd::Selector selector; +rd::Selector selector({ + {"Auton 0", &auton0}, + {"Auton 1", &simple_auton}, + {"Skills Run", &skills} +}); + rd::Console console; void initialize() { - console.println("Adding autons..."); - - selector.add_autons({ - {"Auton 0", &auton0}, - {"Auton 1", &simple_auton}, - {"Skills Run", &skills} - }); - - console.println("Registered auton routines!"); + console.println("Initializing robot..."); + // Robot stuff would happen... } void autonomous() { console.println("Running auton..."); - selector.do_auton(); + selector.run_auton(); } ``` -You can learn more about each of the built-in tools at the topics page. +Documention for each class is linked on the topics page. ## Core -The core library is implemented in C, and is designed to be as familliar as -possible to someone already familliar with LVGL. The following is an example of -how to create a view. +The core library is the view management system for LVGL, and is designed to be +as familliar as possible to someone already familliar with LVGL. Each view, +represented by a memory pointer to an `rd_view_t`, exposes an LVGL object the +size of the view area, which can be thought of as a screen. It is very important +that any LVGL objects that are created in your template or user program are a +child of this exposed object, **NOT `lv_scr_act()`**, since robodash manages +which view is active by hiding and unhiding the object cooresponding to each +view. + +The name passed to each view will be the name that is displayed on screen in the +view switcher and any alert dialogues spawned by the view. + +The following is an example of a simple view that displays a text label. ```cpp void opcontrol() { @@ -56,3 +64,11 @@ void opcontrol() { ``` You can learn more about the core library at the @ref core page. + +
+ +| Previous | Next | +|:------------------------------|--------------------------:| +| [Installing](@ref installing) | [User Interface](@ref ui) | + +
diff --git a/firmware/liblvgl.a b/firmware/liblvgl.a index 1d4151b..6b3a68e 100644 Binary files a/firmware/liblvgl.a and b/firmware/liblvgl.a differ diff --git a/firmware/libpros.a b/firmware/libpros.a index fa074e9..ae9d587 100644 Binary files a/firmware/libpros.a and b/firmware/libpros.a differ diff --git a/include/.DS_Store b/include/.DS_Store new file mode 100644 index 0000000..479bbb2 Binary files /dev/null and b/include/.DS_Store differ diff --git a/include/api.h b/include/api.h index 5606a4a..58e58dd 100644 --- a/include/api.h +++ b/include/api.h @@ -1,84 +1,84 @@ -/** - * \file api.h - * - * PROS API header provides high-level user functionality - * - * Contains declarations for use by typical VEX programmers using PROS. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef _PROS_API_H_ -#define _PROS_API_H_ - -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#include -#include -#else /* (not) __cplusplus */ -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* __cplusplus */ - -#define PROS_VERSION_MAJOR 4 -#define PROS_VERSION_MINOR 0 -#define PROS_VERSION_PATCH 4 -#define PROS_VERSION_STRING "4.0.4" - -#include "pros/adi.h" -#include "pros/colors.h" -#include "pros/device.h" -#include "pros/distance.h" -#include "pros/error.h" -#include "pros/ext_adi.h" -#include "pros/gps.h" -#include "pros/imu.h" -#include "pros/link.h" -#include "pros/llemu.h" -#include "pros/misc.h" -#include "pros/motors.h" -#include "pros/optical.h" -#include "pros/rotation.h" -#include "pros/rtos.h" -#include "pros/screen.h" -#include "pros/vision.h" - -#ifdef __cplusplus -#include "pros/adi.hpp" -#include "pros/colors.hpp" -#include "pros/device.hpp" -#include "pros/distance.hpp" -#include "pros/gps.hpp" -#include "pros/imu.hpp" -#include "pros/link.hpp" -#include "pros/llemu.hpp" -#include "pros/misc.hpp" -#include "pros/motor_group.hpp" -#include "pros/motors.hpp" -#include "pros/optical.hpp" -#include "pros/rotation.hpp" -#include "pros/rtos.hpp" -#include "pros/screen.hpp" -#include "pros/vision.hpp" -#endif - -#endif // _PROS_API_H_ +/** + * \file api.h + * + * PROS API header provides high-level user functionality + * + * Contains declarations for use by typical VEX programmers using PROS. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_API_H_ +#define _PROS_API_H_ + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#include +#include +#else /* (not) __cplusplus */ +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* __cplusplus */ + +#define PROS_VERSION_MAJOR 4 +#define PROS_VERSION_MINOR 0 +#define PROS_VERSION_PATCH 6 +#define PROS_VERSION_STRING "4.0.6" + +#include "pros/adi.h" +#include "pros/colors.h" +#include "pros/device.h" +#include "pros/distance.h" +#include "pros/error.h" +#include "pros/ext_adi.h" +#include "pros/gps.h" +#include "pros/imu.h" +#include "pros/link.h" +#include "pros/llemu.h" +#include "pros/misc.h" +#include "pros/motors.h" +#include "pros/optical.h" +#include "pros/rotation.h" +#include "pros/rtos.h" +#include "pros/screen.h" +#include "pros/vision.h" + +#ifdef __cplusplus +#include "pros/adi.hpp" +#include "pros/colors.hpp" +#include "pros/device.hpp" +#include "pros/distance.hpp" +#include "pros/gps.hpp" +#include "pros/imu.hpp" +#include "pros/link.hpp" +#include "pros/llemu.hpp" +#include "pros/misc.hpp" +#include "pros/motor_group.hpp" +#include "pros/motors.hpp" +#include "pros/optical.hpp" +#include "pros/rotation.hpp" +#include "pros/rtos.hpp" +#include "pros/screen.hpp" +#include "pros/vision.hpp" +#endif + +#endif // _PROS_API_H_ diff --git a/include/liblvgl/core/lv_core.mk b/include/liblvgl/core/lv_core.mk deleted file mode 100644 index 677a9f6..0000000 --- a/include/liblvgl/core/lv_core.mk +++ /dev/null @@ -1,20 +0,0 @@ -CSRCS += lv_disp.c -CSRCS += lv_group.c -CSRCS += lv_indev.c -CSRCS += lv_indev_scroll.c -CSRCS += lv_obj.c -CSRCS += lv_obj_class.c -CSRCS += lv_obj_draw.c -CSRCS += lv_obj_pos.c -CSRCS += lv_obj_scroll.c -CSRCS += lv_obj_style.c -CSRCS += lv_obj_style_gen.c -CSRCS += lv_obj_tree.c -CSRCS += lv_event.c -CSRCS += lv_refr.c -CSRCS += lv_theme.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core" diff --git a/include/liblvgl/core/lv_disp.h b/include/liblvgl/core/lv_disp.h index 7854cb7..cd6efcc 100644 --- a/include/liblvgl/core/lv_disp.h +++ b/include/liblvgl/core/lv_disp.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../hal/lv_hal.h" +#include "liblvgl/hal/lv_hal.h" #include "lv_obj.h" #include "lv_theme.h" diff --git a/include/liblvgl/core/lv_group.h b/include/liblvgl/core/lv_group.h index 0910597..85df325 100644 --- a/include/liblvgl/core/lv_group.h +++ b/include/liblvgl/core/lv_group.h @@ -14,12 +14,12 @@ extern "C" { * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include -#include "../misc/lv_ll.h" -#include "../misc/lv_types.h" +#include "liblvgl/misc/lv_ll.h" +#include "liblvgl/misc/lv_types.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_indev.h b/include/liblvgl/core/lv_indev.h index a98df86..4692ef3 100644 --- a/include/liblvgl/core/lv_indev.h +++ b/include/liblvgl/core/lv_indev.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "lv_obj.h" -#include "../hal/lv_hal_indev.h" +#include "liblvgl/hal/lv_hal_indev.h" #include "lv_group.h" /********************* diff --git a/include/liblvgl/core/lv_obj_draw.h b/include/liblvgl/core/lv_obj_draw.h index 3f9d0f3..a107e55 100644 --- a/include/liblvgl/core/lv_obj_draw.h +++ b/include/liblvgl/core/lv_obj_draw.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../draw/lv_draw.h" +#include "liblvgl/draw/lv_draw.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_obj_pos.h b/include/liblvgl/core/lv_obj_pos.h index d20ee96..fdc6476 100644 --- a/include/liblvgl/core/lv_obj_pos.h +++ b/include/liblvgl/core/lv_obj_pos.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../misc/lv_area.h" +#include "liblvgl/misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_obj_scroll.h b/include/liblvgl/core/lv_obj_scroll.h index e1da245..3717dec 100644 --- a/include/liblvgl/core/lv_obj_scroll.h +++ b/include/liblvgl/core/lv_obj_scroll.h @@ -13,9 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../misc/lv_area.h" -#include "../misc/lv_anim.h" -#include "../misc/lv_types.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_anim.h" +#include "liblvgl/misc/lv_types.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_obj_style.h b/include/liblvgl/core/lv_obj_style.h index 5d122ca..18e530a 100644 --- a/include/liblvgl/core/lv_obj_style.h +++ b/include/liblvgl/core/lv_obj_style.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include #include -#include "../misc/lv_bidi.h" +#include "liblvgl/misc/lv_bidi.h" /********************* * DEFINES diff --git a/include/liblvgl/core/lv_theme.h b/include/liblvgl/core/lv_theme.h index ef46336..80da522 100644 --- a/include/liblvgl/core/lv_theme.h +++ b/include/liblvgl/core/lv_theme.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/arm2d/lv_draw_arm2d.mk b/include/liblvgl/draw/arm2d/lv_draw_arm2d.mk deleted file mode 100644 index 17219b0..0000000 --- a/include/liblvgl/draw/arm2d/lv_draw_arm2d.mk +++ /dev/null @@ -1,6 +0,0 @@ -CSRCS += lv_gpu_arm2d.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d" diff --git a/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h b/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h index 50fa5a8..cc66990 100644 --- a/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h +++ b/include/liblvgl/draw/arm2d/lv_gpu_arm2d.h @@ -13,9 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../misc/lv_color.h" -#include "../../hal/lv_hal_disp.h" -#include "../sw/lv_draw_sw.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/hal/lv_hal_disp.h" +#include "liblvgl/draw/sw/lv_draw_sw.h" #if LV_USE_GPU_ARM2D diff --git a/include/liblvgl/draw/lv_draw.h b/include/liblvgl/draw/lv_draw.h index ffe1d4e..c8aed72 100644 --- a/include/liblvgl/draw/lv_draw.h +++ b/include/liblvgl/draw/lv_draw.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" -#include "../misc/lv_style.h" -#include "../misc/lv_txt.h" +#include "liblvgl/misc/lv_style.h" +#include "liblvgl/misc/lv_txt.h" #include "lv_img_decoder.h" #include "lv_img_cache.h" @@ -72,7 +72,6 @@ typedef struct _lv_draw_ctx_t { */ const lv_area_t * clip_area; - void (*init_buf)(struct _lv_draw_ctx_t * draw_ctx); void (*draw_rect)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); diff --git a/include/liblvgl/draw/lv_draw.mk b/include/liblvgl/draw/lv_draw.mk deleted file mode 100644 index f48f48f..0000000 --- a/include/liblvgl/draw/lv_draw.mk +++ /dev/null @@ -1,25 +0,0 @@ -CSRCS += lv_draw_arc.c -CSRCS += lv_draw.c -CSRCS += lv_draw_img.c -CSRCS += lv_draw_label.c -CSRCS += lv_draw_line.c -CSRCS += lv_draw_mask.c -CSRCS += lv_draw_rect.c -CSRCS += lv_draw_transform.c -CSRCS += lv_draw_layer.c -CSRCS += lv_draw_triangle.c -CSRCS += lv_img_buf.c -CSRCS += lv_img_cache.c -CSRCS += lv_img_decoder.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw" - -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/arm2d/lv_draw_arm2d.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/lv_draw_nxp.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl/lv_draw_sdl.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw/lv_draw_sw.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk diff --git a/include/liblvgl/draw/lv_draw_arc.h b/include/liblvgl/draw/lv_draw_arc.h index 8783f13..8633af5 100644 --- a/include/liblvgl/draw/lv_draw_arc.h +++ b/include/liblvgl/draw/lv_draw_arc.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" -#include "../misc/lv_color.h" -#include "../misc/lv_area.h" -#include "../misc/lv_style.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_img.h b/include/liblvgl/draw/lv_draw_img.h index a88a33c..dcb7113 100644 --- a/include/liblvgl/draw/lv_draw_img.h +++ b/include/liblvgl/draw/lv_draw_img.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include "lv_img_decoder.h" #include "lv_img_buf.h" -#include "../misc/lv_style.h" +#include "liblvgl/misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_label.h b/include/liblvgl/draw/lv_draw_label.h index de72edd..736aa72 100644 --- a/include/liblvgl/draw/lv_draw_label.h +++ b/include/liblvgl/draw/lv_draw_label.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../misc/lv_bidi.h" -#include "../misc/lv_txt.h" -#include "../misc/lv_color.h" -#include "../misc/lv_style.h" +#include "liblvgl/misc/lv_bidi.h" +#include "liblvgl/misc/lv_txt.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_layer.h b/include/liblvgl/draw/lv_draw_layer.h index cd64149..1280d33 100644 --- a/include/liblvgl/draw/lv_draw_layer.h +++ b/include/liblvgl/draw/lv_draw_layer.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_line.h b/include/liblvgl/draw/lv_draw_line.h index d82ea51..79ca0dc 100644 --- a/include/liblvgl/draw/lv_draw_line.h +++ b/include/liblvgl/draw/lv_draw_line.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" -#include "../misc/lv_color.h" -#include "../misc/lv_area.h" -#include "../misc/lv_style.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_style.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_mask.h b/include/liblvgl/draw/lv_draw_mask.h index b7e4e1c..f3c49e5 100644 --- a/include/liblvgl/draw/lv_draw_mask.h +++ b/include/liblvgl/draw/lv_draw_mask.h @@ -15,9 +15,9 @@ extern "C" { * INCLUDES *********************/ #include -#include "../misc/lv_area.h" -#include "../misc/lv_color.h" -#include "../misc/lv_math.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_math.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_draw_rect.h b/include/liblvgl/draw/lv_draw_rect.h index 1583e3e..e259446 100644 --- a/include/liblvgl/draw/lv_draw_rect.h +++ b/include/liblvgl/draw/lv_draw_rect.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" -#include "../misc/lv_color.h" -#include "../misc/lv_area.h" -#include "../misc/lv_style.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_style.h" #include "sw/lv_draw_sw_gradient.h" /********************* diff --git a/include/liblvgl/draw/lv_draw_transform.h b/include/liblvgl/draw/lv_draw_transform.h index 1926c2f..6e6236c 100644 --- a/include/liblvgl/draw/lv_draw_transform.h +++ b/include/liblvgl/draw/lv_draw_transform.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" -#include "../misc/lv_area.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_img_buf.h b/include/liblvgl/draw/lv_img_buf.h index 1be7bb6..8998839 100644 --- a/include/liblvgl/draw/lv_img_buf.h +++ b/include/liblvgl/draw/lv_img_buf.h @@ -14,8 +14,8 @@ extern "C" { * INCLUDES *********************/ #include -#include "../misc/lv_color.h" -#include "../misc/lv_area.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/lv_img_decoder.h b/include/liblvgl/draw/lv_img_decoder.h index 9dc84dd..c0c5860 100644 --- a/include/liblvgl/draw/lv_img_decoder.h +++ b/include/liblvgl/draw/lv_img_decoder.h @@ -13,13 +13,13 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include "lv_img_buf.h" -#include "../misc/lv_fs.h" -#include "../misc/lv_types.h" -#include "../misc/lv_area.h" +#include "liblvgl/misc/lv_fs.h" +#include "liblvgl/misc/lv_types.h" +#include "liblvgl/misc/lv_area.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/nxp/lv_draw_nxp.mk b/include/liblvgl/draw/nxp/lv_draw_nxp.mk deleted file mode 100644 index 18a751e..0000000 --- a/include/liblvgl/draw/nxp/lv_draw_nxp.mk +++ /dev/null @@ -1,7 +0,0 @@ -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp" - -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp/lv_draw_nxp_pxp.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite/lv_draw_nxp_vglite.mk diff --git a/include/liblvgl/draw/nxp/lv_gpu_nxp.h b/include/liblvgl/draw/nxp/lv_gpu_nxp.h index cc0bdab..853da56 100644 --- a/include/liblvgl/draw/nxp/lv_gpu_nxp.h +++ b/include/liblvgl/draw/nxp/lv_gpu_nxp.h @@ -1,71 +1,71 @@ -/** - * @file lv_gpu_nxp.h - * - */ - -/** - * MIT License - * - * Copyright 2022 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_GPU_NXP_H -#define LV_GPU_NXP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -#include "liblvgl/lv_conf_internal.h" -#if LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE -#include "../sw/lv_draw_sw.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ -typedef lv_draw_sw_ctx_t lv_draw_nxp_ctx_t; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -void lv_draw_nxp_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - -void lv_draw_nxp_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - -/********************** - * MACROS - **********************/ -#endif /*LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_GPU_NXP_H*/ +/** + * @file lv_gpu_nxp.h + * + */ + +/** + * MIT License + * + * Copyright 2022 NXP + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next paragraph) + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LV_GPU_NXP_H +#define LV_GPU_NXP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "liblvgl/lv_conf_internal.h" +#if LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE +#include "../sw/lv_draw_sw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef lv_draw_sw_ctx_t lv_draw_nxp_ctx_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_nxp_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +void lv_draw_nxp_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GPU_NXP_H*/ diff --git a/include/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk b/include/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk deleted file mode 100644 index 5c684bc..0000000 --- a/include/liblvgl/draw/nxp/pxp/lv_draw_nxp_pxp.mk +++ /dev/null @@ -1,9 +0,0 @@ -CSRCS += lv_draw_pxp.c -CSRCS += lv_draw_pxp_blend.c -CSRCS += lv_gpu_nxp_pxp_osa.c -CSRCS += lv_gpu_nxp_pxp.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/pxp" diff --git a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h deleted file mode 100644 index 1ace3bc..0000000 --- a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file lv_draw_pxp.h - * - */ - -/** - * MIT License - * - * Copyright 2022, 2023 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_DRAW_PXP_H -#define LV_DRAW_PXP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -#include "../../../lv_conf_internal.h" - -#if LV_USE_GPU_NXP_PXP -#include "../../sw/lv_draw_sw.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ -typedef lv_draw_sw_ctx_t lv_draw_pxp_ctx_t; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -void lv_draw_pxp_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - -void lv_draw_pxp_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - -/********************** - * MACROS - **********************/ -#endif /*LV_USE_GPU_NXP_PXP*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_DRAW_PXP_H*/ diff --git a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h index 9fe9192..acce871 100644 --- a/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h +++ b/include/liblvgl/draw/nxp/pxp/lv_draw_pxp_blend.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2023 NXP + * Copyright 2020-2022 NXP * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,7 +38,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_NXP_PXP #include "lv_gpu_nxp_pxp.h" @@ -48,6 +48,31 @@ extern "C" { * DEFINES *********************/ +#ifndef LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT +/** Minimum area (in pixels) for image copy with 100% opacity to be handled by PXP*/ +#define LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT +/** Minimum area (in pixels) for image copy with transparency to be handled by PXP*/ +#define LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT +/** Minimum invalidated area (in pixels) to be synchronized by PXP during buffer sync */ +#define LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_PXP_FILL_SIZE_LIMIT +/** Minimum area (in pixels) to be filled by PXP with 100% opacity*/ +#define LV_GPU_NXP_PXP_FILL_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT +/** Minimum area (in pixels) to be filled by PXP with transparency*/ +#define LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT 5000 +#endif + /********************** * TYPEDEFS **********************/ @@ -59,49 +84,51 @@ extern "C" { /** * Fill area, with optional opacity. * - * @param[in/out] dest_buf Destination buffer - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dest_stride Stride of destination buffer in pixels - * @param[in] color Color - * @param[in] opa Opacity + * @param[in/out] dest_buf destination buffer + * @param[in] dest_stride width (stride) of destination buffer in pixels + * @param[in] fill_area area to fill + * @param[in] color color + * @param[in] opa transparency of the color + * @retval LV_RES_OK Fill completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) */ -void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - lv_color_t color, lv_opa_t opa); +lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area, + lv_color_t color, lv_opa_t opa); /** * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects. * By default, image is copied directly, with optional opacity. This function can also * rotate the display output buffer to a specified angle (90x step). * - * @param[in/out] dest_buf Destination buffer - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dest_stride Stride of destination buffer in pixels - * @param[in] src_buf Source buffer - * @param[in] src_area Source area with relative coordinates of source buffer - * @param[in] src_stride Stride of source buffer in pixels - * @param[in] opa Opacity - * @param[in] angle Display rotation angle (90x) + * @param[in/out] dest_buf destination buffer + * @param[in] dest_area destination area + * @param[in] dest_stride width (stride) of destination buffer in pixels + * @param[in] src_buf source buffer + * @param[in] src_area source area with absolute coordinates to draw on destination buffer + * @param[in] opa opacity of the result + * @param[in] angle display rotation angle (90x) + * @retval LV_RES_OK Fill completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) */ -void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, - lv_opa_t opa, lv_disp_rot_t angle); +lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, lv_opa_t opa, lv_disp_rot_t angle); /** * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation. * * - * @param[in/out] dest_buf Destination buffer - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dest_stride Stride of destination buffer in pixels - * @param[in] src_buf Source buffer - * @param[in] src_area Area with relative coordinates of source buffer - * @param[in] src_stride Stride of source buffer in pixels - * @param[in] dsc Image descriptor - * @param[in] cf Color format + * @param[in/out] dest_buf destination buffer + * @param[in] dest_area destination area + * @param[in] dest_stride width (stride) of destination buffer in pixels + * @param[in] src_buf source buffer + * @param[in] src_area source area with absolute coordinates to draw on destination buffer + * @param[in] dsc image descriptor + * @param[in] cf color format + * @retval LV_RES_OK Fill completed + * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS) */ -void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride, - const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); +lv_res_t lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride, + const lv_color_t * src_buf, const lv_area_t * src_area, const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h index 10a6721..aeb9d6c 100644 --- a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h +++ b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2023 NXP + * Copyright 2020-2022 NXP * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,7 +38,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_NXP_PXP #include "fsl_cache.h" @@ -81,11 +81,8 @@ typedef struct { /** Callback for PXP interrupt de-initialization*/ void (*pxp_interrupt_deinit)(void); - /** Callback for PXP start*/ + /** Callback that should start PXP and wait for operation complete*/ void (*pxp_run)(void); - - /** Callback for waiting of PXP completion*/ - void (*pxp_wait)(void); } lv_nxp_pxp_cfg_t; /********************** @@ -107,20 +104,10 @@ lv_res_t lv_gpu_nxp_pxp_init(void); void lv_gpu_nxp_pxp_deinit(void); /** - * Reset PXP device. - */ -void lv_gpu_nxp_pxp_reset(void); - -/** - * Clear cache and start PXP. + * Start PXP job and wait for completion. */ void lv_gpu_nxp_pxp_run(void); -/** - * Wait for PXP completion. - */ -void lv_gpu_nxp_pxp_wait(void); - /********************** * MACROS **********************/ diff --git a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h index 5c87824..d907447 100644 --- a/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h +++ b/include/liblvgl/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.h @@ -38,7 +38,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT #include "lv_gpu_nxp_pxp.h" diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk b/include/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk deleted file mode 100644 index c9473cc..0000000 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_nxp_vglite.mk +++ /dev/null @@ -1,12 +0,0 @@ -CSRCS += lv_draw_vglite.c -CSRCS += lv_draw_vglite_arc.c -CSRCS += lv_draw_vglite_blend.c -CSRCS += lv_draw_vglite_line.c -CSRCS += lv_draw_vglite_rect.c -CSRCS += lv_vglite_buf.c -CSRCS += lv_vglite_utils.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite" diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h deleted file mode 100644 index c44cb8f..0000000 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file lv_draw_vglite.h - * - */ - -/** - * MIT License - * - * Copyright 2022, 2023 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_DRAW_VGLITE_H -#define LV_DRAW_VGLITE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -#include "../../../lv_conf_internal.h" - -#if LV_USE_GPU_NXP_VG_LITE -#include "../../sw/lv_draw_sw.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ -typedef lv_draw_sw_ctx_t lv_draw_vglite_ctx_t; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -void lv_draw_vglite_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - -void lv_draw_vglite_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); - -/********************** - * MACROS - **********************/ -#endif /*LV_USE_GPU_NXP_VG_LITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_DRAW_VGLITE_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h index 0fbff3d..e2da419 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_arc.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2021-2023 NXP + * Copyright 2021, 2022 NXP * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,10 +37,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_NXP_VG_LITE -#include "lv_vglite_utils.h" +#include "lv_gpu_nxp_vglite.h" /********************* * DEFINES @@ -54,21 +54,17 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -/** +/*** * Draw arc shape with effects - * - * @param[in] center Arc center with relative coordinates - * @param[in] radius Radius of external arc - * @param[in] start_angle Starting angle in degrees - * @param[in] end_angle Ending angle in degrees - * @param[in] clip_area Clipping area with relative coordinates to dest buff - * @param[in] dsc Arc description structure (width, rounded ending, opacity) - * - * @retval LV_RES_OK Draw completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + * @param draw_ctx drawing context + * @param dsc the arc description structure (width, rounded ending, opacity) + * @param center the coordinates of the arc center + * @param radius the radius of external arc + * @param start_angle the starting angle in degrees + * @param end_angle the ending angle in degrees */ -lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, int32_t start_angle, int32_t end_angle, - const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc); +lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, + int32_t radius, int32_t start_angle, int32_t end_angle); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h index 025d2b5..1726dcd 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_blend.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2020-2023 NXP + * Copyright 2020-2022 NXP * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,19 +38,67 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_NXP_VG_LITE -#include "lv_vglite_utils.h" +#include "lv_gpu_nxp_vglite.h" /********************* * DEFINES *********************/ +#ifndef LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT +/** Minimum area (in pixels) to be filled by VG-Lite with 100% opacity*/ +#define LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT +/** Minimum area (in pixels) to be filled by VG-Lite with transparency*/ +#define LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT +/** Minimum area (in pixels) for image copy with 100% opacity to be handled by VG-Lite*/ +#define LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT +/** Minimum invalidated area (in pixels) to be synchronized by VG-Lite during buffer sync */ +#define LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT 5000 +#endif + +#ifndef LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT +/** Minimum area (in pixels) for image copy with transparency to be handled by VG-Lite*/ +#define LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT 5000 +#endif + /********************** * TYPEDEFS **********************/ +/** + * BLock Image Transfer descriptor structure + */ +typedef struct { + + const lv_color_t * src; /**< Source buffer pointer (must be aligned on 32 bytes)*/ + lv_area_t src_area; /**< Area to be copied from source*/ + lv_coord_t src_width; /**< Source buffer width*/ + lv_coord_t src_height; /**< Source buffer height*/ + int32_t src_stride; /**< Source buffer stride in bytes (must be aligned on 16 px)*/ + + const lv_color_t * dst; /**< Destination buffer pointer (must be aligned on 32 bytes)*/ + lv_area_t dst_area; /**< Target area in destination buffer (must be the same as src_area)*/ + lv_coord_t dst_width; /**< Destination buffer width*/ + lv_coord_t dst_height; /**< Destination buffer height*/ + int32_t dst_stride; /**< Destination buffer stride in bytes (must be aligned on 16 px)*/ + + lv_opa_t opa; /**< Opacity - alpha mix (0 = source not copied, 255 = 100% opaque)*/ + uint32_t angle; /**< Rotation angle (1/10 of degree)*/ + uint32_t zoom; /**< 256 = no zoom (1:1 scale ratio)*/ + lv_point_t pivot; /**< The coordinates of rotation pivot in source image buffer*/ +} lv_gpu_nxp_vglite_blit_info_t; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -58,52 +106,35 @@ extern "C" { /** * Fill area, with optional opacity. * - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] color Color + * @param[in/out] dest_buf Destination buffer pointer (must be aligned on 32 bytes) + * @param[in] dest_width Destination buffer width in pixels (must be aligned on 16 px) + * @param[in] dest_height Destination buffer height in pixels + * @param[in] fill_area Area to be filled + * @param[in] color Fill color * @param[in] opa Opacity (255 = full, 128 = 50% background/50% color, 0 = no fill) - * * @retval LV_RES_OK Fill completed * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, lv_opa_t opa); +lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height, + const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa); /** - * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects. - * By default, image is copied directly, with optional opacity. - * - * @param[in/out] dest_buf Destination buffer - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dest_stride Stride of destination buffer in pixels - * @param[in] src_buf Source buffer - * @param[in] src_area Source area with relative coordinates of source buffer - * @param[in] src_stride Stride of source buffer in pixels - * @param[in] opa Opacity + * BLock Image Transfer. * + * @param[in] blit Description of the transfer * @retval LV_RES_OK Transfer complete * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_blit(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, - lv_opa_t opa); +lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit); /** - * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation. - * By default, image is copied directly, with optional opacity. - * - * @param[in/out] dest_buf Destination buffer - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dest_stride Stride of destination buffer in pixels - * @param[in] src_buf Source buffer - * @param[in] src_area Source area with relative coordinates of source buffer - * @param[in] src_stride Stride of source buffer in pixels - * @param[in] dsc Image descriptor + * BLock Image Transfer with transformation. * + * @param[in] blit Description of the transfer * @retval LV_RES_OK Transfer complete * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) */ -lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride, - const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride, - const lv_draw_img_dsc_t * dsc); +lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.h deleted file mode 100644 index cbd4b95..0000000 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_line.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file lv_draw_vglite_line.h - * - */ - -/** - * MIT License - * - * Copyright 2022, 2023 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_DRAW_VGLITE_LINE_H -#define LV_DRAW_VGLITE_LINE_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_GPU_NXP_VG_LITE -#include "lv_vglite_utils.h" -#include "../../lv_draw_line.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Draw line shape with effects - * - * @param[in] point1 Starting point with relative coordinates - * @param[in] point2 Ending point with relative coordinates - * @param[in] clip_area Clipping area with relative coordinates to dest buff - * @param[in] dsc Line description structure (width, rounded ending, opacity, ...) - * - * @retval LV_RES_OK Draw completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) - */ -lv_res_t lv_gpu_nxp_vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2, - const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc); - -/********************** - * MACROS - **********************/ - -#endif /*LV_USE_GPU_NXP_VG_LITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_DRAW_VGLITE_RECT_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h index 7958227..8a64170 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h +++ b/include/liblvgl/draw/nxp/vglite/lv_draw_vglite_rect.h @@ -6,7 +6,7 @@ /** * MIT License * - * Copyright 2021-2023 NXP + * Copyright 2021, 2022 NXP * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,10 +37,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_NXP_VG_LITE -#include "lv_vglite_utils.h" +#include "lv_gpu_nxp_vglite.h" #include "../../lv_draw_rect.h" /********************* @@ -56,33 +56,13 @@ extern "C" { **********************/ /** - * Draw rectangle background with effects (rounded corners, gradient) - * - * @param[in] coords Coordinates of the rectangle background (relative to dest buff) - * @param[in] clip_area Clipping area with relative coordinates to dest buff - * @param[in] dsc Description of the rectangle background - * - * @retval LV_RES_OK Draw completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) - * - */ -lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * clip_area, - const lv_draw_rect_dsc_t * dsc); - -/** - * Draw rectangle border/outline shape with effects (rounded corners, opacity) - * - * @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff) - * @param[in] clip_area Clipping area with relative coordinates to dest buff - * @param[in] dsc Description of the rectangle border/outline - * @param[in] border True for border, False for outline - * - * @retval LV_RES_OK Draw completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) + * Draw rectangle shape with effects (rounded corners, gradient) * + * @param draw_ctx drawing context + * @param dsc description of the rectangle + * @param coords the area where rectangle is clipped */ -lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const lv_area_t * clip_area, - const lv_draw_rect_dsc_t * dsc, bool border); +lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords); /********************** * MACROS diff --git a/include/liblvgl/draw/nxp/vglite/lv_gpu_nxp_vglite.h b/include/liblvgl/draw/nxp/vglite/lv_gpu_nxp_vglite.h index cb99a87..8754492 100644 --- a/include/liblvgl/draw/nxp/vglite/lv_gpu_nxp_vglite.h +++ b/include/liblvgl/draw/nxp/vglite/lv_gpu_nxp_vglite.h @@ -1,185 +1,185 @@ -/** - * @file lv_gpu_nxp_vglite.h - * - */ - -/** - * MIT License - * - * Copyright 2020-2022 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_GPU_NXP_VGLITE_H -#define LV_GPU_NXP_VGLITE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "liblvgl/lv_conf_internal.h" - -#if LV_USE_GPU_NXP_VG_LITE -#include "vg_lite.h" -#include "../../sw/lv_draw_sw.h" -#include "../../../misc/lv_log.h" -#include "fsl_debug_console.h" - -/********************* - * DEFINES - *********************/ - -/** Use this symbol as limit to disable feature (value has to be larger than supported resolution) */ -#define LV_GPU_NXP_VG_LITE_FEATURE_DISABLED (1920*1080+1) - -/** Stride in px required by VG-Lite HW. Don't change this. */ -#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U - -#ifndef LV_GPU_NXP_VG_LITE_LOG_ERRORS -/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/ -#define LV_GPU_NXP_VG_LITE_LOG_ERRORS 1 -#endif - -#ifndef LV_GPU_NXP_VG_LITE_LOG_TRACES -/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/ -#define LV_GPU_NXP_VG_LITE_LOG_TRACES 0 -#endif - -/* Draw rectangles around BLIT tiles */ -#define BLIT_DBG_AREAS 0 - -/* Print detailed info to SDK console (NOT to LVGL log system) */ -#define BLIT_DBG_VERBOSE 0 - -/* Verbose debug print */ -#if BLIT_DBG_VERBOSE -#define PRINT_BLT PRINTF -#else -#define PRINT_BLT(...) -#endif - -/* The optimal Bezier control point offset for radial unit - * see: https://spencermortensen.com/articles/bezier-circle/ - **/ -#define BEZIER_OPTIM_CIRCLE 0.551915024494f - -/* Draw lines for control points of Bezier curves */ -#define BEZIER_DBG_CONTROL_POINTS 0 - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Fills vg_lite_buffer_t structure according given parameters. - * - * @param[in/out] vgbuf Buffer structure to be filled - * @param[in] width Width of buffer in pixels - * @param[in] height Height of buffer in pixels - * @param[in] stride Stride of the buffer in bytes - * @param[in] ptr Pointer to the buffer (must be aligned according VG-Lite requirements) - * @param[in] source Boolean to check if this is a source buffer - */ -lv_res_t lv_vglite_init_buf(vg_lite_buffer_t * vgbuf, uint32_t width, uint32_t height, uint32_t stride, - const lv_color_t * ptr, bool source); - -#if BLIT_DBG_AREAS -/** - * Draw a simple rectangle, 1 px line width. - * - * @param dest_buf Destination buffer - * @param dest_width Destination buffer width (must be aligned on 16px) - * @param dest_height Destination buffer height - * @param fill_area Rectangle coordinates - * @param color Rectangle color - */ -void lv_vglite_dbg_draw_rectangle(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height, - lv_area_t * fill_area, lv_color_t color); -#endif - -/** - * Clean & invalidate cache. - */ -void lv_vglite_invalidate_cache(void); - -/********************** - * MACROS - **********************/ - -#define VG_LITE_COND_STOP(cond, txt) \ - do { \ - if (cond) { \ - LV_LOG_ERROR("%s. STOP!", txt); \ - for ( ; ; ); \ - } \ - } while(0) - -#if LV_GPU_NXP_VG_LITE_LOG_ERRORS -#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ - do { \ - if(err != VG_LITE_SUCCESS) { \ - LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ - return LV_RES_INV; \ - } \ - } while (0) -#else -#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ - do { \ - if(err != VG_LITE_SUCCESS) { \ - return LV_RES_INV; \ - } \ - }while(0) -#endif /*LV_GPU_NXP_VG_LITE_LOG_ERRORS*/ - -#if LV_GPU_NXP_VG_LITE_LOG_TRACES -#define VG_LITE_LOG_TRACE(fmt, ...) \ - do { \ - LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ - } while (0) - -#define VG_LITE_RETURN_INV(fmt, ...) \ - do { \ - LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ - return LV_RES_INV; \ - } while (0) -#else -#define VG_LITE_LOG_TRACE(fmt, ...) \ - do { \ - } while (0) -#define VG_LITE_RETURN_INV(fmt, ...) \ - do { \ - return LV_RES_INV; \ - }while(0) -#endif /*LV_GPU_NXP_VG_LITE_LOG_TRACES*/ - -#endif /*LV_USE_GPU_NXP_VG_LITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_GPU_NXP_VGLITE_H*/ +/** + * @file lv_gpu_nxp_vglite.h + * + */ + +/** + * MIT License + * + * Copyright 2020-2022 NXP + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next paragraph) + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef LV_GPU_NXP_VGLITE_H +#define LV_GPU_NXP_VGLITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "liblvgl/lv_conf_internal.h" + +#if LV_USE_GPU_NXP_VG_LITE +#include "vg_lite.h" +#include "../../sw/lv_draw_sw.h" +#include "../../../misc/lv_log.h" +#include "fsl_debug_console.h" + +/********************* + * DEFINES + *********************/ + +/** Use this symbol as limit to disable feature (value has to be larger than supported resolution) */ +#define LV_GPU_NXP_VG_LITE_FEATURE_DISABLED (1920*1080+1) + +/** Stride in px required by VG-Lite HW. Don't change this. */ +#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U + +#ifndef LV_GPU_NXP_VG_LITE_LOG_ERRORS +/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/ +#define LV_GPU_NXP_VG_LITE_LOG_ERRORS 1 +#endif + +#ifndef LV_GPU_NXP_VG_LITE_LOG_TRACES +/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/ +#define LV_GPU_NXP_VG_LITE_LOG_TRACES 0 +#endif + +/* Draw rectangles around BLIT tiles */ +#define BLIT_DBG_AREAS 0 + +/* Print detailed info to SDK console (NOT to LVGL log system) */ +#define BLIT_DBG_VERBOSE 0 + +/* Verbose debug print */ +#if BLIT_DBG_VERBOSE +#define PRINT_BLT PRINTF +#else +#define PRINT_BLT(...) +#endif + +/* The optimal Bezier control point offset for radial unit + * see: https://spencermortensen.com/articles/bezier-circle/ + **/ +#define BEZIER_OPTIM_CIRCLE 0.551915024494f + +/* Draw lines for control points of Bezier curves */ +#define BEZIER_DBG_CONTROL_POINTS 0 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Fills vg_lite_buffer_t structure according given parameters. + * + * @param[in/out] vgbuf Buffer structure to be filled + * @param[in] width Width of buffer in pixels + * @param[in] height Height of buffer in pixels + * @param[in] stride Stride of the buffer in bytes + * @param[in] ptr Pointer to the buffer (must be aligned according VG-Lite requirements) + * @param[in] source Boolean to check if this is a source buffer + */ +lv_res_t lv_vglite_init_buf(vg_lite_buffer_t * vgbuf, uint32_t width, uint32_t height, uint32_t stride, + const lv_color_t * ptr, bool source); + +#if BLIT_DBG_AREAS +/** + * Draw a simple rectangle, 1 px line width. + * + * @param dest_buf Destination buffer + * @param dest_width Destination buffer width (must be aligned on 16px) + * @param dest_height Destination buffer height + * @param fill_area Rectangle coordinates + * @param color Rectangle color + */ +void lv_vglite_dbg_draw_rectangle(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height, + lv_area_t * fill_area, lv_color_t color); +#endif + +/** + * Clean & invalidate cache. + */ +void lv_vglite_invalidate_cache(void); + +/********************** + * MACROS + **********************/ + +#define VG_LITE_COND_STOP(cond, txt) \ + do { \ + if (cond) { \ + LV_LOG_ERROR("%s. STOP!", txt); \ + for ( ; ; ); \ + } \ + } while(0) + +#if LV_GPU_NXP_VG_LITE_LOG_ERRORS +#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ + do { \ + if(err != VG_LITE_SUCCESS) { \ + LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ + return LV_RES_INV; \ + } \ + } while (0) +#else +#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ + do { \ + if(err != VG_LITE_SUCCESS) { \ + return LV_RES_INV; \ + } \ + }while(0) +#endif /*LV_GPU_NXP_VG_LITE_LOG_ERRORS*/ + +#if LV_GPU_NXP_VG_LITE_LOG_TRACES +#define VG_LITE_LOG_TRACE(fmt, ...) \ + do { \ + LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ + } while (0) + +#define VG_LITE_RETURN_INV(fmt, ...) \ + do { \ + LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ + return LV_RES_INV; \ + } while (0) +#else +#define VG_LITE_LOG_TRACE(fmt, ...) \ + do { \ + } while (0) +#define VG_LITE_RETURN_INV(fmt, ...) \ + do { \ + return LV_RES_INV; \ + }while(0) +#endif /*LV_GPU_NXP_VG_LITE_LOG_TRACES*/ + +#endif /*LV_USE_GPU_NXP_VG_LITE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GPU_NXP_VGLITE_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h b/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h deleted file mode 100644 index 9219dca..0000000 --- a/include/liblvgl/draw/nxp/vglite/lv_vglite_buf.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file lv_vglite_buf.h - * - */ - -/** - * MIT License - * - * Copyright 2023 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_VGLITE_BUF_H -#define LV_VGLITE_BUF_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_GPU_NXP_VG_LITE -#include "vg_lite.h" -#include "../../sw/lv_draw_sw.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ -/** - * Init vglite destination buffer. It will be done once per frame. - * - * @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode) - * @param[in] area Destination buffer area (for width and height) - * @param[in] stride Stride of destination buffer - */ -void lv_gpu_nxp_vglite_init_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride); - -/** - * Get vglite destination buffer pointer. - * - * @retval The vglite destination buffer - */ -vg_lite_buffer_t * lv_vglite_get_dest_buf(void); - -/** - * Get vglite source buffer pointer. - * - * @retval The vglite source buffer - */ -vg_lite_buffer_t * lv_vglite_get_src_buf(void); - -/** - * Set vglite destination buffer address only. - * - * @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode) - */ -void lv_vglite_set_dest_buf_ptr(const lv_color_t * buf); - -/** - * Set vglite source buffer address only. - * - * @param[in] buf Source buffer address - */ -void lv_vglite_set_src_buf_ptr(const lv_color_t * buf); - -/** - * Set vglite source buffer. It will be done only if buffer addreess is different. - * - * @param[in] buf Source buffer address - * @param[in] area Source buffer area (for width and height) - * @param[in] stride Stride of source buffer - */ -void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride); - -/********************** - * MACROS - **********************/ - -#endif /*LV_USE_GPU_NXP_VG_LITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_VGLITE_BUF_H*/ diff --git a/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h b/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h deleted file mode 100644 index 9ff4de0..0000000 --- a/include/liblvgl/draw/nxp/vglite/lv_vglite_utils.h +++ /dev/null @@ -1,166 +0,0 @@ -/** - * @file lv_vglite_utils.h - * - */ - -/** - * MIT License - * - * Copyright 2022, 2023 NXP - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next paragraph) - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef LV_VGLITE_UTILS_H -#define LV_VGLITE_UTILS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_GPU_NXP_VG_LITE -#include "vg_lite.h" -#include "../../sw/lv_draw_sw.h" -#include "../../../misc/lv_log.h" - -/********************* - * DEFINES - *********************/ - -#ifndef LV_GPU_NXP_VG_LITE_LOG_ERRORS -/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/ -#define LV_GPU_NXP_VG_LITE_LOG_ERRORS 1 -#endif - -#ifndef LV_GPU_NXP_VG_LITE_LOG_TRACES -/** Enable logging of VG-Lite traces (\see LV_LOG_ERROR)*/ -#define LV_GPU_NXP_VG_LITE_LOG_TRACES 0 -#endif - - -/* The optimal Bezier control point offset for radial unit - * see: https://spencermortensen.com/articles/bezier-circle/ - **/ -#define BEZIER_OPTIM_CIRCLE 0.551915024494f - -/* Draw lines for control points of Bezier curves */ -#define BEZIER_DBG_CONTROL_POINTS 0 - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Premultiplies and swizzles given LVGL 32bit color to obtain vglite color. - * - * @param[in/out] vg_col32 The obtained vglite color - * @param[in] lv_col32 The initial LVGL 32bit color - * @param[in] opa The opacity to premultiply with - * @param[in] vg_col_format The format of the resulting vglite color - * - * @retval LV_RES_OK Operation completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) - */ -lv_res_t lv_vglite_premult_and_swizzle(vg_lite_color_t * vg_col32, lv_color32_t lv_col32, lv_opa_t opa, - vg_lite_buffer_format_t vg_col_format); - -/** - * Get vglite blend mode. - * - * @param[in] lv_blend_mode The LVGL blend mode - * - * @retval The vglite blend mode - */ -vg_lite_blend_t lv_vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode); - -/** - * Clear cache and flush command to VG-Lite. - * - * @retval LV_RES_OK Run completed - * @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS) - */ -lv_res_t lv_vglite_run(void); - -/********************** - * MACROS - **********************/ - -#define VG_LITE_COND_STOP(cond, txt) \ - do { \ - if (cond) { \ - LV_LOG_ERROR("%s. STOP!", txt); \ - for ( ; ; ); \ - } \ - } while(0) - -#if LV_GPU_NXP_VG_LITE_LOG_ERRORS -#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ - do { \ - if(err != VG_LITE_SUCCESS) { \ - LV_LOG_ERROR(fmt" (err = %d)", \ - err, ##__VA_ARGS__); \ - return LV_RES_INV; \ - } \ - } while (0) -#else -#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \ - do { \ - if(err != VG_LITE_SUCCESS) { \ - return LV_RES_INV; \ - } \ - }while(0) -#endif /*LV_GPU_NXP_VG_LITE_LOG_ERRORS*/ - -#if LV_GPU_NXP_VG_LITE_LOG_TRACES -#define VG_LITE_LOG_TRACE(fmt, ...) \ - do { \ - LV_LOG(fmt, ##__VA_ARGS__); \ - } while (0) - -#define VG_LITE_RETURN_INV(fmt, ...) \ - do { \ - LV_LOG_ERROR(fmt, ##__VA_ARGS__); \ - return LV_RES_INV; \ - } while (0) -#else -#define VG_LITE_LOG_TRACE(fmt, ...) \ - do { \ - } while (0) -#define VG_LITE_RETURN_INV(fmt, ...) \ - do { \ - return LV_RES_INV; \ - }while(0) -#endif /*LV_GPU_NXP_VG_LITE_LOG_TRACES*/ - -#endif /*LV_USE_GPU_NXP_VG_LITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_VGLITE_UTILS_H*/ diff --git a/include/liblvgl/draw/sdl/README.md b/include/liblvgl/draw/sdl/README.md deleted file mode 100644 index 4415ffa..0000000 --- a/include/liblvgl/draw/sdl/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# SDL_Renderer Based Drawing Functions - -In LVGL, drawing was performed by CPU. To improve drawing performance on platforms with GPU, -we should perform drawing operations on GPU if possible. - -This implementation has moved most bitmap blending and drawing procedures to utilize SDL_Renderer, -which takes advantages of hardware acceleration APIs like DirectX or OpenGL. - -This implementation can be also considered as a reference implementation, for contributors wants to -develop accelerated drawing functions with other APIs such as OpenGL/OpenGL ES. - -## Caveats -`lv_draw_arc`, `lv_draw_line` is not enabled, due to incomplete implementation. So lines and arcs will -have significant impact to drawing performances. - -Performance of this implementation still has room to improve. Or we should use more powerful APIs -such as OpenGL. - -## Notices for files - -### `lv_draw_sdl_stack_blur.c` - -Contains modified code from [android-stackblur](https://github.com/kikoso/android-stackblur) project. -Apache License 2.0 - -### `lv_draw_sdl_lru.c`/`lv_draw_sdl_lru.h` - -Contains modified code from [C-LRU-Cache](https://github.com/willcannings/C-LRU-Cache) project. No license defined. \ No newline at end of file diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl.h b/include/liblvgl/draw/sdl/lv_draw_sdl.h index 9b44a7b..7708d5b 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl.mk b/include/liblvgl/draw/sdl/lv_draw_sdl.mk deleted file mode 100644 index c5c28b6..0000000 --- a/include/liblvgl/draw/sdl/lv_draw_sdl.mk +++ /dev/null @@ -1,19 +0,0 @@ -CSRCS += lv_draw_sdl.c -CSRCS += lv_draw_sdl_arc.c -CSRCS += lv_draw_sdl_bg.c -CSRCS += lv_draw_sdl_composite.c -CSRCS += lv_draw_sdl_img.c -CSRCS += lv_draw_sdl_label.c -CSRCS += lv_draw_sdl_line.c -CSRCS += lv_draw_sdl_mask.c -CSRCS += lv_draw_sdl_polygon.c -CSRCS += lv_draw_sdl_rect.c -CSRCS += lv_draw_sdl_stack_blur.c -CSRCS += lv_draw_sdl_texture_cache.c -CSRCS += lv_draw_sdl_utils.c -CSRCS += lv_draw_sdl_layer.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl" diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h b/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h index 72a2dae..3a598d7 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_composite.h @@ -14,13 +14,13 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include LV_GPU_SDL_INCLUDE_PATH #include "lv_draw_sdl.h" -#include "../../misc/lv_area.h" -#include "../../misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_color.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_img.h b/include/liblvgl/draw/sdl/lv_draw_sdl_img.h index 0e27027..d6e3758 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_img.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_img.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h b/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h index a562d73..aa4dd2b 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_mask.h @@ -14,13 +14,13 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include LV_GPU_SDL_INCLUDE_PATH #include "lv_draw_sdl.h" -#include "../../misc/lv_area.h" -#include "../../misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_color.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h b/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h index 24a8762..736fe89 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_priv.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h b/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h index 3472af3..fc96894 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_rect.h @@ -14,7 +14,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL @@ -59,11 +59,6 @@ typedef struct lv_draw_sdl_rect_header_t { SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius); -SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w, - lv_coord_t h, lv_coord_t radius); - -SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad); - void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture * frag, lv_coord_t frag_size, const lv_area_t * coords, const lv_area_t * clip, bool full); diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h b/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h index 413b1c9..3d854e3 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_stack_blur.h @@ -13,7 +13,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h b/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h index 1bbf17c..0b54246 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_texture_cache.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL @@ -50,7 +50,6 @@ typedef enum { LV_GPU_CACHE_KEY_MAGIC_RECT_BG = 0x31, LV_GPU_CACHE_KEY_MAGIC_RECT_SHADOW = 0x32, LV_GPU_CACHE_KEY_MAGIC_RECT_BORDER = 0x33, - LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD = 0x34, LV_GPU_CACHE_KEY_MAGIC_FONT_GLYPH = 0x41, LV_GPU_CACHE_KEY_MAGIC_MASK = 0x51, } lv_sdl_cache_key_magic_t; diff --git a/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h b/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h index 9afae68..943bda3 100644 --- a/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h +++ b/include/liblvgl/draw/sdl/lv_draw_sdl_utils.h @@ -13,7 +13,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_GPU_SDL #include "lv_draw_sdl.h" diff --git a/include/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk b/include/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk deleted file mode 100644 index 8ed00b0..0000000 --- a/include/liblvgl/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk +++ /dev/null @@ -1,6 +0,0 @@ -CSRCS += lv_gpu_stm32_dma2d.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d" diff --git a/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h b/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h index 5ecce6d..f2bcdbe 100644 --- a/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h +++ b/include/liblvgl/draw/stm32_dma2d/lv_gpu_stm32_dma2d.h @@ -10,83 +10,52 @@ extern "C" { #endif -#include "../../misc/lv_color.h" -#include "../../hal/lv_hal_disp.h" -#include "../sw/lv_draw_sw.h" - -#if LV_USE_GPU_STM32_DMA2D - /********************* * INCLUDES *********************/ -#include LV_GPU_DMA2D_CMSIS_INCLUDE +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/hal/lv_hal_disp.h" +#include "liblvgl/draw/sw/lv_draw_sw.h" + +#if LV_USE_GPU_STM32_DMA2D /********************* * DEFINES *********************/ -#if defined(LV_STM32_DMA2D_TEST) -// removes "static" modifier for some internal methods in order to test them -#define LV_STM32_DMA2D_STATIC -#else -#define LV_STM32_DMA2D_STATIC static -#endif + +#define LV_DMA2D_ARGB8888 0 +#define LV_DMA2D_RGB888 1 +#define LV_DMA2D_RGB565 2 +#define LV_DMA2D_ARGB1555 3 +#define LV_DMA2D_ARGB4444 4 /********************** * TYPEDEFS **********************/ -enum dma2d_color_format { - ARGB8888 = 0x0, - RGB888 = 0x01, - RGB565 = 0x02, - ARGB1555 = 0x03, - ARGB4444 = 0x04, - A8 = 0x09, - UNSUPPORTED = 0xff, -}; -typedef enum dma2d_color_format dma2d_color_format_t; typedef lv_draw_sw_ctx_t lv_draw_stm32_dma2d_ctx_t; + struct _lv_disp_drv_t; /********************** * GLOBAL PROTOTYPES **********************/ + +/** + * Turn on the peripheral and set output color mode, this only needs to be done once + */ void lv_draw_stm32_dma2d_init(void); + void lv_draw_stm32_dma2d_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); + void lv_draw_stm32_dma2d_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx); -static void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); -static void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx, - void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area, - void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area); -static lv_res_t lv_draw_stm32_dma2d_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc, - const lv_area_t * src_area, const void * src); -static void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx); -static void lv_draw_stm32_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * img_dsc, - const lv_area_t * coords, const uint8_t * src_buf, lv_img_cf_t color_format); -static dma2d_color_format_t lv_color_format_to_dma2d_color_format(lv_img_cf_t color_format); -static lv_point_t lv_area_get_offset(const lv_area_t * area1, const lv_area_t * area2); -/********************** - * STATIC PROTOTYPES - **********************/ -LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_fill(const lv_color_t * dst_buf, lv_coord_t dst_stride, - const lv_area_t * draw_area, lv_color_t color, lv_opa_t opa); -LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_map(const lv_color_t * dest_buf, lv_coord_t dest_stride, - const lv_area_t * draw_area, const void * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset, lv_opa_t opa, - dma2d_color_format_t src_color_format, bool ignore_src_alpha); -LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_blend_paint(const lv_color_t * dst_buf, lv_coord_t dst_stride, - const lv_area_t * draw_area, const lv_opa_t * mask_buf, lv_coord_t mask_stride, const lv_point_t * mask_offset, - lv_color_t color, lv_opa_t opa); -LV_STM32_DMA2D_STATIC void _lv_draw_stm32_dma2d_copy_buffer(const lv_color_t * dest_buf, lv_coord_t dest_stride, - const lv_area_t * draw_area, const lv_color_t * src_buf, lv_coord_t src_stride, const lv_point_t * src_offset); -LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_await_dma_transfer_finish(lv_disp_drv_t * disp_drv); -LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_start_dma_transfer(void); -LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_invalidate_cache(uint32_t address, lv_coord_t offset, - lv_coord_t width, lv_coord_t height, uint8_t pixel_size); -LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dma2d_clean_cache(uint32_t address, lv_coord_t offset, lv_coord_t width, - lv_coord_t height, uint8_t pixel_size); -LV_STM32_DMA2D_STATIC bool _lv_gpu_stm32_dwt_init(void); -LV_STM32_DMA2D_STATIC void _lv_gpu_stm32_dwt_reset(void); -LV_STM32_DMA2D_STATIC uint32_t _lv_gpu_stm32_dwt_get_us(void); +void lv_draw_stm32_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc); + +void lv_draw_stm32_dma2d_buffer_copy(lv_draw_ctx_t * draw_ctx, + void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area, + void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area); + +void lv_gpu_stm32_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx); /********************** * MACROS diff --git a/include/liblvgl/draw/sw/lv_draw_sw.h b/include/liblvgl/draw/sw/lv_draw_sw.h index 1618649..4496612 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw.h +++ b/include/liblvgl/draw/sw/lv_draw_sw.h @@ -14,10 +14,10 @@ extern "C" { * INCLUDES *********************/ #include "lv_draw_sw_blend.h" -#include "../lv_draw.h" -#include "../../misc/lv_area.h" -#include "../../misc/lv_color.h" -#include "../../hal/lv_hal_disp.h" +#include "liblvgl/draw/lv_draw.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/hal/lv_hal_disp.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sw/lv_draw_sw.mk b/include/liblvgl/draw/sw/lv_draw_sw.mk deleted file mode 100644 index 4625cbc..0000000 --- a/include/liblvgl/draw/sw/lv_draw_sw.mk +++ /dev/null @@ -1,17 +0,0 @@ -CSRCS += lv_draw_sw.c -CSRCS += lv_draw_sw_arc.c -CSRCS += lv_draw_sw_blend.c -CSRCS += lv_draw_sw_dither.c -CSRCS += lv_draw_sw_gradient.c -CSRCS += lv_draw_sw_img.c -CSRCS += lv_draw_sw_letter.c -CSRCS += lv_draw_sw_line.c -CSRCS += lv_draw_sw_polygon.c -CSRCS += lv_draw_sw_rect.c -CSRCS += lv_draw_sw_transform.c -CSRCS += lv_draw_sw_layer.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw" diff --git a/include/liblvgl/draw/sw/lv_draw_sw_blend.h b/include/liblvgl/draw/sw/lv_draw_sw_blend.h index 9a00e53..6fa859c 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw_blend.h +++ b/include/liblvgl/draw/sw/lv_draw_sw_blend.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../misc/lv_color.h" -#include "../../misc/lv_area.h" -#include "../../misc/lv_style.h" -#include "../lv_draw_mask.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_style.h" +#include "liblvgl/draw/lv_draw_mask.h" /********************* * DEFINES diff --git a/include/liblvgl/draw/sw/lv_draw_sw_dither.h b/include/liblvgl/draw/sw/lv_draw_sw_dither.h index 6362c5a..9785e18 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw_dither.h +++ b/include/liblvgl/draw/sw/lv_draw_sw_dither.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../core/lv_obj_pos.h" +#include "liblvgl/core/lv_obj_pos.h" /********************* diff --git a/include/liblvgl/draw/sw/lv_draw_sw_gradient.h b/include/liblvgl/draw/sw/lv_draw_sw_gradient.h index f5f3215..0860d50 100644 --- a/include/liblvgl/draw/sw/lv_draw_sw_gradient.h +++ b/include/liblvgl/draw/sw/lv_draw_sw_gradient.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../misc/lv_color.h" -#include "../../misc/lv_style.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_style.h" #include "lv_draw_sw_dither.h" /********************* diff --git a/include/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk b/include/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk deleted file mode 100644 index bc19e38..0000000 --- a/include/liblvgl/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk +++ /dev/null @@ -1,6 +0,0 @@ -CSRCS += lv_gpu_swm341_dma2d.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d" diff --git a/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h b/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h index 20b8922..baec7fe 100644 --- a/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h +++ b/include/liblvgl/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h @@ -13,9 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../misc/lv_color.h" -#include "../../hal/lv_hal_disp.h" -#include "../sw/lv_draw_sw.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/hal/lv_hal_disp.h" +#include "liblvgl/draw/sw/lv_draw_sw.h" #if LV_USE_GPU_SWM341_DMA2D diff --git a/include/liblvgl/extra/README.md b/include/liblvgl/extra/README.md deleted file mode 100644 index 80bb49d..0000000 --- a/include/liblvgl/extra/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Extra components - -This directory contains extra (optional) components to lvgl. -It's a good place for contributions as there are less strict expectations about the completeness and flexibility of the components here. - -In other words, if you have created a complex widget from other widgets, or modified an existing widget with special events, styles or animations, or have a new feature that could work as a plugin to lvgl feel free to the share it here. - -## How to contribute -- Create a [Pull request](https://docs.lvgl.io/8.0/CONTRIBUTING.html#pull-request) with your new content -- Please and follow the [Coding style](https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md) of LVGL -- Add setter/getter functions in pair -- Update [lv_conf_template.h](https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h) -- Add description in the [docs](https://github.com/lvgl/lvgl/tree/master/docs) -- Add [examples](https://github.com/lvgl/lvgl/tree/master/examples) -- Update the [changelog](https://github.com/lvgl/lvgl/tree/master/docs/CHANGELOG.md) -- Add yourself to the [Contributors](#contributors) section below. - -## Ideas -Here some ideas as inspiration feel free to contribute with ideas too. -- New [Calendar headers](https://github.com/lvgl/lvgl/tree/master/src/extra/widgets/calendar) -- Color picker with RGB and or HSV bars -- Ruler, horizontal or vertical with major and minor ticks and labels -- New [List items types](https://github.com/lvgl/lvgl/tree/master/src/extra/widgets/list) -- [Preloaders](https://www.google.com/search?q=preloader&sxsrf=ALeKk01ddA4YB0WEgLLN1bZNSm8YER7pkg:1623080551559&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiwoN6d7oXxAhVuw4sKHVedBB4Q_AUoAXoECAEQAw&biw=952&bih=940) -- Drop-down list with a container to which content can be added -- 9 patch button: Similar to [lv_imgbtn](https://docs.lvgl.io/8.0/widgets/extra/imgbtn.html) but 9 images for 4 corner, 4 sides and the center - -## Contributors -- lv_animimg: @ZhaoQiang-b45475 -- lv_span: @guoweilkd -- lv_menu: @HX2003 \ No newline at end of file diff --git a/include/liblvgl/extra/layouts/flex/lv_flex.h b/include/liblvgl/extra/layouts/flex/lv_flex.h index 58c3221..d961961 100644 --- a/include/liblvgl/extra/layouts/flex/lv_flex.h +++ b/include/liblvgl/extra/layouts/flex/lv_flex.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_FLEX /********************* diff --git a/include/liblvgl/extra/layouts/grid/lv_grid.h b/include/liblvgl/extra/layouts/grid/lv_grid.h index 5c4f767..8e57fd9 100644 --- a/include/liblvgl/extra/layouts/grid/lv_grid.h +++ b/include/liblvgl/extra/layouts/grid/lv_grid.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_GRID /********************* diff --git a/include/liblvgl/extra/libs/bmp/lv_bmp.h b/include/liblvgl/extra/libs/bmp/lv_bmp.h index db1e540..3d9e948 100644 --- a/include/liblvgl/extra/libs/bmp/lv_bmp.h +++ b/include/liblvgl/extra/libs/bmp/lv_bmp.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_BMP /********************* diff --git a/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h b/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h index 8c7fc26..f3a365c 100644 --- a/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h +++ b/include/liblvgl/extra/libs/ffmpeg/lv_ffmpeg.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_FFMPEG != 0 /********************* diff --git a/include/liblvgl/extra/libs/freetype/arial.ttf b/include/liblvgl/extra/libs/freetype/arial.ttf deleted file mode 100644 index 886789b..0000000 Binary files a/include/liblvgl/extra/libs/freetype/arial.ttf and /dev/null differ diff --git a/include/liblvgl/extra/libs/freetype/lv_freetype.h b/include/liblvgl/extra/libs/freetype/lv_freetype.h index 247a7fb..e576c2e 100644 --- a/include/liblvgl/extra/libs/freetype/lv_freetype.h +++ b/include/liblvgl/extra/libs/freetype/lv_freetype.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_FREETYPE /********************* diff --git a/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h b/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h index 285d598..2b0adfd 100644 --- a/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h +++ b/include/liblvgl/extra/libs/fsdrv/lv_fsdrv.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" /********************* * DEFINES diff --git a/include/liblvgl/extra/libs/gif/gifdec.h b/include/liblvgl/extra/libs/gif/gifdec.h index b68fab5..eaa4cad 100644 --- a/include/liblvgl/extra/libs/gif/gifdec.h +++ b/include/liblvgl/extra/libs/gif/gifdec.h @@ -2,7 +2,7 @@ #define GIFDEC_H #include -#include "../../../misc/lv_fs.h" +#include "liblvgl/misc/lv_fs.h" #if LV_USE_GIF @@ -29,7 +29,7 @@ typedef struct gd_GIF { int32_t anim_start; uint16_t width, height; uint16_t depth; - int32_t loop_count; + uint16_t loop_count; gd_GCE gce; gd_Palette *palette; gd_Palette lct, gct; diff --git a/include/liblvgl/extra/libs/gif/lv_gif.h b/include/liblvgl/extra/libs/gif/lv_gif.h index d8c93db..b40b690 100644 --- a/include/liblvgl/extra/libs/gif/lv_gif.h +++ b/include/liblvgl/extra/libs/gif/lv_gif.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_GIF #include "gifdec.h" diff --git a/include/liblvgl/extra/libs/png/lodepng.h b/include/liblvgl/extra/libs/png/lodepng.h index dbfed72..4068d4b 100644 --- a/include/liblvgl/extra/libs/png/lodepng.h +++ b/include/liblvgl/extra/libs/png/lodepng.h @@ -28,7 +28,7 @@ freely, subject to the following restrictions: #include /*for size_t*/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_PNG extern const char* LODEPNG_VERSION_STRING; diff --git a/include/liblvgl/extra/libs/png/lv_png.h b/include/liblvgl/extra/libs/png/lv_png.h index 4380472..ef63454 100644 --- a/include/liblvgl/extra/libs/png/lv_png.h +++ b/include/liblvgl/extra/libs/png/lv_png.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_PNG /********************* diff --git a/include/liblvgl/extra/libs/qrcode/lv_qrcode.h b/include/liblvgl/extra/libs/qrcode/lv_qrcode.h index b0752ac..c8db4e5 100644 --- a/include/liblvgl/extra/libs/qrcode/lv_qrcode.h +++ b/include/liblvgl/extra/libs/qrcode/lv_qrcode.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_QRCODE /********************* diff --git a/include/liblvgl/extra/libs/rlottie/lv_rlottie.h b/include/liblvgl/extra/libs/rlottie/lv_rlottie.h index d66dc22..a8aca7b 100644 --- a/include/liblvgl/extra/libs/rlottie/lv_rlottie.h +++ b/include/liblvgl/extra/libs/rlottie/lv_rlottie.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_RLOTTIE /********************* diff --git a/include/liblvgl/extra/libs/sjpg/tjpgd.h b/include/liblvgl/extra/libs/sjpg/tjpgd.h index b255ccf..866e6b3 100644 --- a/include/liblvgl/extra/libs/sjpg/tjpgd.h +++ b/include/liblvgl/extra/libs/sjpg/tjpgd.h @@ -8,7 +8,7 @@ extern "C" { #endif -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_SJPG #include "tjpgdcnf.h" diff --git a/include/liblvgl/extra/lv_extra.mk b/include/liblvgl/extra/lv_extra.mk deleted file mode 100644 index 1afcc7b..0000000 --- a/include/liblvgl/extra/lv_extra.mk +++ /dev/null @@ -1 +0,0 @@ -CSRCS += $(shell find -L $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra -name \*.c) diff --git a/include/liblvgl/extra/others/fragment/README.md b/include/liblvgl/extra/others/fragment/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/include/liblvgl/extra/others/fragment/lv_fragment.h b/include/liblvgl/extra/others/fragment/lv_fragment.h index da30b39..9b7312f 100644 --- a/include/liblvgl/extra/others/fragment/lv_fragment.h +++ b/include/liblvgl/extra/others/fragment/lv_fragment.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_FRAGMENT -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/extra/others/gridnav/lv_gridnav.h b/include/liblvgl/extra/others/gridnav/lv_gridnav.h index f480ded..8939120 100644 --- a/include/liblvgl/extra/others/gridnav/lv_gridnav.h +++ b/include/liblvgl/extra/others/gridnav/lv_gridnav.h @@ -53,7 +53,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_GRIDNAV diff --git a/include/liblvgl/extra/others/ime/lv_ime_pinyin.h b/include/liblvgl/extra/others/ime/lv_ime_pinyin.h index 3ff7bb9..2d70d29 100644 --- a/include/liblvgl/extra/others/ime/lv_ime_pinyin.h +++ b/include/liblvgl/extra/others/ime/lv_ime_pinyin.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_IME_PINYIN != 0 diff --git a/include/liblvgl/extra/others/imgfont/lv_imgfont.h b/include/liblvgl/extra/others/imgfont/lv_imgfont.h index 5069b62..4fb6f78 100644 --- a/include/liblvgl/extra/others/imgfont/lv_imgfont.h +++ b/include/liblvgl/extra/others/imgfont/lv_imgfont.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_IMGFONT diff --git a/include/liblvgl/extra/others/monkey/lv_monkey.h b/include/liblvgl/extra/others/monkey/lv_monkey.h index bf5e13c..589daf1 100644 --- a/include/liblvgl/extra/others/monkey/lv_monkey.h +++ b/include/liblvgl/extra/others/monkey/lv_monkey.h @@ -12,7 +12,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "liblvgl/lvgl.h" #if LV_USE_MONKEY != 0 diff --git a/include/liblvgl/extra/others/msg/lv_msg.h b/include/liblvgl/extra/others/msg/lv_msg.h index 0ac2f77..64dc0d4 100644 --- a/include/liblvgl/extra/others/msg/lv_msg.h +++ b/include/liblvgl/extra/others/msg/lv_msg.h @@ -13,14 +13,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_MSG /********************* * DEFINES *********************/ -#define LV_MSG_ID_ANY UINT32_MAX -LV_EXPORT_CONST_INT(LV_MSG_ID_ANY); /********************** * TYPEDEFS @@ -72,14 +70,6 @@ void * lv_msg_subsribe_obj(uint32_t msg_id, lv_obj_t * obj, void * user_data); */ void lv_msg_unsubscribe(void * s); -/** - * Unsubscribe an object from a message ID - * @param msg_id the message ID to unsubcribe from or `LV_MSG_ID_ANY` for any message ID - * @param obj the object to unsubscribe or NULL for any object - * @return number of unsubscriptions - */ -uint32_t lv_msg_unsubscribe_obj(uint32_t msg_id, lv_obj_t * obj); - /** * Send a message with a given ID and payload * @param msg_id ID of the message to send @@ -115,17 +105,6 @@ void * lv_msg_get_user_data(lv_msg_t * m); */ lv_msg_t * lv_event_get_msg(lv_event_t * e); -/*Fix typo*/ -static inline void * lv_msg_subscribe(uint32_t msg_id, lv_msg_subscribe_cb_t cb, void * user_data) -{ - return lv_msg_subsribe(msg_id, cb, user_data); -} - -static inline void * lv_msg_subscribe_obj(uint32_t msg_id, lv_obj_t * obj, void * user_data) -{ - return lv_msg_subsribe_obj(msg_id, obj, user_data); -} - /********************** * GLOBAL VARIABLES **********************/ diff --git a/include/liblvgl/extra/others/snapshot/lv_snapshot.h b/include/liblvgl/extra/others/snapshot/lv_snapshot.h index 6451926..33d9741 100644 --- a/include/liblvgl/extra/others/snapshot/lv_snapshot.h +++ b/include/liblvgl/extra/others/snapshot/lv_snapshot.h @@ -16,8 +16,8 @@ extern "C" { #include #include -#include "../../../lv_conf_internal.h" -#include "../../../core/lv_obj.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/extra/themes/basic/lv_theme_basic.h b/include/liblvgl/extra/themes/basic/lv_theme_basic.h index 93a8fa8..06d6828 100644 --- a/include/liblvgl/extra/themes/basic/lv_theme_basic.h +++ b/include/liblvgl/extra/themes/basic/lv_theme_basic.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_THEME_BASIC diff --git a/include/liblvgl/extra/themes/default/lv_theme_default.h b/include/liblvgl/extra/themes/default/lv_theme_default.h index 5b1fd91..7fab5be 100644 --- a/include/liblvgl/extra/themes/default/lv_theme_default.h +++ b/include/liblvgl/extra/themes/default/lv_theme_default.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_THEME_DEFAULT diff --git a/include/liblvgl/extra/themes/mono/lv_theme_mono.h b/include/liblvgl/extra/themes/mono/lv_theme_mono.h index 10b8f18..3d907ff 100644 --- a/include/liblvgl/extra/themes/mono/lv_theme_mono.h +++ b/include/liblvgl/extra/themes/mono/lv_theme_mono.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_THEME_MONO diff --git a/include/liblvgl/extra/widgets/animimg/lv_animimg.h b/include/liblvgl/extra/widgets/animimg/lv_animimg.h index 5b17f0a..9ffe621 100644 --- a/include/liblvgl/extra/widgets/animimg/lv_animimg.h +++ b/include/liblvgl/extra/widgets/animimg/lv_animimg.h @@ -37,7 +37,7 @@ typedef struct { lv_img_t img; lv_anim_t anim; /*picture sequence */ - const void ** dsc; + lv_img_dsc_t ** dsc; int8_t pic_count; } lv_animimg_t; @@ -69,7 +69,7 @@ lv_obj_t * lv_animimg_create(lv_obj_t * parent); * @param dsc pointer to a series images * @param num images' number */ -void lv_animimg_set_src(lv_obj_t * img, const void * dsc[], uint8_t num); +void lv_animimg_set_src(lv_obj_t * img, lv_img_dsc_t * dsc[], uint8_t num); /** * Startup the image animation. diff --git a/include/liblvgl/extra/widgets/list/lv_list.h b/include/liblvgl/extra/widgets/list/lv_list.h index 6142aac..e9bb626 100644 --- a/include/liblvgl/extra/widgets/list/lv_list.h +++ b/include/liblvgl/extra/widgets/list/lv_list.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "liblvgl/core/lv_obj.h" -#include "../../layouts/flex/lv_flex.h" +#include "liblvgl/extra/layouts/flex/lv_flex.h" #if LV_USE_LIST diff --git a/include/liblvgl/font/korean.ttf b/include/liblvgl/font/korean.ttf deleted file mode 100644 index e0ec117..0000000 Binary files a/include/liblvgl/font/korean.ttf and /dev/null differ diff --git a/include/liblvgl/font/lv_font.h b/include/liblvgl/font/lv_font.h index d32902d..3c0a689 100644 --- a/include/liblvgl/font/lv_font.h +++ b/include/liblvgl/font/lv_font.h @@ -271,11 +271,6 @@ LV_FONT_DECLARE(pros_font_dejavu_mono_40); LV_FONT_DECLARE(pros_font_dejavu_mono_40_latin_sup); #endif -/*Declare the custom (user defined) fonts*/ -#ifdef LV_FONT_CUSTOM_DECLARE -LV_FONT_CUSTOM_DECLARE -#endif - /** * Just a wrapper around LV_FONT_DEFAULT because it might be more convenient to use a function in some cases * @return pointer to LV_FONT_DEFAULT diff --git a/include/liblvgl/font/lv_font.mk b/include/liblvgl/font/lv_font.mk deleted file mode 100644 index 2201b73..0000000 --- a/include/liblvgl/font/lv_font.mk +++ /dev/null @@ -1,36 +0,0 @@ -CSRCS += lv_font.c -CSRCS += lv_font_fmt_txt.c -CSRCS += lv_font_loader.c - -CSRCS += lv_font_dejavu_16_persian_hebrew.c -CSRCS += lv_font_montserrat_8.c -CSRCS += lv_font_montserrat_10.c -CSRCS += lv_font_montserrat_12.c -CSRCS += lv_font_montserrat_12_subpx.c -CSRCS += lv_font_montserrat_14.c -CSRCS += lv_font_montserrat_16.c -CSRCS += lv_font_montserrat_18.c -CSRCS += lv_font_montserrat_20.c -CSRCS += lv_font_montserrat_22.c -CSRCS += lv_font_montserrat_24.c -CSRCS += lv_font_montserrat_26.c -CSRCS += lv_font_montserrat_28.c -CSRCS += lv_font_montserrat_28_compressed.c -CSRCS += lv_font_montserrat_30.c -CSRCS += lv_font_montserrat_32.c -CSRCS += lv_font_montserrat_34.c -CSRCS += lv_font_montserrat_36.c -CSRCS += lv_font_montserrat_38.c -CSRCS += lv_font_montserrat_40.c -CSRCS += lv_font_montserrat_42.c -CSRCS += lv_font_montserrat_44.c -CSRCS += lv_font_montserrat_46.c -CSRCS += lv_font_montserrat_48.c -CSRCS += lv_font_simsun_16_cjk.c -CSRCS += lv_font_unscii_8.c -CSRCS += lv_font_unscii_16.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font" diff --git a/include/liblvgl/font/lv_symbol_def.h b/include/liblvgl/font/lv_symbol_def.h index 696daf1..1055392 100644 --- a/include/liblvgl/font/lv_symbol_def.h +++ b/include/liblvgl/font/lv_symbol_def.h @@ -5,7 +5,7 @@ extern "C" { #endif -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" /*------------------------------- * Symbols from "normal" font diff --git a/include/liblvgl/hal/lv_hal.mk b/include/liblvgl/hal/lv_hal.mk deleted file mode 100644 index c35ec2d..0000000 --- a/include/liblvgl/hal/lv_hal.mk +++ /dev/null @@ -1,8 +0,0 @@ -CSRCS += lv_hal_disp.c -CSRCS += lv_hal_indev.c -CSRCS += lv_hal_tick.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal" diff --git a/include/liblvgl/hal/lv_hal_disp.h b/include/liblvgl/hal/lv_hal_disp.h index d3425fe..5b36916 100644 --- a/include/liblvgl/hal/lv_hal_disp.h +++ b/include/liblvgl/hal/lv_hal_disp.h @@ -18,11 +18,11 @@ extern "C" { #include #include #include "lv_hal.h" -#include "../draw/lv_draw.h" -#include "../misc/lv_color.h" -#include "../misc/lv_area.h" -#include "../misc/lv_ll.h" -#include "../misc/lv_timer.h" +#include "liblvgl/draw/lv_draw.h" +#include "liblvgl/misc/lv_color.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_ll.h" +#include "liblvgl/misc/lv_timer.h" /********************* * DEFINES diff --git a/include/liblvgl/hal/lv_hal_indev.h b/include/liblvgl/hal/lv_hal_indev.h index 5bbcf53..630d471 100644 --- a/include/liblvgl/hal/lv_hal_indev.h +++ b/include/liblvgl/hal/lv_hal_indev.h @@ -15,12 +15,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include -#include "../misc/lv_area.h" -#include "../misc/lv_timer.h" +#include "liblvgl/misc/lv_area.h" +#include "liblvgl/misc/lv_timer.h" /********************* * DEFINES @@ -141,7 +141,6 @@ typedef struct _lv_indev_proc_t { struct { /*Pointer and button data*/ lv_point_t act_point; /**< Current point of input device.*/ - lv_point_t indev_point; lv_point_t last_point; /**< Last point of input device.*/ lv_point_t last_raw_point; /**< Last point read from read_cb. */ lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/ diff --git a/include/liblvgl/hal/lv_hal_tick.h b/include/liblvgl/hal/lv_hal_tick.h index 949f56b..407fa42 100644 --- a/include/liblvgl/hal/lv_hal_tick.h +++ b/include/liblvgl/hal/lv_hal_tick.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include diff --git a/include/liblvgl/llemu.h b/include/liblvgl/llemu.h index 550e46f..c3c4e6d 100644 --- a/include/liblvgl/llemu.h +++ b/include/liblvgl/llemu.h @@ -1,438 +1,438 @@ -/** - * \file liblvgl/llemu.h - * \ingroup c-llemu - * - * Legacy LCD Emulator - * - * \details This file defines a high-level API for emulating the three-button, UART-based - * VEX LCD, containing a set of functions that facilitate the use of a software- - * emulated version of the classic VEX LCD module. - * - * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-llemu LLEMU C API - * @{ - * LLEMU - Legacy Lcd EMUlator - * - * \image html llemu/llemu-3.8.png - * - * LLEMU provides a virtual 40x8 LCD screen with 3 buttons. The user can set the - * text of the screen and set create functions that are run when the buttons are - * pressed. - * - * LLEMU is a emulation of the UART-based LCD screens that were available with - * VEX's cortex product line. - * @} - */ - -#ifndef _LIBLVGL_LLEMU_H_ -#define _LIBLVGL_LLEMU_H_ - -#include -#include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wignored-qualifiers" -#include "liblvgl/lvgl.h" -#pragma GCC diagnostic pop - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -typedef void (*lcd_btn_cb_fn_t)(void); - -#define LCD_BTN_LEFT 4 -#define LCD_BTN_CENTER 2 -#define LCD_BTN_RIGHT 1 - -typedef struct lcd_s { - lv_obj_t* frame; - lv_obj_t* screen; - lv_obj_t* lcd_text[8]; - lv_obj_t* btn_container; - lv_obj_t* btns[3]; // < 0 => left; 1 => center; 2 => right - lcd_btn_cb_fn_t callbacks[3]; // < 0 => left; 1 => center; 2 => right - volatile uint8_t touch_bits; // < 4 => left; 2 => center; 1 => right (no - // multitouch support) -} lcd_s_t; - -/** - * \ingroup c-llemu - */ - -/** - * \addtogroup c-llemu - * @{ - */ - -/** - * \enum lcd_text_align_e - * - * @brief Represents how to align the text in the LCD - */ -typedef enum lcd_text_align_e { - /// Align the text to the left side of LCD line - LCD_TEXT_ALIGN_LEFT = 0, - /// Align the text to the center of the LCD line - LCD_TEXT_ALIGN_CENTER = 1, - /// Align the text to the right side of the LCD line - LCD_TEXT_ALIGN_RIGHT = 2 -} text_align_e_t; - -/// @} - -#ifdef __cplusplus - -/** - * \ingroup c-llemu - */ -namespace c { -#endif - -/** - * \ingroup c-llemu - */ - -/** - * \addtogroup c-llemu - * @{ - */ - -/** - * Checks whether the emulated three-button LCD has already been initialized. - * - * \return True if the LCD has been initialized or false if not. - * - * \b Example - * \code - * if (pros::c::lcd_is_initialized()) { - * pros::c::lcd_print("LLEMU!"); - * } - * else { - * printf("Error: LLEMU is not initialized\n"); - * } - * \endcode - */ -bool lcd_is_initialized(void); - -/** - * Creates an emulation of the three-button, UART-based VEX LCD on the display. - * - * \return True if the LCD was successfully initialized, or false if it has - * already been initialized. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void initialize() { - * if (pros::c::lcd_initialize()) { - * pros::c::lcd_print("LLEMU!"); - * } - * else { - * printf("Error: LLEMU could not initailize\n"); - * } - * } - * \endcode - */ -bool lcd_initialize(void); - -/** - * Turns off the Legacy LCD Emulator. - * - * Calling this function will clear the entire display, and you will not be able - * to call any further LLEMU functions until another call to lcd_initialize. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void disabled() { - * pros::c::lcd_shutdown(); - * } - * \endcode - */ -bool lcd_shutdown(void); - -/** - * Displays a formatted string on the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line on which to display the text [0-7] - * \param fmt - * Format string - * \param ... - * Optional list of arguments for the format string - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_print(0, "My formatted text: %d!", 2); - * } - * \endcode - */ -bool lcd_print(int16_t line, const char* fmt, ...); - -/** - * Displays a string on the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line on which to display the text [0-7] - * \param text - * The text to display - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_set_text(0, "My custom LLEMU text!"); - * } - * \endcode - */ -bool lcd_set_text(int16_t line, const char* text); - -/** - * Clears the contents of the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_clear(); // Clear the LCD screen - * } - * \endcode - */ -bool lcd_clear(void); - -/** - * Clears the contents of a line of the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line to clear - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_clear_line(0); // Clear line 0 - * } - * \endcode - */ -bool lcd_clear_line(int16_t line); - -/** - * Registers a callback function for the leftmost button. - * - * When the leftmost button on the emulated three-button LCD is pressed, the - * user-provided callback function will be invoked. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * - * \param cb - * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void left_callback() { - * static int i = 0; - * - * i++; - * pros::c::lcd_print(0, "Left button pressed %i times", i); - * } - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_register_btn0_cb(); - * } - * \endcode - */ -bool lcd_register_btn0_cb(lcd_btn_cb_fn_t cb); - -/** - * Registers a callback function for the center button. - * - * When the center button on the emulated three-button LCD is pressed, the - * user-provided callback function will be invoked. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * - * \param cb - * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void center_callback() { - * static int i = 0; - * - * i++; - * pros::c::lcd_print(0, "Center button pressed %i times", i); - * } - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_register_btn1_cb(); - * } - * \endcode - */ -bool lcd_register_btn1_cb(lcd_btn_cb_fn_t cb); - -/** - * Registers a callback function for the rightmost button. - * - * When the rightmost button on the emulated three-button LCD is pressed, the - * user-provided callback function will be invoked. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * - * \param cb - * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void right_callback() { - * static int i = 0; - * - * i++; - * pros::c::lcd_print(0, "Right button pressed %i times", i); - * } - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_register_btn2_cb(); - * } - * \endcode - */ -bool lcd_register_btn2_cb(lcd_btn_cb_fn_t cb); - -/** - * Gets the button status from the emulated three-button LCD. - * - * The value returned is a 3-bit integer where 1 0 0 indicates the left button - * is pressed, 0 1 0 indicates the center button is pressed, and 0 0 1 - * indicates the right button is pressed. 0 is returned if no buttons are - * currently being pressed. - * - * Note that this function is provided for legacy API compatibility purposes, - * with the caveat that the V5 touch screen does not actually support pressing - * multiple points on the screen at the same time. - * - * \return The buttons pressed as a bit mask - */ -uint8_t lcd_read_buttons(void); - -/** - * Changes the alignment of text on the LCD background - * - * \param alignment - * An enum specifying the alignment. Available alignments are: - * TEXT_ALIGN_LEFT - * TEXT_ALIGN_RIGHT - * TEXT_ALIGN_CENTER - * - * \b Example - * \code - * #include "pros/llemu.h" - * - * void initialize() { - * pros::c::lcd_initialize(); - * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::LEFT); - * pros::c::lcd_print(0, "Left Aligned Text"); - * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::CENTER); - * pros::c::lcd_print(1, "Center Aligned Text"); - * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::RIGHT); - * pros::c::lcd_print(2, "Right Aligned Text"); - * } - * \endcode - */ -void lcd_set_text_align(text_align_e_t alignment); - - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} // extern "C" -#endif -#endif // _LIBLVGL_LLEMU_H_ +/** + * \file liblvgl/llemu.h + * \ingroup c-llemu + * + * Legacy LCD Emulator + * + * \details This file defines a high-level API for emulating the three-button, UART-based + * VEX LCD, containing a set of functions that facilitate the use of a software- + * emulated version of the classic VEX LCD module. + * + * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-llemu LLEMU C API + * @{ + * LLEMU - Legacy Lcd EMUlator + * + * \image html llemu/llemu-3.8.png + * + * LLEMU provides a virtual 40x8 LCD screen with 3 buttons. The user can set the + * text of the screen and set create functions that are run when the buttons are + * pressed. + * + * LLEMU is a emulation of the UART-based LCD screens that were available with + * VEX's cortex product line. + * @} + */ + +#ifndef _LIBLVGL_LLEMU_H_ +#define _LIBLVGL_LLEMU_H_ + +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#include "liblvgl/lvgl.h" +#pragma GCC diagnostic pop + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +typedef void (*lcd_btn_cb_fn_t)(void); + +#define LCD_BTN_LEFT 4 +#define LCD_BTN_CENTER 2 +#define LCD_BTN_RIGHT 1 + +typedef struct lcd_s { + lv_obj_t* frame; + lv_obj_t* screen; + lv_obj_t* lcd_text[8]; + lv_obj_t* btn_container; + lv_obj_t* btns[3]; // < 0 => left; 1 => center; 2 => right + lcd_btn_cb_fn_t callbacks[3]; // < 0 => left; 1 => center; 2 => right + volatile uint8_t touch_bits; // < 4 => left; 2 => center; 1 => right (no + // multitouch support) +} lcd_s_t; + +/** + * \ingroup c-llemu + */ + +/** + * \addtogroup c-llemu + * @{ + */ + +/** + * \enum lcd_text_align_e + * + * @brief Represents how to align the text in the LCD + */ +typedef enum lcd_text_align_e { + /// Align the text to the left side of LCD line + LCD_TEXT_ALIGN_LEFT = 0, + /// Align the text to the center of the LCD line + LCD_TEXT_ALIGN_CENTER = 1, + /// Align the text to the right side of the LCD line + LCD_TEXT_ALIGN_RIGHT = 2 +} text_align_e_t; + +/// @} + +#ifdef __cplusplus + +/** + * \ingroup c-llemu + */ +namespace c { +#endif + +/** + * \ingroup c-llemu + */ + +/** + * \addtogroup c-llemu + * @{ + */ + +/** + * Checks whether the emulated three-button LCD has already been initialized. + * + * \return True if the LCD has been initialized or false if not. + * + * \b Example + * \code + * if (pros::c::lcd_is_initialized()) { + * pros::c::lcd_print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU is not initialized\n"); + * } + * \endcode + */ +bool lcd_is_initialized(void); + +/** + * Creates an emulation of the three-button, UART-based VEX LCD on the display. + * + * \return True if the LCD was successfully initialized, or false if it has + * already been initialized. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * if (pros::c::lcd_initialize()) { + * pros::c::lcd_print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU could not initailize\n"); + * } + * } + * \endcode + */ +bool lcd_initialize(void); + +/** + * Turns off the Legacy LCD Emulator. + * + * Calling this function will clear the entire display, and you will not be able + * to call any further LLEMU functions until another call to lcd_initialize. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void disabled() { + * pros::c::lcd_shutdown(); + * } + * \endcode + */ +bool lcd_shutdown(void); + +/** + * Displays a formatted string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param fmt + * Format string + * \param ... + * Optional list of arguments for the format string + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_print(0, "My formatted text: %d!", 2); + * } + * \endcode + */ +bool lcd_print(int16_t line, const char* fmt, ...); + +/** + * Displays a string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param text + * The text to display + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_set_text(0, "My custom LLEMU text!"); + * } + * \endcode + */ +bool lcd_set_text(int16_t line, const char* text); + +/** + * Clears the contents of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_clear(); // Clear the LCD screen + * } + * \endcode + */ +bool lcd_clear(void); + +/** + * Clears the contents of a line of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line to clear + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_clear_line(0); // Clear line 0 + * } + * \endcode + */ +bool lcd_clear_line(int16_t line); + +/** + * Registers a callback function for the leftmost button. + * + * When the leftmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void left_callback() { + * static int i = 0; + * + * i++; + * pros::c::lcd_print(0, "Left button pressed %i times", i); + * } + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_register_btn0_cb(); + * } + * \endcode + */ +bool lcd_register_btn0_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the center button. + * + * When the center button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void center_callback() { + * static int i = 0; + * + * i++; + * pros::c::lcd_print(0, "Center button pressed %i times", i); + * } + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_register_btn1_cb(); + * } + * \endcode + */ +bool lcd_register_btn1_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the rightmost button. + * + * When the rightmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t (void (*cb)(void)) + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void right_callback() { + * static int i = 0; + * + * i++; + * pros::c::lcd_print(0, "Right button pressed %i times", i); + * } + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_register_btn2_cb(); + * } + * \endcode + */ +bool lcd_register_btn2_cb(lcd_btn_cb_fn_t cb); + +/** + * Gets the button status from the emulated three-button LCD. + * + * The value returned is a 3-bit integer where 1 0 0 indicates the left button + * is pressed, 0 1 0 indicates the center button is pressed, and 0 0 1 + * indicates the right button is pressed. 0 is returned if no buttons are + * currently being pressed. + * + * Note that this function is provided for legacy API compatibility purposes, + * with the caveat that the V5 touch screen does not actually support pressing + * multiple points on the screen at the same time. + * + * \return The buttons pressed as a bit mask + */ +uint8_t lcd_read_buttons(void); + +/** + * Changes the alignment of text on the LCD background + * + * \param alignment + * An enum specifying the alignment. Available alignments are: + * TEXT_ALIGN_LEFT + * TEXT_ALIGN_RIGHT + * TEXT_ALIGN_CENTER + * + * \b Example + * \code + * #include "pros/llemu.h" + * + * void initialize() { + * pros::c::lcd_initialize(); + * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::LEFT); + * pros::c::lcd_print(0, "Left Aligned Text"); + * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::CENTER); + * pros::c::lcd_print(1, "Center Aligned Text"); + * pros::c::lcd_set_alignment(pros::c::lcd_Text_Align::RIGHT); + * pros::c::lcd_print(2, "Right Aligned Text"); + * } + * \endcode + */ +void lcd_set_text_align(text_align_e_t alignment); + + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} // extern "C" +#endif +#endif // _LIBLVGL_LLEMU_H_ diff --git a/include/liblvgl/llemu.hpp b/include/liblvgl/llemu.hpp index 6fbd29b..78d3193 100644 --- a/include/liblvgl/llemu.hpp +++ b/include/liblvgl/llemu.hpp @@ -1,373 +1,373 @@ -/** - * \file liblvgl/llemu.hpp - * - * \ingroup cpp-llemu - * - * Legacy LCD Emulator - * - * \details This file defines a high-level API for emulating the three-button, UART-based - * VEX LCD, containing a set of functions that facilitate the use of a software- - * emulated version of the classic VEX LCD module. - * - * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup cpp-llemu LLEMU C++ API - * @{ - * LLEMU - Legacy Lcd EMUlator - * - * \image html llemu/llemu-3.8.png - * - * LLEMU provides a virtual 40x8 LCD screen with 3 buttons. The user can set the - * text of the screen and set create functions that are run when the buttons are - * pressed. - * - * LLEMU is a emulation of the UART-based LCD screens that were available with - * VEX's cortex product line. - * @} - */ - -#ifndef _LIBLVGL_LLEMU_HPP_ -#define _LIBLVGL_LLEMU_HPP_ - -#include -#include - -#include "liblvgl/llemu.h" - -namespace pros { - -/** - * \ingroup cpp-llemu - */ -namespace lcd { - -/** - * \ingroup cpp-llemu - */ - -/** - * \addtogroup cpp-llemu - * @{ - */ - -/** - * \enum Text_Align - * - * @brief Represents how to align the text in the LCD - */ -enum class Text_Align { - /// Align the text to the left side of LCD line - LEFT = 0, - /// Align the text to the center of the LCD line - CENTER = 1, - /// Align the text to the right side of the LCD line - RIGHT = 2 -}; - -/** - * Checks whether the emulated three-button LCD has already been initialized. - * - * \return True if the LCD has been initialized or false if not. - * - * \b Example - * \code - * if (pros::lcd::is_initialized()) { - * pros::lcd::print("LLEMU!"); - * } - * else { - * printf("Error: LLEMU is not initialized\n"); - * } - * \endcode - */ -bool is_initialized(void); - -/** - * Creates an emulation of the three-button, UART-based VEX LCD on the display. - * - * \return True if the LCD was successfully initialized, or false if it has - * already been initialized. - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * if (pros::lcd::initialize()) { - * pros::lcd::print("LLEMU!"); - * } - * else { - * printf("Error: LLEMU could not initailize\n"); - * } - * } - * \endcode - */ -bool initialize(void); - -/** - * Turns off the Legacy LCD Emulator. - * - * Calling this function will clear the entire display, and you will not be able - * to call any further LLEMU functions until another call to lcd_initialize. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void disabled() { - * pros::lcd::shutdown(); - * } - * \endcode - */ -bool shutdown(void); - -/** - * Displays a string on the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line on which to display the text [0-7] - * \param text - * The text to display - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::set_text(0, "My custom LLEMU text!"); - * } - * \endcode - */ -bool set_text(std::int16_t line, std::string text); - -/** - * Clears the contents of the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::clear(); // Clear the LCD screen - * } - * \endcode - */ -bool clear(void); - -/** - * Clears the contents of a line of the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line to clear - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::clear_line(0); // Clear line 0 - * } - * \endcode - */ -bool clear_line(std::int16_t line); - -using lcd_btn_cb_fn_t = void (*)(void); - -/** - * Registers a callback function for the leftmost button. - * - * When the leftmost button on the emulated three-button LCD is pressed, the - * user-provided callback function will be invoked. - * - * \param cb - * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void left_callback() { - * static int i = 0; - * - * pros::lcd::print(0, "Left button pressed %i times", i); - * i++ - * } - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::register_btn0_cb(); - * } - * \endcode - */ -void register_btn0_cb(lcd_btn_cb_fn_t cb); - -/** - * Registers a callback function for the center button. - * - * When the center button on the emulated three-button LCD is pressed, the - * user-provided callback function will be invoked. - * - * \param cb - * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) - * - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void center_callback() { - * static int i = 0; - * - * pros::lcd::print(0, "Center button pressed %i times", i); - * i++ - * } - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::register_btn1_cb(); - * } - * \endcode - */ -void register_btn1_cb(lcd_btn_cb_fn_t cb); - -/** - * Registers a callback function for the rightmost button. - * - * When the rightmost button on the emulated three-button LCD is pressed, the - * user-provided callback function will be invoked. - * - * \param cb - * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void right_callback() { - * static int i = 0; - * - * pros::lcd::print(0, "Right button pressed %i times", i); - * i++ - * } - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::register_btn2_cb(); - * } - * \endcode - */ -void register_btn2_cb(lcd_btn_cb_fn_t cb); - -/** - * Sets the alignment to use for subsequent calls that print text to a line. - * - * \param alignment - * An enum specifying the alignment. Available alignments are: - * TEXT_ALIGN_LEFT - * TEXT_ALIGN_RIGHT - * TEXT_ALIGN_CENTER - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::set_alignment(pros::lcd::Text_Align::LEFT); - * pros::lcd::print(0, "Left Aligned Text"); - * pros::lcd::set_alignment(pros::lcd::Text_Align::CENTER); - * pros::lcd::print(1, "Center Aligned Text"); - * pros::lcd::set_alignment(pros::lcd::Text_Align::RIGHT); - * pros::lcd::print(2, "Right Aligned Text"); - * } - * \endcode - */ -void set_text_align(Text_Align alignment); - -/** - * Gets the button status from the emulated three-button LCD. - * - * The value returned is a 3-bit integer where 1 0 0 indicates the left button - * is pressed, 0 1 0 indicates the center button is pressed, and 0 0 1 - * indicates the right button is pressed. 0 is returned if no buttons are - * currently being pressed. - * - * Note that this function is provided for legacy API compatibility purposes, - * with the caveat that the V5 touch screen does not actually support pressing - * multiple points on the screen at the same time. - * - * \return The buttons pressed as a bit mask - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * pros::lcd::initialize(); - * } - * - * void opcontrol() { - * while(true) { - * std::uint8_t state = pros::lcd::read_buttons(); - * pros::lcd::print(0, "%d %d %d", - * (state & LCD_BTN_LEFT) >> 2 - * (state & LCD_BTN_CENTER) >> 1, - * (state & LCD_BTN_RIGHT) >> 0 - * ); - * - * pros::delay(10); - * } - * } - * \endcode - */ -std::uint8_t read_buttons(void); - -///@} - -} // namespace lcd -} // namespace pros - - -#endif // _LIBLVGL_LLEMU_HPP_ +/** + * \file liblvgl/llemu.hpp + * + * \ingroup cpp-llemu + * + * Legacy LCD Emulator + * + * \details This file defines a high-level API for emulating the three-button, UART-based + * VEX LCD, containing a set of functions that facilitate the use of a software- + * emulated version of the classic VEX LCD module. + * + * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/adi.html to learn more. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-llemu LLEMU C++ API + * @{ + * LLEMU - Legacy Lcd EMUlator + * + * \image html llemu/llemu-3.8.png + * + * LLEMU provides a virtual 40x8 LCD screen with 3 buttons. The user can set the + * text of the screen and set create functions that are run when the buttons are + * pressed. + * + * LLEMU is a emulation of the UART-based LCD screens that were available with + * VEX's cortex product line. + * @} + */ + +#ifndef _LIBLVGL_LLEMU_HPP_ +#define _LIBLVGL_LLEMU_HPP_ + +#include +#include + +#include "liblvgl/llemu.h" + +namespace pros { + +/** + * \ingroup cpp-llemu + */ +namespace lcd { + +/** + * \ingroup cpp-llemu + */ + +/** + * \addtogroup cpp-llemu + * @{ + */ + +/** + * \enum Text_Align + * + * @brief Represents how to align the text in the LCD + */ +enum class Text_Align { + /// Align the text to the left side of LCD line + LEFT = 0, + /// Align the text to the center of the LCD line + CENTER = 1, + /// Align the text to the right side of the LCD line + RIGHT = 2 +}; + +/** + * Checks whether the emulated three-button LCD has already been initialized. + * + * \return True if the LCD has been initialized or false if not. + * + * \b Example + * \code + * if (pros::lcd::is_initialized()) { + * pros::lcd::print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU is not initialized\n"); + * } + * \endcode + */ +bool is_initialized(void); + +/** + * Creates an emulation of the three-button, UART-based VEX LCD on the display. + * + * \return True if the LCD was successfully initialized, or false if it has + * already been initialized. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * if (pros::lcd::initialize()) { + * pros::lcd::print("LLEMU!"); + * } + * else { + * printf("Error: LLEMU could not initailize\n"); + * } + * } + * \endcode + */ +bool initialize(void); + +/** + * Turns off the Legacy LCD Emulator. + * + * Calling this function will clear the entire display, and you will not be able + * to call any further LLEMU functions until another call to lcd_initialize. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void disabled() { + * pros::lcd::shutdown(); + * } + * \endcode + */ +bool shutdown(void); + +/** + * Displays a string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param text + * The text to display + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::set_text(0, "My custom LLEMU text!"); + * } + * \endcode + */ +bool set_text(std::int16_t line, std::string text); + +/** + * Clears the contents of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::clear(); // Clear the LCD screen + * } + * \endcode + */ +bool clear(void); + +/** + * Clears the contents of a line of the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line to clear + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::clear_line(0); // Clear line 0 + * } + * \endcode + */ +bool clear_line(std::int16_t line); + +using lcd_btn_cb_fn_t = void (*)(void); + +/** + * Registers a callback function for the leftmost button. + * + * When the leftmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void left_callback() { + * static int i = 0; + * + * pros::lcd::print(0, "Left button pressed %i times", i); + * i++ + * } + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::register_btn0_cb(); + * } + * \endcode + */ +void register_btn0_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the center button. + * + * When the center button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) + * + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void center_callback() { + * static int i = 0; + * + * pros::lcd::print(0, "Center button pressed %i times", i); + * i++ + * } + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::register_btn1_cb(); + * } + * \endcode + */ +void register_btn1_cb(lcd_btn_cb_fn_t cb); + +/** + * Registers a callback function for the rightmost button. + * + * When the rightmost button on the emulated three-button LCD is pressed, the + * user-provided callback function will be invoked. + * + * \param cb + * A callback function of type lcd_btn_cb_fn_t(void (*cb)(void)) + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void right_callback() { + * static int i = 0; + * + * pros::lcd::print(0, "Right button pressed %i times", i); + * i++ + * } + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::register_btn2_cb(); + * } + * \endcode + */ +void register_btn2_cb(lcd_btn_cb_fn_t cb); + +/** + * Sets the alignment to use for subsequent calls that print text to a line. + * + * \param alignment + * An enum specifying the alignment. Available alignments are: + * TEXT_ALIGN_LEFT + * TEXT_ALIGN_RIGHT + * TEXT_ALIGN_CENTER + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::set_alignment(pros::lcd::Text_Align::LEFT); + * pros::lcd::print(0, "Left Aligned Text"); + * pros::lcd::set_alignment(pros::lcd::Text_Align::CENTER); + * pros::lcd::print(1, "Center Aligned Text"); + * pros::lcd::set_alignment(pros::lcd::Text_Align::RIGHT); + * pros::lcd::print(2, "Right Aligned Text"); + * } + * \endcode + */ +void set_text_align(Text_Align alignment); + +/** + * Gets the button status from the emulated three-button LCD. + * + * The value returned is a 3-bit integer where 1 0 0 indicates the left button + * is pressed, 0 1 0 indicates the center button is pressed, and 0 0 1 + * indicates the right button is pressed. 0 is returned if no buttons are + * currently being pressed. + * + * Note that this function is provided for legacy API compatibility purposes, + * with the caveat that the V5 touch screen does not actually support pressing + * multiple points on the screen at the same time. + * + * \return The buttons pressed as a bit mask + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * } + * + * void opcontrol() { + * while(true) { + * std::uint8_t state = pros::lcd::read_buttons(); + * pros::lcd::print(0, "%d %d %d", + * (state & LCD_BTN_LEFT) >> 2 + * (state & LCD_BTN_CENTER) >> 1, + * (state & LCD_BTN_RIGHT) >> 0 + * ); + * + * pros::delay(10); + * } + * } + * \endcode + */ +std::uint8_t read_buttons(void); + +///@} + +} // namespace lcd +} // namespace pros + + +#endif // _LIBLVGL_LLEMU_HPP_ diff --git a/include/liblvgl/lv_conf.h b/include/liblvgl/lv_conf.h index 4ca7e73..bd93a55 100644 --- a/include/liblvgl/lv_conf.h +++ b/include/liblvgl/lv_conf.h @@ -1,775 +1,779 @@ -/** - * @file lv_conf.h - * Configuration file for v7.11.0 - */ - -/* - * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER - */ - -#if 1 /*Set it to "1" to enable content*/ - -#ifndef LV_CONF_H -#define LV_CONF_H -/* clang-format off */ - -#include - -/*==================== - Graphical settings - *====================*/ - -/* Maximal horizontal and vertical resolution to support by the library.*/ -#define LV_HOR_RES_MAX (480) -#define LV_VER_RES_MAX (240) - -/* Color depth: - * - 1: 1 byte per pixel - * - 8: RGB332 - * - 16: RGB565 - * - 32: ARGB8888 - */ -#define LV_COLOR_DEPTH 32 - -/* Swap the 2 bytes of RGB565 color. - * Useful if the display has a 8 bit interface (e.g. SPI)*/ -#define LV_COLOR_16_SWAP 0 - -/* 1: Enable screen transparency. - * Useful for OSD or other overlapping GUIs. - * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/ -#define LV_COLOR_SCREEN_TRANSP 0 - -/*Images pixels with this color will not be drawn (with chroma keying)*/ -#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ - -/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ -#define LV_ANTIALIAS 1 - -/* Default display refresh period. - * Can be changed in the display driver (`lv_disp_drv_t`).*/ -#define LV_DISP_DEF_REFR_PERIOD 40 /*[ms]*/ - -/* Dot Per Inch: used to initialize default sizes. - * E.g. a button with width = LV_DPI / 2 -> half inch wide - * (Not so important, you can adjust it to modify default sizes and spaces)*/ -#define LV_DPI 126 /*[px]*/ - -/* The the real width of the display changes some default values: - * default object sizes, layout of examples, etc. - * According to the width of the display (hor. res. / dpi) - * the displays fall in 4 categories. - * The 4th is extra large which has no upper limit so not listed here - * The upper limit of the categories are set below in 0.1 inch unit. - */ -#define LV_DISP_SMALL_LIMIT 30 -#define LV_DISP_MEDIUM_LIMIT 50 -#define LV_DISP_LARGE_LIMIT 70 - -/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ -typedef int16_t lv_coord_t; - -/* Maximum buffer size to allocate for rotation. Only used if software rotation is enabled. */ -#define LV_DISP_ROT_MAX_BUF (10U * 1024U) - -/*========================= - Memory manager settings - *=========================*/ - -/* LittelvGL's internal memory manager's settings. - * The graphical objects and other related data are stored here. */ - -/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ -#define LV_MEM_CUSTOM 0 -#if LV_MEM_CUSTOM == 0 -/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ -# define LV_MEM_SIZE (32U * 1024U) - -/* Compiler prefix for a big array declaration */ -# define LV_MEM_ATTR - -/* Set an address for the memory pool instead of allocating it as an array. - * Can be in external SRAM too. */ -# define LV_MEM_ADR 0 - -/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */ -# define LV_MEM_AUTO_DEFRAG 1 -#else /*LV_MEM_CUSTOM*/ -# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ -# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ -# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ -#endif /*LV_MEM_CUSTOM*/ - -/* Use the standard memcpy and memset instead of LVGL's own functions. - * The standard functions might or might not be faster depending on their implementation. */ -#define LV_MEMCPY_MEMSET_STD 0 - -/* Garbage Collector settings - * Used if lvgl is binded to higher level language and the memory is managed by that language */ -#define LV_ENABLE_GC 0 -#if LV_ENABLE_GC != 0 -# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ -# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ -# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ -#endif /* LV_ENABLE_GC */ - -/*======================= - Input device settings - *=======================*/ - -/* Input device default settings. - * Can be changed in the Input device driver (`lv_indev_drv_t`)*/ - -/* Input device read period in milliseconds */ -#define LV_INDEV_DEF_READ_PERIOD 50 - -/* Drag threshold in pixels */ -#define LV_INDEV_DEF_DRAG_LIMIT 10 - -/* Drag throw slow-down in [%]. Greater value -> faster slow-down */ -#define LV_INDEV_DEF_DRAG_THROW 20 - -/* Long press time in milliseconds. - * Time to send `LV_EVENT_LONG_PRESSED`) */ -#define LV_INDEV_DEF_LONG_PRESS_TIME 400 - -/* Repeated trigger period in long press [ms] - * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ -#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 - -/* Gesture threshold in pixels */ -#define LV_INDEV_DEF_GESTURE_LIMIT 50 - -/* Gesture min velocity at release before swipe (pixels)*/ -#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3 - -/*================== - * Feature usage - *==================*/ - -/*1: Enable the Animations */ -#define LV_USE_ANIMATION 1 -#if LV_USE_ANIMATION - -/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ -typedef void * lv_anim_user_data_t; - -#endif - -/* 1: Enable shadow drawing on rectangles*/ -#define LV_USE_SHADOW 1 -#if LV_USE_SHADOW -/* Allow buffering some shadow calculation - * LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, - * where shadow size is `shadow_width + radius` - * Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/ -#define LV_SHADOW_CACHE_SIZE 0 -#endif - -/*1: enable outline drawing on rectangles*/ -#define LV_USE_OUTLINE 1 - -/*1: enable pattern drawing on rectangles*/ -#define LV_USE_PATTERN 1 - -/*1: enable value string drawing on rectangles*/ -#define LV_USE_VALUE_STR 1 - -/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ -#define LV_USE_BLEND_MODES 1 - -/* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/ -#define LV_USE_OPA_SCALE 1 - -/* 1: Use image zoom and rotation*/ -#define LV_USE_IMG_TRANSFORM 1 - -/* 1: Enable object groups (for keyboard/encoder navigation) */ -#define LV_USE_GROUP 1 -#if LV_USE_GROUP -typedef void * lv_group_user_data_t; -#endif /*LV_USE_GROUP*/ - -/* 1: Enable GPU interface*/ -#define LV_USE_GPU 0 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */ -#define LV_USE_GPU_STM32_DMA2D 0 -/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor -e.g. "stm32f769xx.h" or "stm32f429xx.h" */ -#define LV_GPU_DMA2D_CMSIS_INCLUDE - -/*1: Use PXP for CPU off-load on NXP RTxxx platforms */ -#define LV_USE_GPU_NXP_PXP 0 - -/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) - * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS - * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. - *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() - * */ -#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 - -/*1: Use VG-Lite for CPU offload on NXP RTxxx platforms */ -#define LV_USE_GPU_NXP_VG_LITE 0 - -/* 1: Enable file system (might be required for images */ -#define LV_USE_FILESYSTEM 1 -#if LV_USE_FILESYSTEM -/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ -typedef void * lv_fs_drv_user_data_t; -#endif - -/*1: Add a `user_data` to drivers and objects*/ -#define LV_USE_USER_DATA 1 - -/*1: Show CPU usage and FPS count in the right bottom corner*/ -#define LV_USE_PERF_MONITOR 0 - -/*1: Use the functions and types from the older API if possible */ -#define LV_USE_API_EXTENSION_V6 1 -#define LV_USE_API_EXTENSION_V7 1 - -/*======================== - * Image decoder and cache - *========================*/ - -/* 1: Enable indexed (palette) images */ -#define LV_IMG_CF_INDEXED 1 - -/* 1: Enable alpha indexed images */ -#define LV_IMG_CF_ALPHA 1 - -/* Default image cache size. Image caching keeps the images opened. - * If only the built-in image formats are used there is no real advantage of caching. - * (I.e. no new image decoder is added) - * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. - * However the opened images might consume additional RAM. - * Set it to 0 to disable caching */ -#define LV_IMG_CACHE_DEF_SIZE 1 - -/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ -typedef void * lv_img_decoder_user_data_t; - -/*===================== - * Compiler settings - *====================*/ - -/* For big endian systems set to 1 */ -#define LV_BIG_ENDIAN_SYSTEM 0 - -/* Define a custom attribute to `lv_tick_inc` function */ -#define LV_ATTRIBUTE_TICK_INC - -/* Define a custom attribute to `lv_task_handler` function */ -#define LV_ATTRIBUTE_TASK_HANDLER - -/* Define a custom attribute to `lv_disp_flush_ready` function */ -#define LV_ATTRIBUTE_FLUSH_READY - -/* Required alignment size for buffers */ -#define LV_ATTRIBUTE_MEM_ALIGN_SIZE - -/* With size optimization (-Os) the compiler might not align data to - * 4 or 8 byte boundary. Some HW may need even 32 or 64 bytes. - * This alignment will be explicitly applied where needed. - * LV_ATTRIBUTE_MEM_ALIGN_SIZE should be used to specify required align size. - * E.g. __attribute__((aligned(LV_ATTRIBUTE_MEM_ALIGN_SIZE))) */ -#define LV_ATTRIBUTE_MEM_ALIGN - -/* Attribute to mark large constant arrays for example - * font's bitmaps */ -#define LV_ATTRIBUTE_LARGE_CONST - -/* Prefix performance critical functions to place them into a faster memory (e.g RAM) - * Uses 15-20 kB extra memory */ -#define LV_ATTRIBUTE_FAST_MEM - -/* Export integer constant to binding. - * This macro is used with constants in the form of LV_ that - * should also appear on lvgl binding API such as Micropython - * - * The default value just prevents a GCC warning. - */ -#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning - -/* Prefix variables that are used in GPU accelerated operations, often these need to be - * placed in RAM sections that are DMA accessible */ -#define LV_ATTRIBUTE_DMA - -/*=================== - * HAL settings - *==================*/ - -/* 1: use a custom tick source. - * It removes the need to manually update the tick with `lv_tick_inc`) */ -#define LV_TICK_CUSTOM 0 -#if LV_TICK_CUSTOM == 1 -#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ -#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ -#endif /*LV_TICK_CUSTOM*/ - -typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ -typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/ - -/*================ - * Log settings - *===============*/ - -/*1: Enable the log module*/ -#define LV_USE_LOG 0 -#if LV_USE_LOG -/* How important log should be added: - * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information - * LV_LOG_LEVEL_INFO Log important events - * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem - * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail - * LV_LOG_LEVEL_NONE Do not log anything - */ -# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN - -/* 1: Print the log with 'printf'; - * 0: user need to register a callback with `lv_log_register_print_cb`*/ -# define LV_LOG_PRINTF 0 -#endif /*LV_USE_LOG*/ - -/*================= - * Debug settings - *================*/ - -/* If Debug is enabled LittelvGL validates the parameters of the functions. - * If an invalid parameter is found an error log message is printed and - * the MCU halts at the error. (`LV_USE_LOG` should be enabled) - * If you are debugging the MCU you can pause - * the debugger to see exactly where the issue is. - * - * The behavior of asserts can be overwritten by redefining them here. - * E.g. #define LV_ASSERT_MEM(p) - */ -#define LV_USE_DEBUG 1 -#if LV_USE_DEBUG - -/*Check if the parameter is NULL. (Quite fast) */ -#define LV_USE_ASSERT_NULL 1 - -/*Checks is the memory is successfully allocated or no. (Quite fast)*/ -#define LV_USE_ASSERT_MEM 1 - -/*Check the integrity of `lv_mem` after critical operations. (Slow)*/ -#define LV_USE_ASSERT_MEM_INTEGRITY 0 - -/* Check the strings. - * Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow) - * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ -#define LV_USE_ASSERT_STR 0 - -/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow) - * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ -#define LV_USE_ASSERT_OBJ 0 - -/*Check if the styles are properly initialized. (Fast)*/ -#define LV_USE_ASSERT_STYLE 0 - -#endif /*LV_USE_DEBUG*/ - -/*================== - * FONT USAGE - *===================*/ - -/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. - * The symbols are available via `LV_SYMBOL_...` defines - * More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html - * To create a new font go to: https://lvgl.com/ttf-font-to-c-array - */ - -/* Montserrat fonts with bpp = 4 - * https://fonts.google.com/specimen/Montserrat */ -#define LV_FONT_MONTSERRAT_8 0 -#define LV_FONT_MONTSERRAT_10 1 -#define LV_FONT_MONTSERRAT_12 0 -#define LV_FONT_MONTSERRAT_14 1 -#define LV_FONT_MONTSERRAT_16 0 -#define LV_FONT_MONTSERRAT_18 0 -#define LV_FONT_MONTSERRAT_20 1 -#define LV_FONT_MONTSERRAT_22 0 -#define LV_FONT_MONTSERRAT_24 0 -#define LV_FONT_MONTSERRAT_26 0 -#define LV_FONT_MONTSERRAT_28 0 -#define LV_FONT_MONTSERRAT_30 1 -#define LV_FONT_MONTSERRAT_32 0 -#define LV_FONT_MONTSERRAT_34 0 -#define LV_FONT_MONTSERRAT_36 0 -#define LV_FONT_MONTSERRAT_38 0 -#define LV_FONT_MONTSERRAT_40 1 -#define LV_FONT_MONTSERRAT_42 0 -#define LV_FONT_MONTSERRAT_44 0 -#define LV_FONT_MONTSERRAT_46 0 -#define LV_FONT_MONTSERRAT_48 0 - -/* Demonstrate special features */ -#define LV_FONT_MONTSERRAT_12_SUBPX 0 -#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ -#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, PErisan letters and all their forms*/ -#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ - -/*Pixel perfect monospace font - * http://pelulamu.net/unscii/ */ -#define LV_FONT_UNSCII_8 1 -#define LV_FONT_UNSCII_16 1 - -/* Optionally declare your custom fonts here. - * You can use these fonts as default font too - * and they will be available globally. E.g. - * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ - * LV_FONT_DECLARE(my_font_2) - */ -#define LV_FONT_CUSTOM_DECLARE - -/* Enable it if you have fonts with a lot of characters. - * The limit depends on the font size, font face and bpp - * but with > 10,000 characters if you see issues probably you need to enable it.*/ -#define LV_FONT_FMT_TXT_LARGE 0 - -/* Enables/disables support for compressed fonts. If it's disabled, compressed - * glyphs cannot be processed by the library and won't be rendered. - */ -#define LV_USE_FONT_COMPRESSED 1 - -/* Enable subpixel rendering */ -#define LV_USE_FONT_SUBPX 1 -#if LV_USE_FONT_SUBPX -/* Set the pixel order of the display. - * Important only if "subpx fonts" are used. - * With "normal" font it doesn't matter. - */ -#define LV_FONT_SUBPX_BGR 0 - -/* PROS adds the mono variant of DejaVu sans */ -#define USE_PROS_FONT_DEJAVU_MONO_10 1 - -#define USE_PROS_FONT_DEJAVU_MONO_18 1 // llemu font - -#define USE_PROS_FONT_DEJAVU_MONO_30 0 - -#define USE_PROS_FONT_DEJAVU_MONO_40 0 - -#endif - -/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ -typedef void * lv_font_user_data_t; - -/*================ - * THEME USAGE - *================*/ - -/*Always enable at least on theme*/ - -/* No theme, you can apply your styles as you need - * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ -#define LV_USE_THEME_EMPTY 1 - -/*Simple to the create your theme based on it - * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ -#define LV_USE_THEME_TEMPLATE 1 - -/* A fast and impressive theme. - * Flags: - * LV_THEME_MATERIAL_FLAG_LIGHT: light theme - * LV_THEME_MATERIAL_FLAG_DARK: dark theme - * LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations) - * LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state) - * */ -#define LV_USE_THEME_MATERIAL 1 - -/* Mono-color theme for monochrome displays. - * If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the - * texts and borders will be black and the background will be - * white. Else the colors are inverted. - * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ -#define LV_USE_THEME_MONO 1 - -#define LV_THEME_DEFAULT_INCLUDE /*Include a header for the init. function*/ -#define LV_THEME_DEFAULT_INIT lv_theme_material_init -#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1) -#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6) -#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_DARK -#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_10 -#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_20 -#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_10 -#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_30 - -/*================= - * Text settings - *=================*/ - -/* Select a character encoding for strings. - * Your IDE or editor should have the same character encoding - * - LV_TXT_ENC_UTF8 - * - LV_TXT_ENC_ASCII - * */ -#define LV_TXT_ENC LV_TXT_ENC_UTF8 - - /*Can break (wrap) texts on these chars*/ -#define LV_TXT_BREAK_CHARS " ,.;:-_" - -/* If a word is at least this long, will break wherever "prettiest" - * To disable, set to a value <= 0 */ -#define LV_TXT_LINE_BREAK_LONG_LEN 0 - -/* Minimum number of characters in a long word to put on a line before a break. - * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ -#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 - -/* Minimum number of characters in a long word to put on a line after a break. - * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ -#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 - -/* The control character to use for signalling text recoloring. */ -#define LV_TXT_COLOR_CMD "#" - -/* Support bidirectional texts. - * Allows mixing Left-to-Right and Right-to-Left texts. - * The direction will be processed according to the Unicode Bidirectional Algorithm: - * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ -#define LV_USE_BIDI 0 -#if LV_USE_BIDI -/* Set the default direction. Supported values: - * `LV_BIDI_DIR_LTR` Left-to-Right - * `LV_BIDI_DIR_RTL` Right-to-Left - * `LV_BIDI_DIR_AUTO` detect texts base direction */ -#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO -#endif - -/* Enable Arabic/Persian processing - * In these languages characters should be replaced with - * an other form based on their position in the text */ -#define LV_USE_ARABIC_PERSIAN_CHARS 0 - -/*Change the built in (v)snprintf functions*/ -#define LV_SPRINTF_CUSTOM 0 -#if LV_SPRINTF_CUSTOM -# define LV_SPRINTF_INCLUDE -# define lv_snprintf snprintf -# define lv_vsnprintf vsnprintf -#else /*!LV_SPRINTF_CUSTOM*/ -# define LV_SPRINTF_DISABLE_FLOAT 1 -#endif /*LV_SPRINTF_CUSTOM*/ - -/*=================== - * LV_OBJ SETTINGS - *==================*/ - -#if LV_USE_USER_DATA -/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/ -typedef void * lv_obj_user_data_t; -/*Provide a function to free user data*/ -#define LV_USE_USER_DATA_FREE 0 -#if LV_USE_USER_DATA_FREE -# define LV_USER_DATA_FREE_INCLUDE "something.h" /*Header for user data free function*/ -/* Function prototype : void user_data_free(lv_obj_t * obj); */ -# define LV_USER_DATA_FREE (user_data_free) /*Invoking for user data free function*/ -#endif -#endif - -/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/ -#define LV_USE_OBJ_REALIGN 1 - -/* Enable to make the object clickable on a larger area. - * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature - * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px) - * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px) - */ -#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_TINY - -/*================== - * LV OBJ X USAGE - *================*/ -/* - * Documentation of the object types: https://docs.lvgl.com/#Object-types - */ - -/*Arc (dependencies: -)*/ -#define LV_USE_ARC 1 - -/*Bar (dependencies: -)*/ -#define LV_USE_BAR 1 - -/*Button (dependencies: lv_cont*/ -#define LV_USE_BTN 1 - -/*Button matrix (dependencies: -)*/ -#define LV_USE_BTNMATRIX 1 - -/*Calendar (dependencies: -)*/ -#define LV_USE_CALENDAR 1 -#if LV_USE_CALENDAR -# define LV_CALENDAR_WEEK_STARTS_MONDAY 0 -#endif - -/*Canvas (dependencies: lv_img)*/ -#define LV_USE_CANVAS 1 - -/*Check box (dependencies: lv_btn, lv_label)*/ -#define LV_USE_CHECKBOX 1 - -/*Chart (dependencies: -)*/ -#define LV_USE_CHART 1 -#if LV_USE_CHART -# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 256 -#endif - -/*Container (dependencies: -*/ -#define LV_USE_CONT 1 - -/*Color picker (dependencies: -*/ -#define LV_USE_CPICKER 1 - -/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ -#define LV_USE_DROPDOWN 1 -#if LV_USE_DROPDOWN != 0 -/*Open and close default animation time [ms] (0: no animation)*/ -# define LV_DROPDOWN_DEF_ANIM_TIME 200 -#endif - -/*Gauge (dependencies:lv_bar, lv_linemeter)*/ -#define LV_USE_GAUGE 1 - -/*Image (dependencies: lv_label*/ -#define LV_USE_IMG 1 - -/*Image Button (dependencies: lv_btn*/ -#define LV_USE_IMGBTN 1 -#if LV_USE_IMGBTN -/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ -# define LV_IMGBTN_TILED 0 -#endif - -/*Keyboard (dependencies: lv_btnm)*/ -#define LV_USE_KEYBOARD 1 - -/*Label (dependencies: -*/ -#define LV_USE_LABEL 1 -#if LV_USE_LABEL != 0 -/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/ -# define LV_LABEL_DEF_SCROLL_SPEED 25 - -/* Waiting period at beginning/end of animation cycle */ -# define LV_LABEL_WAIT_CHAR_COUNT 3 - -/*Enable selecting text of the label */ -# define LV_LABEL_TEXT_SEL 0 - -/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/ -# define LV_LABEL_LONG_TXT_HINT 0 -#endif - -/*LED (dependencies: -)*/ -#define LV_USE_LED 1 -#if LV_USE_LED -# define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/ -# define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/ -#endif - -/*Line (dependencies: -*/ -#define LV_USE_LINE 1 - -/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ -#define LV_USE_LIST 1 -#if LV_USE_LIST != 0 -/*Default animation time of focusing to a list element [ms] (0: no animation) */ -# define LV_LIST_DEF_ANIM_TIME 100 -#endif - -/*Line meter (dependencies: *;)*/ -#define LV_USE_LINEMETER 1 -#if LV_USE_LINEMETER -/* Draw line more precisely at cost of performance. - * Useful if there are lot of lines any minor are visible - * 0: No extra precision - * 1: Some extra precision - * 2: Best precision - */ -# define LV_LINEMETER_PRECISE 1 -#endif - -/*Mask (dependencies: -)*/ -#define LV_USE_OBJMASK 1 - -/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ -#define LV_USE_MSGBOX 1 - -/*Page (dependencies: lv_cont)*/ -#define LV_USE_PAGE 1 -#if LV_USE_PAGE != 0 -/*Focus default animation time [ms] (0: no animation)*/ -# define LV_PAGE_DEF_ANIM_TIME 400 -#endif - -/*Preload (dependencies: lv_arc, lv_anim)*/ -#define LV_USE_SPINNER 1 -#if LV_USE_SPINNER != 0 -# define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/ -# define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/ -# define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC -#endif - -/*Roller (dependencies: lv_ddlist)*/ -#define LV_USE_ROLLER 1 -#if LV_USE_ROLLER != 0 -/*Focus animation time [ms] (0: no animation)*/ -# define LV_ROLLER_DEF_ANIM_TIME 200 - -/*Number of extra "pages" when the roller is infinite*/ -# define LV_ROLLER_INF_PAGES 7 -#endif - -/*Slider (dependencies: lv_bar)*/ -#define LV_USE_SLIDER 1 - -/*Spinbox (dependencies: lv_ta)*/ -#define LV_USE_SPINBOX 1 - -/*Switch (dependencies: lv_slider)*/ -#define LV_USE_SWITCH 1 - -/*Text area (dependencies: lv_label, lv_page)*/ -#define LV_USE_TEXTAREA 1 -#if LV_USE_TEXTAREA != 0 -# define LV_TEXTAREA_DEF_CURSOR_BLINK_TIME 400 /*ms*/ -# define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ -#endif - -/*Table (dependencies: lv_label)*/ -#define LV_USE_TABLE 1 -#if LV_USE_TABLE -# define LV_TABLE_COL_MAX 12 -# define LV_TABLE_CELL_STYLE_CNT 4 -#endif - -/*Tab (dependencies: lv_page, lv_btnm)*/ -#define LV_USE_TABVIEW 1 -# if LV_USE_TABVIEW != 0 -/*Time of slide animation [ms] (0: no animation)*/ -# define LV_TABVIEW_DEF_ANIM_TIME 300 -#endif - -/*Tileview (dependencies: lv_page) */ -#define LV_USE_TILEVIEW 1 -#if LV_USE_TILEVIEW -/*Time of slide animation [ms] (0: no animation)*/ -# define LV_TILEVIEW_DEF_ANIM_TIME 300 -#endif - -/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ -#define LV_USE_WIN 1 - -/*================== - * Non-user section - *==================*/ - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ -# define _CRT_SECURE_NO_WARNINGS -#endif - -/*--END OF LV_CONF_H--*/ - -#endif /*LV_CONF_H*/ - -#endif /*End of "Content enable"*/ +/** + * @file lv_conf.h + * Configuration file for v7.11.0 + */ + +/* + * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER + */ + +#if 1 /*Set it to "1" to enable content*/ + +#ifndef LV_CONF_H +#define LV_CONF_H +/* clang-format off */ + +#include + +/*==================== + Graphical settings + *====================*/ + +/* Maximal horizontal and vertical resolution to support by the library.*/ +#define LV_HOR_RES_MAX (480) +#define LV_VER_RES_MAX (240) + +/* Color depth: + * - 1: 1 byte per pixel + * - 8: RGB332 + * - 16: RGB565 + * - 32: ARGB8888 + */ +#define LV_COLOR_DEPTH 32 + +/* Swap the 2 bytes of RGB565 color. + * Useful if the display has a 8 bit interface (e.g. SPI)*/ +#define LV_COLOR_16_SWAP 0 + +/* 1: Enable screen transparency. + * Useful for OSD or other overlapping GUIs. + * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/ +#define LV_COLOR_SCREEN_TRANSP 0 + +/*Images pixels with this color will not be drawn (with chroma keying)*/ +#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 1 + +/* Default display refresh period. + * Can be changed in the display driver (`lv_disp_drv_t`).*/ +#define LV_DISP_DEF_REFR_PERIOD 40 /*[ms]*/ + +/* Dot Per Inch: used to initialize default sizes. + * E.g. a button with width = LV_DPI / 2 -> half inch wide + * (Not so important, you can adjust it to modify default sizes and spaces)*/ +#define LV_DPI 126 /*[px]*/ + +/* The the real width of the display changes some default values: + * default object sizes, layout of examples, etc. + * According to the width of the display (hor. res. / dpi) + * the displays fall in 4 categories. + * The 4th is extra large which has no upper limit so not listed here + * The upper limit of the categories are set below in 0.1 inch unit. + */ +#define LV_DISP_SMALL_LIMIT 30 +#define LV_DISP_MEDIUM_LIMIT 50 +#define LV_DISP_LARGE_LIMIT 70 + +/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ +typedef int16_t lv_coord_t; + +/* Maximum buffer size to allocate for rotation. Only used if software rotation is enabled. */ +#define LV_DISP_ROT_MAX_BUF (10U * 1024U) + +/*========================= + Memory manager settings + *=========================*/ + +/* LittelvGL's internal memory manager's settings. + * The graphical objects and other related data are stored here. */ + +/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ +#define LV_MEM_CUSTOM 0 +#if LV_MEM_CUSTOM == 0 +/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +# define LV_MEM_SIZE (32U * 1024U) + +/* Compiler prefix for a big array declaration */ +# define LV_MEM_ATTR + +/* Set an address for the memory pool instead of allocating it as an array. + * Can be in external SRAM too. */ +# define LV_MEM_ADR 0 + +/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */ +# define LV_MEM_AUTO_DEFRAG 1 +#else /*LV_MEM_CUSTOM*/ +# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ +# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ +# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ + +/* Use the standard memcpy and memset instead of LVGL's own functions. + * The standard functions might or might not be faster depending on their implementation. */ +#define LV_MEMCPY_MEMSET_STD 0 + +/* Garbage Collector settings + * Used if lvgl is binded to higher level language and the memory is managed by that language */ +#define LV_ENABLE_GC 0 +#if LV_ENABLE_GC != 0 +# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ +# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ +# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ +#endif /* LV_ENABLE_GC */ + +/*======================= + Input device settings + *=======================*/ + +/* Input device default settings. + * Can be changed in the Input device driver (`lv_indev_drv_t`)*/ + +/* Input device read period in milliseconds */ +#define LV_INDEV_DEF_READ_PERIOD 50 + +/* Drag threshold in pixels */ +#define LV_INDEV_DEF_DRAG_LIMIT 10 + +/* Drag throw slow-down in [%]. Greater value -> faster slow-down */ +#define LV_INDEV_DEF_DRAG_THROW 20 + +/* Long press time in milliseconds. + * Time to send `LV_EVENT_LONG_PRESSED`) */ +#define LV_INDEV_DEF_LONG_PRESS_TIME 400 + +/* Repeated trigger period in long press [ms] + * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ +#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 + +/* Gesture threshold in pixels */ +#define LV_INDEV_DEF_GESTURE_LIMIT 50 + +/* Gesture min velocity at release before swipe (pixels)*/ +#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3 + +/*================== + * Feature usage + *==================*/ + +/*1: Enable the Animations */ +#define LV_USE_ANIMATION 1 +#if LV_USE_ANIMATION + +/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_anim_user_data_t; + +#endif + +/* 1: Enable shadow drawing on rectangles*/ +#define LV_USE_SHADOW 1 +#if LV_USE_SHADOW +/* Allow buffering some shadow calculation + * LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, + * where shadow size is `shadow_width + radius` + * Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/ +#define LV_SHADOW_CACHE_SIZE 0 +#endif + +/*1: enable outline drawing on rectangles*/ +#define LV_USE_OUTLINE 1 + +/*1: enable pattern drawing on rectangles*/ +#define LV_USE_PATTERN 1 + +/*1: enable value string drawing on rectangles*/ +#define LV_USE_VALUE_STR 1 + +/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ +#define LV_USE_BLEND_MODES 1 + +/* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/ +#define LV_USE_OPA_SCALE 1 + +/* 1: Use image zoom and rotation*/ +#define LV_USE_IMG_TRANSFORM 1 + +/* 1: Enable object groups (for keyboard/encoder navigation) */ +#define LV_USE_GROUP 1 +#if LV_USE_GROUP +typedef void * lv_group_user_data_t; +#endif /*LV_USE_GROUP*/ + +/* 1: Enable GPU interface*/ +#define LV_USE_GPU 0 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */ +#define LV_USE_GPU_STM32_DMA2D 0 +/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor +e.g. "stm32f769xx.h" or "stm32f429xx.h" */ +#define LV_GPU_DMA2D_CMSIS_INCLUDE + +/*1: Use PXP for CPU off-load on NXP RTxxx platforms */ +#define LV_USE_GPU_NXP_PXP 0 + +/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) + * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS + * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. + *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() + * */ +#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 + +/*1: Use VG-Lite for CPU offload on NXP RTxxx platforms */ +#define LV_USE_GPU_NXP_VG_LITE 0 + +/* 1: Enable file system (might be required for images */ +#define LV_USE_FILESYSTEM 1 +#if LV_USE_FILESYSTEM +/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_fs_drv_user_data_t; +#endif + +/*1: Add a `user_data` to drivers and objects*/ +#define LV_USE_USER_DATA 1 + +/*1: Show CPU usage and FPS count in the right bottom corner*/ +#define LV_USE_PERF_MONITOR 0 + +/*1: Use the functions and types from the older API if possible */ +#define LV_USE_API_EXTENSION_V6 1 +#define LV_USE_API_EXTENSION_V7 1 + +/*======================== + * Image decoder and cache + *========================*/ + +/* 1: Enable indexed (palette) images */ +#define LV_IMG_CF_INDEXED 1 + +/* 1: Enable alpha indexed images */ +#define LV_IMG_CF_ALPHA 1 + +/* Default image cache size. Image caching keeps the images opened. + * If only the built-in image formats are used there is no real advantage of caching. + * (I.e. no new image decoder is added) + * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. + * However the opened images might consume additional RAM. + * Set it to 0 to disable caching */ +#define LV_IMG_CACHE_DEF_SIZE 1 + +/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_img_decoder_user_data_t; + +/*===================== + * Compiler settings + *====================*/ + +/* For big endian systems set to 1 */ +#define LV_BIG_ENDIAN_SYSTEM 0 + +/* Define a custom attribute to `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TICK_INC + +/* Define a custom attribute to `lv_task_handler` function */ +#define LV_ATTRIBUTE_TASK_HANDLER + +/* Define a custom attribute to `lv_disp_flush_ready` function */ +#define LV_ATTRIBUTE_FLUSH_READY + +/* Required alignment size for buffers */ +#define LV_ATTRIBUTE_MEM_ALIGN_SIZE + +/* With size optimization (-Os) the compiler might not align data to + * 4 or 8 byte boundary. Some HW may need even 32 or 64 bytes. + * This alignment will be explicitly applied where needed. + * LV_ATTRIBUTE_MEM_ALIGN_SIZE should be used to specify required align size. + * E.g. __attribute__((aligned(LV_ATTRIBUTE_MEM_ALIGN_SIZE))) */ +#define LV_ATTRIBUTE_MEM_ALIGN + +/* Attribute to mark large constant arrays for example + * font's bitmaps */ +#define LV_ATTRIBUTE_LARGE_CONST + +/* Prefix performance critical functions to place them into a faster memory (e.g RAM) + * Uses 15-20 kB extra memory */ +#define LV_ATTRIBUTE_FAST_MEM + +/* Export integer constant to binding. + * This macro is used with constants in the form of LV_ that + * should also appear on lvgl binding API such as Micropython + * + * The default value just prevents a GCC warning. + */ +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning + +/* Prefix variables that are used in GPU accelerated operations, often these need to be + * placed in RAM sections that are DMA accessible */ +#define LV_ATTRIBUTE_DMA + +/*=================== + * HAL settings + *==================*/ + +/* 1: use a custom tick source. + * It removes the need to manually update the tick with `lv_tick_inc`) */ +#define LV_TICK_CUSTOM 0 +#if LV_TICK_CUSTOM == 1 +#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ +#endif /*LV_TICK_CUSTOM*/ + +typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ +typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/ + +/*================ + * Log settings + *===============*/ + +/*1: Enable the log module*/ +#define LV_USE_LOG 0 +#if LV_USE_LOG +/* How important log should be added: + * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + * LV_LOG_LEVEL_INFO Log important events + * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem + * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + * LV_LOG_LEVEL_NONE Do not log anything + */ +# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + +/* 1: Print the log with 'printf'; + * 0: user need to register a callback with `lv_log_register_print_cb`*/ +# define LV_LOG_PRINTF 0 +#endif /*LV_USE_LOG*/ + +/*================= + * Debug settings + *================*/ + +/* If Debug is enabled LittelvGL validates the parameters of the functions. + * If an invalid parameter is found an error log message is printed and + * the MCU halts at the error. (`LV_USE_LOG` should be enabled) + * If you are debugging the MCU you can pause + * the debugger to see exactly where the issue is. + * + * The behavior of asserts can be overwritten by redefining them here. + * E.g. #define LV_ASSERT_MEM(p) + */ +#define LV_USE_DEBUG 1 +#if LV_USE_DEBUG + +/*Check if the parameter is NULL. (Quite fast) */ +#define LV_USE_ASSERT_NULL 1 + +/*Checks is the memory is successfully allocated or no. (Quite fast)*/ +#define LV_USE_ASSERT_MEM 1 + +/*Check the integrity of `lv_mem` after critical operations. (Slow)*/ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 + +/* Check the strings. + * Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow) + * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ +#define LV_USE_ASSERT_STR 0 + +/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow) + * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ +#define LV_USE_ASSERT_OBJ 0 + +/*Check if the styles are properly initialized. (Fast)*/ +#define LV_USE_ASSERT_STYLE 0 + +#endif /*LV_USE_DEBUG*/ + +/*================== + * FONT USAGE + *===================*/ + +/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. + * The symbols are available via `LV_SYMBOL_...` defines + * More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html + * To create a new font go to: https://lvgl.com/ttf-font-to-c-array + */ + +/* Montserrat fonts with bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ +#define LV_FONT_MONTSERRAT_8 0 +#define LV_FONT_MONTSERRAT_10 1 +#define LV_FONT_MONTSERRAT_12 1 +#define LV_FONT_MONTSERRAT_14 1 +#define LV_FONT_MONTSERRAT_16 1 +#define LV_FONT_MONTSERRAT_18 1 +#define LV_FONT_MONTSERRAT_20 1 +#define LV_FONT_MONTSERRAT_22 0 +#define LV_FONT_MONTSERRAT_24 1 +#define LV_FONT_MONTSERRAT_26 0 +#define LV_FONT_MONTSERRAT_28 0 +#define LV_FONT_MONTSERRAT_30 1 +#define LV_FONT_MONTSERRAT_32 0 +#define LV_FONT_MONTSERRAT_34 0 +#define LV_FONT_MONTSERRAT_36 1 +#define LV_FONT_MONTSERRAT_38 0 +#define LV_FONT_MONTSERRAT_40 1 +#define LV_FONT_MONTSERRAT_42 1 +#define LV_FONT_MONTSERRAT_44 0 +#define LV_FONT_MONTSERRAT_46 0 +#define LV_FONT_MONTSERRAT_48 1 + +/* Demonstrate special features */ +#define LV_FONT_MONTSERRAT_12_SUBPX 0 +#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ +#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, PErisan letters and all their forms*/ +#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ + +/*Pixel perfect monospace font + * http://pelulamu.net/unscii/ */ +#define LV_FONT_UNSCII_8 1 +#define LV_FONT_UNSCII_16 1 + +/* Optionally declare your custom fonts here. + * You can use these fonts as default font too + * and they will be available globally. E.g. + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ + * LV_FONT_DECLARE(my_font_2) + */ +#define LV_FONT_CUSTOM_DECLARE + +/* Enable it if you have fonts with a lot of characters. + * The limit depends on the font size, font face and bpp + * but with > 10,000 characters if you see issues probably you need to enable it.*/ +#define LV_FONT_FMT_TXT_LARGE 0 + +/* Enables/disables support for compressed fonts. If it's disabled, compressed + * glyphs cannot be processed by the library and won't be rendered. + */ +#define LV_USE_FONT_COMPRESSED 1 + +/* Enable subpixel rendering */ +#define LV_USE_FONT_SUBPX 1 +#if LV_USE_FONT_SUBPX +/* Set the pixel order of the display. + * Important only if "subpx fonts" are used. + * With "normal" font it doesn't matter. + */ +#define LV_FONT_SUBPX_BGR 0 + +/* PROS adds the mono variant of DejaVu sans */ +#define USE_PROS_FONT_DEJAVU_MONO_10 1 + +#define USE_PROS_FONT_DEJAVU_MONO_18 1 // llemu font + +#define USE_PROS_FONT_DEJAVU_MONO_30 0 + +#define USE_PROS_FONT_DEJAVU_MONO_40 0 + +#endif + +/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_font_user_data_t; + +/*================ + * THEME USAGE + *================*/ + +/*Always enable at least on theme*/ + +/* No theme, you can apply your styles as you need + * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ +#define LV_USE_THEME_EMPTY 1 + +/*Simple to the create your theme based on it + * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ +#define LV_USE_THEME_TEMPLATE 1 + +/* A fast and impressive theme. + * Flags: + * LV_THEME_MATERIAL_FLAG_LIGHT: light theme + * LV_THEME_MATERIAL_FLAG_DARK: dark theme + * LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations) + * LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state) + * */ +#define LV_USE_THEME_MATERIAL 1 + +/* Mono-color theme for monochrome displays. + * If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the + * texts and borders will be black and the background will be + * white. Else the colors are inverted. + * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ +#define LV_USE_THEME_MONO 1 + +#define LV_THEME_DEFAULT_INCLUDE /*Include a header for the init. function*/ +#define LV_THEME_DEFAULT_INIT lv_theme_material_init +#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1) +#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6) +#define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_DARK +#define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_10 +#define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_20 +#define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_10 +#define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_30 + +#define CONFIG_LV_THEME_DEFAULT_DARK 1 + +/*================= + * Text settings + *=================*/ + +/* Select a character encoding for strings. + * Your IDE or editor should have the same character encoding + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + * */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + + /*Can break (wrap) texts on these chars*/ +#define LV_TXT_BREAK_CHARS " ,.;:-_" + +/* If a word is at least this long, will break wherever "prettiest" + * To disable, set to a value <= 0 */ +#define LV_TXT_LINE_BREAK_LONG_LEN 0 + +/* Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + +/* Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + +/* The control character to use for signalling text recoloring. */ +#define LV_TXT_COLOR_CMD "#" + +/* Support bidirectional texts. + * Allows mixing Left-to-Right and Right-to-Left texts. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +#define LV_USE_BIDI 0 +#if LV_USE_BIDI +/* Set the default direction. Supported values: + * `LV_BIDI_DIR_LTR` Left-to-Right + * `LV_BIDI_DIR_RTL` Right-to-Left + * `LV_BIDI_DIR_AUTO` detect texts base direction */ +#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO +#endif + +/* Enable Arabic/Persian processing + * In these languages characters should be replaced with + * an other form based on their position in the text */ +#define LV_USE_ARABIC_PERSIAN_CHARS 0 + +/*Change the built in (v)snprintf functions*/ +#define LV_SPRINTF_CUSTOM 0 +#if LV_SPRINTF_CUSTOM +# define LV_SPRINTF_INCLUDE +# define lv_snprintf snprintf +# define lv_vsnprintf vsnprintf +#else /*!LV_SPRINTF_CUSTOM*/ +# define LV_SPRINTF_DISABLE_FLOAT 1 +#endif /*LV_SPRINTF_CUSTOM*/ + +/*=================== + * LV_OBJ SETTINGS + *==================*/ + +#if LV_USE_USER_DATA +/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_obj_user_data_t; +/*Provide a function to free user data*/ +#define LV_USE_USER_DATA_FREE 0 +#if LV_USE_USER_DATA_FREE +# define LV_USER_DATA_FREE_INCLUDE "something.h" /*Header for user data free function*/ +/* Function prototype : void user_data_free(lv_obj_t * obj); */ +# define LV_USER_DATA_FREE (user_data_free) /*Invoking for user data free function*/ +#endif +#endif + +/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/ +#define LV_USE_OBJ_REALIGN 1 + +/* Enable to make the object clickable on a larger area. + * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature + * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px) + * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px) + */ +#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_TINY + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://docs.lvgl.com/#Object-types + */ + +/*Arc (dependencies: -)*/ +#define LV_USE_ARC 1 + +/*Bar (dependencies: -)*/ +#define LV_USE_BAR 1 + +/*Button (dependencies: lv_cont*/ +#define LV_USE_BTN 1 + +/*Button matrix (dependencies: -)*/ +#define LV_USE_BTNMATRIX 1 + +/*Calendar (dependencies: -)*/ +#define LV_USE_CALENDAR 1 +#if LV_USE_CALENDAR +# define LV_CALENDAR_WEEK_STARTS_MONDAY 0 +#endif + +/*Canvas (dependencies: lv_img)*/ +#define LV_USE_CANVAS 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define LV_USE_CHECKBOX 1 + +/*Chart (dependencies: -)*/ +#define LV_USE_CHART 1 +#if LV_USE_CHART +# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 256 +#endif + +/*Container (dependencies: -*/ +#define LV_USE_CONT 1 + +/*Color picker (dependencies: -*/ +#define LV_USE_CPICKER 1 + +/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ +#define LV_USE_DROPDOWN 1 +#if LV_USE_DROPDOWN != 0 +/*Open and close default animation time [ms] (0: no animation)*/ +# define LV_DROPDOWN_DEF_ANIM_TIME 200 +#endif + +/*Gauge (dependencies:lv_bar, lv_linemeter)*/ +#define LV_USE_GAUGE 1 + +/*Image (dependencies: lv_label*/ +#define LV_USE_IMG 1 + +/*Image Button (dependencies: lv_btn*/ +#define LV_USE_IMGBTN 1 +#if LV_USE_IMGBTN +/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ +# define LV_IMGBTN_TILED 0 +#endif + +/*Keyboard (dependencies: lv_btnm)*/ +#define LV_USE_KEYBOARD 1 + +/*Label (dependencies: -*/ +#define LV_USE_LABEL 1 +#if LV_USE_LABEL != 0 +/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/ +# define LV_LABEL_DEF_SCROLL_SPEED 25 + +/* Waiting period at beginning/end of animation cycle */ +# define LV_LABEL_WAIT_CHAR_COUNT 3 + +/*Enable selecting text of the label */ +# define LV_LABEL_TEXT_SEL 0 + +/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/ +# define LV_LABEL_LONG_TXT_HINT 0 +#endif + +/*LED (dependencies: -)*/ +#define LV_USE_LED 1 +#if LV_USE_LED +# define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/ +# define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/ +#endif + +/*Line (dependencies: -*/ +#define LV_USE_LINE 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ +#define LV_USE_LIST 1 +#if LV_USE_LIST != 0 +/*Default animation time of focusing to a list element [ms] (0: no animation) */ +# define LV_LIST_DEF_ANIM_TIME 100 +#endif + +/*Line meter (dependencies: *;)*/ +#define LV_USE_LINEMETER 1 +#if LV_USE_LINEMETER +/* Draw line more precisely at cost of performance. + * Useful if there are lot of lines any minor are visible + * 0: No extra precision + * 1: Some extra precision + * 2: Best precision + */ +# define LV_LINEMETER_PRECISE 1 +#endif + +/*Mask (dependencies: -)*/ +#define LV_USE_OBJMASK 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define LV_USE_MSGBOX 1 + +/*Page (dependencies: lv_cont)*/ +#define LV_USE_PAGE 1 +#if LV_USE_PAGE != 0 +/*Focus default animation time [ms] (0: no animation)*/ +# define LV_PAGE_DEF_ANIM_TIME 400 +#endif + +/*Preload (dependencies: lv_arc, lv_anim)*/ +#define LV_USE_SPINNER 1 +#if LV_USE_SPINNER != 0 +# define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/ +# define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/ +# define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define LV_USE_ROLLER 1 +#if LV_USE_ROLLER != 0 +/*Focus animation time [ms] (0: no animation)*/ +# define LV_ROLLER_DEF_ANIM_TIME 200 + +/*Number of extra "pages" when the roller is infinite*/ +# define LV_ROLLER_INF_PAGES 7 +#endif + +/*Slider (dependencies: lv_bar)*/ +#define LV_USE_SLIDER 1 + +/*Spinbox (dependencies: lv_ta)*/ +#define LV_USE_SPINBOX 1 + +/*Switch (dependencies: lv_slider)*/ +#define LV_USE_SWITCH 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define LV_USE_TEXTAREA 1 +#if LV_USE_TEXTAREA != 0 +# define LV_TEXTAREA_DEF_CURSOR_BLINK_TIME 400 /*ms*/ +# define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +/*Table (dependencies: lv_label)*/ +#define LV_USE_TABLE 1 +#if LV_USE_TABLE +# define LV_TABLE_COL_MAX 12 +# define LV_TABLE_CELL_STYLE_CNT 4 +#endif + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define LV_USE_TABVIEW 1 +# if LV_USE_TABVIEW != 0 +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TABVIEW_DEF_ANIM_TIME 300 +#endif + +/*Tileview (dependencies: lv_page) */ +#define LV_USE_TILEVIEW 1 +#if LV_USE_TILEVIEW +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TILEVIEW_DEF_ANIM_TIME 300 +#endif + +#define CONFIG_LV_USE_GIF 1 + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define LV_USE_WIN 1 + +/*================== + * Non-user section + *==================*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ +# define _CRT_SECURE_NO_WARNINGS +#endif + +/*--END OF LV_CONF_H--*/ + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/include/liblvgl/lv_conf.old.h b/include/liblvgl/lv_conf.old.h new file mode 100644 index 0000000..16deedd --- /dev/null +++ b/include/liblvgl/lv_conf.old.h @@ -0,0 +1,341 @@ +/** + * @file lv_conf.h + * + */ + +#ifndef LV_CONF_H +#define LV_CONF_H + +/*---------------- + * Dynamic memory + *----------------*/ + +/* Memory size which will be used by the library + * to store the graphical objects and other data */ +#define LV_MEM_CUSTOM \ + 0 /*1: use custom malloc/free, 0: use the built-in \ + lv_mem_alloc/lv_mem_free*/ +#if LV_MEM_CUSTOM == 0 +#define LV_MEM_SIZE \ + (32U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +#define LV_MEM_ATTR /*Complier prefix for big array declaration*/ +#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ +#else /*LV_MEM_CUSTOM*/ +#define LV_MEM_CUSTOM_INCLUDE \ + /*Header for the dynamic memory function*/ +#define LV_MEM_CUSTOM_ALLOC kmalloc /*Wrapper to malloc*/ +#define LV_MEM_CUSTOM_FREE kfree /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ +#define LV_ENABLE_GC 0 + +/*=================== + Graphical settings + *===================*/ + +/* Horizontal and vertical resolution of the library.*/ +#define LV_HOR_RES (480) +#define LV_VER_RES (240) +#define LV_DPI 126 + +/* Size of VDB (Virtual Display Buffer: the internal graphics buffer). + * Required for buffered drawing, opacity and anti-aliasing + * VDB makes the double buffering, you don't need to deal with it! + * Typical size: ~1/10 screen */ +#define LV_VDB_SIZE \ + (LV_VER_RES * \ + LV_HOR_RES) /*Size of VDB in pixel count (1/10 screen size is good for \ + first)*/ +#define LV_VDB_ADR \ + 0 /*Place VDB to a specific address (e.g. in external RAM) (0: allocate \ + automatically into RAM)*/ + +/* Use two Virtual Display buffers (VDB) parallelize rendering and flushing + * (optional) + * The flushing should use DMA to write the frame buffer in the background*/ +#define LV_VDB_DOUBLE 0 /*1: Enable the use of 2 VDBs*/ +#define LV_VDB2_ADR \ + 0 /*Place VDB2 to a specific address (e.g. in external RAM) (0: allocate \ + automatically into RAM)*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ + +/*Screen refresh settings*/ +#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/ +#define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */ + +/*================= + Misc. setting + *=================*/ + +/*Input device settings*/ +#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ +#define LV_INDEV_POINT_MARKER \ + 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/ +#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ +#define LV_INDEV_DRAG_THROW \ + 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */ +#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/ +#define LV_INDEV_LONG_PRESS_REP_TIME \ + 100 /*Repeated trigger period in long press [ms] */ + +/*Color settings*/ +#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/24*/ +#define LV_COLOR_TRANSP \ + LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma \ + keying)*/ + +/*Text settings*/ +#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */ +#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ +#define LV_TXT_LINE_BREAK_LONG_LEN 12 +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 1 + +/*Graphics feature usage*/ +#define USE_LV_ANIMATION 1 /*1: Enable all animations*/ +#define USE_LV_SHADOW 1 /*1: Enable shadows*/ +#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ +#define USE_LV_GPU 0 /*1: Enable GPU interface*/ +#define USE_LV_REAL_DRAW \ + 1 /*1: Enable function which draw directly to the frame buffer instead of \ + VDB (required if LV_VDB_SIZE = 0)*/ +#define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/ +#define USE_LV_MULTI_LANG 1 + +/*Compiler attributes*/ +#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to tick increment \ + function */ +#define LV_ATTRIBUTE_TASK_HANDLER +#define LV_ATTRIBUTE_MEM_ALIGN +#define LV_COMPILER_VLA_SUPPORTED 1 +#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 1 + +#define USE_LV_LOG 0 +/*================ + * THEME USAGE + *================*/ +#define LV_THEME_LIVE_UPDATE 1 +#define USE_LV_THEME_TEMPL 0 /*Just for test*/ +#define USE_LV_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/ +#define USE_LV_THEME_ALIEN 1 /*Dark futuristic theme*/ +#define USE_LV_THEME_NIGHT 1 /*Dark elegant theme*/ +#define USE_LV_THEME_MONO 1 /*Mono color theme for monochrome displays*/ +#define USE_LV_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ +#define USE_LV_THEME_ZEN 1 /*Peaceful, mainly light theme */ + +/*================== + * FONT USAGE + *===================*/ + +/* More info about fonts: https://littlevgl.com/basics#fonts + * To enable a built-in font use 1,2,4 or 8 values + * which will determine the bit-per-pixel */ +#define LV_FONT_DEFAULT \ + &lv_font_dejavu_20 /*Always set a default font from the built-in fonts*/ + +#define USE_LV_FONT_DEJAVU_10 4 +#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 4 +#define USE_LV_FONT_DEJAVU_10_CYRILLIC 4 +#define USE_LV_FONT_SYMBOL_10 4 + +#define USE_LV_FONT_DEJAVU_20 4 +#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 4 +#define USE_LV_FONT_DEJAVU_20_CYRILLIC 4 +#define USE_LV_FONT_SYMBOL_20 4 + +#define USE_LV_FONT_DEJAVU_30 0 +#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_30_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_30 0 + +#define USE_LV_FONT_DEJAVU_40 0 +#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 0 +#define USE_LV_FONT_DEJAVU_40_CYRILLIC 0 +#define USE_LV_FONT_SYMBOL_40 0 + +/* PROS adds the mono variant of DejaVu sans */ +#define USE_PROS_FONT_DEJAVU_MONO_10 4 +#define USE_PROS_FONT_DEJAVU_MONO_10_LATIN_SUP 4 + +#define USE_PROS_FONT_DEJAVU_MONO_20 4 +#define USE_PROS_FONT_DEJAVU_MONO_LATIN_SUP_20 4 + +#define USE_PROS_FONT_DEJAVU_MONO_30 0 +#define USE_PROS_FONT_DEJAVU_MONO_30_LATIN_SUP 0 + +#define USE_PROS_FONT_DEJAVU_MONO_40 0 +#define USE_PROS_FONT_DEJAVU_MONO_40_LATIN_SUP 0 + +/*=================== + * LV_OBJ SETTINGS + *==================*/ +#define LV_OBJ_FREE_NUM_TYPE \ + uint32_t /*Type of free number attribute (comment out disable free number)*/ +#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/ + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://littlevgl.com/object-types + */ + +/***************** + * Simple object + *****************/ + +/*Label (dependencies: -*/ +#define USE_LV_LABEL 1 +#if USE_LV_LABEL != 0 +#define LV_LABEL_SCROLL_SPEED \ + 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' \ + mode*/ +#endif + +/*Image (dependencies: lv_label*/ +#define USE_LV_IMG 1 +#if USE_LV_IMG != 0 +# define LV_IMG_CF_INDEXED 1 +# define LV_IMG_CF_ALPHA 1 +#endif + +/*Line (dependencies: -*/ +#define USE_LV_LINE 1 +#define USE_LV_ARC 1 + +/******************* + * Container objects + *******************/ + +/*Container (dependencies: -*/ +#define USE_LV_CONT 1 + +/*Page (dependencies: lv_cont)*/ +#define USE_LV_PAGE 1 + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define USE_LV_WIN 1 + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define USE_LV_TABVIEW 1 +#if USE_LV_TABVIEW != 0 +#define LV_TABVIEW_ANIM_TIME \ + 300 /*Time of slide animation [ms] (0: no animation)*/ +#endif +#define USE_LV_TILEVIEW 1 +#if USE_LV_TILEVIEW +# define LV_TILEVIEW_ANIM_TIME 300 +#endif + + +/************************* + * Data visualizer objects + *************************/ + +/*Bar (dependencies: -)*/ +#define USE_LV_BAR 1 + +/*Line meter (dependencies: *;)*/ +#define USE_LV_LMETER 1 + +/*Gauge (dependencies:bar, lmeter)*/ +#define USE_LV_GAUGE 1 + +/*Chart (dependencies: -)*/ +#define USE_LV_CHART 1 + +#define USE_LV_TABLE 1 +#if USE_LV_TABLE +# define LV_TABLE_COL_MAX 12 +#endif + +/*LED (dependencies: -)*/ +#define USE_LV_LED 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define USE_LV_MBOX 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define USE_LV_TA 1 +#if USE_LV_TA != 0 +#define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/ +#define LV_TA_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +#define USE_LV_SPINBOX 1 +#define USE_LV_CALENDAR 1 + +#define USE_PRELOAD 1 +#if USE_LV_PRELOAD != 0 +# define LV_PRELOAD_DEF_ARC_LENGTH 60 +# define LV_PRELOAD_DEF_SPIN_TIME 1000 +# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC +#endif + +#define USE_LV_CANVAS 1 +/************************* + * User input objects + *************************/ + +/*Button (dependencies: lv_cont*/ +#define USE_LV_BTN 1 +#if USE_LV_BTN != 0 +# define LV_BTN_INK_EFFECT 1 +#endif + +#define USE_LV_IMGBTN 1 +#if USE_LV_IMGBTN +# define LV_IMGBTN_TILED 0 +#endif + +/*Button matrix (dependencies: -)*/ +#define USE_LV_BTNM 1 + +/*Keyboard (dependencies: lv_btnm)*/ +#define USE_LV_KB 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define USE_LV_CB 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons + * ))*/ +#define USE_LV_LIST 1 +#if USE_LV_LIST != 0 +#define LV_LIST_FOCUS_TIME \ + 100 /*Default animation time of focusing to a list element [ms] (0: no \ + animation) */ +#endif + +/*Drop down list (dependencies: lv_page, lv_label)*/ +#define USE_LV_DDLIST 1 +#if USE_LV_DDLIST != 0 +#define LV_DDLIST_ANIM_TIME \ + 200 /*Open and close default animation time [ms] (0: no animation)*/ +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define USE_LV_ROLLER 1 +#if USE_LV_ROLLER != 0 +#define LV_ROLLER_ANIM_TIME \ + 200 /*Focus animation time [ms] (0: no \ + animation)*/ +#endif + +/*Slider (dependencies: lv_bar)*/ +#define USE_LV_SLIDER 1 + +/*Switch (dependencies: lv_slider)*/ +#define USE_LV_SW 1 + +#if LV_INDEV_DRAG_THROW <= 0 +#warning "LV_INDEV_DRAG_THROW must be greater than 0" +#undef LV_INDEV_DRAG_THROW +#define LV_INDEV_DRAG_THROW 1 +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +# define _CRT_SECURE_NO_WARNINGS +#endif +#include "liblvgl/lv_conf_checker.h" +#endif /*LV_CONF_H*/ diff --git a/include/liblvgl/lv_conf_checker.h b/include/liblvgl/lv_conf_checker.h new file mode 100644 index 0000000..3a8ead5 --- /dev/null +++ b/include/liblvgl/lv_conf_checker.h @@ -0,0 +1,664 @@ +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_conf_checker.h + * Make sure all the defines of lv_conf.h have a default value +**/ + +#ifndef LV_CONF_CHECKER_H +#define LV_CONF_CHECKER_H +/*=================== + Dynamic memory + *===================*/ + +/* Memory size which will be used by the library + * to store the graphical objects and other data */ +#ifndef LV_MEM_CUSTOM +#define LV_MEM_CUSTOM 0 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/ +#endif +#if LV_MEM_CUSTOM == 0 +#ifndef LV_MEM_SIZE +# define LV_MEM_SIZE (64U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +#endif +#ifndef LV_MEM_ATTR +# define LV_MEM_ATTR /*Complier prefix for big array declaration*/ +#endif +#ifndef LV_MEM_ADR +# define LV_MEM_ADR 0 /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/ +#endif +#ifndef LV_MEM_AUTO_DEFRAG +# define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ +#endif +#else /*LV_MEM_CUSTOM*/ +#ifndef LV_MEM_CUSTOM_INCLUDE +# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ +#endif +#ifndef LV_MEM_CUSTOM_ALLOC +# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ +#endif +#ifndef LV_MEM_CUSTOM_FREE +# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ +#endif +#endif /*LV_MEM_CUSTOM*/ + +/* Garbage Collector settings + * Used if lvgl is binded to higher language and the memory is managed by that language */ +#ifndef LV_ENABLE_GC +#define LV_ENABLE_GC 0 +#endif +#if LV_ENABLE_GC != 0 +#ifndef LV_MEM_CUSTOM_REALLOC +# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ +#endif +#ifndef LV_MEM_CUSTOM_GET_SIZE +# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ +#endif +#ifndef LV_GC_INCLUDE +# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ +#endif +#endif /* LV_ENABLE_GC */ + +/*=================== + Graphical settings + *===================*/ + +/* Horizontal and vertical resolution of the library.*/ +#ifndef LV_HOR_RES +#define LV_HOR_RES (480) +#endif +#ifndef LV_VER_RES +#define LV_VER_RES (320) +#endif + +/* Dot Per Inch: used to initialize default sizes. E.g. a button with width = LV_DPI / 2 -> half inch wide + * (Not so important, you can adjust it to modify default sizes and spaces)*/ +#ifndef LV_DPI +#define LV_DPI 100 +#endif + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#ifndef LV_ANTIALIAS +#define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ +#endif + +/*Screen refresh period in milliseconds*/ +#ifndef LV_REFR_PERIOD +#define LV_REFR_PERIOD 30 +#endif + +/*----------------- + * VDB settings + *----------------*/ + +/* VDB (Virtual Display Buffer) is an internal graphics buffer. + * The GUI will be drawn into this buffer first and then + * the buffer will be passed to your `disp_drv.disp_flush` function to + * copy it to your frame buffer. + * VDB is required for: buffered drawing, opacity, anti-aliasing and shadows + * Learn more: https://docs.littlevgl.com/#Drawing*/ + +/* Size of the VDB in pixels. Typical size: ~1/10 screen. Must be >= LV_HOR_RES + * Setting it to 0 will disable VDB and `disp_drv.disp_fill` and `disp_drv.disp_map` functions + * will be called to draw to the frame buffer directly*/ +#ifndef LV_VDB_SIZE +#define LV_VDB_SIZE ((LV_VER_RES * LV_HOR_RES) / 10) +#endif + + /* Bit-per-pixel of VDB. Useful for monochrome or non-standard color format displays. + * Special formats are handled with `disp_drv.vdb_wr`)*/ +#ifndef LV_VDB_PX_BPP +#define LV_VDB_PX_BPP LV_COLOR_SIZE /*LV_COLOR_SIZE comes from LV_COLOR_DEPTH below to set 8, 16 or 32 bit pixel size automatically */ +#endif + + /* Place VDB to a specific address (e.g. in external RAM) + * 0: allocate automatically into RAM + * LV_VDB_ADR_INV: to replace it later with `lv_vdb_set_adr()`*/ +#ifndef LV_VDB_ADR +#define LV_VDB_ADR 0 +#endif + +/* Use two Virtual Display buffers (VDB) to parallelize rendering and flushing + * The flushing should use DMA to write the frame buffer in the background */ +#ifndef LV_VDB_DOUBLE +#define LV_VDB_DOUBLE 0 +#endif + +/* Place VDB2 to a specific address (e.g. in external RAM) + * 0: allocate automatically into RAM + * LV_VDB_ADR_INV: to replace it later with `lv_vdb_set_adr()`*/ +#ifndef LV_VDB2_ADR +#define LV_VDB2_ADR 0 +#endif + +/* Using true double buffering in `disp_drv.disp_flush` you will always get the image of the whole screen. + * Your only task is to set the rendered image (`color_p` parameter) as frame buffer address or send it to your display. + * The best if you do in the blank period of you display to avoid tearing effect. + * Requires: + * - LV_VDB_SIZE = LV_HOR_RES * LV_VER_RES + * - LV_VDB_DOUBLE = 1 + */ +#ifndef LV_VDB_TRUE_DOUBLE_BUFFERED +#define LV_VDB_TRUE_DOUBLE_BUFFERED 0 +#endif + +/*================= + Misc. setting + *=================*/ + +/*Input device settings*/ +#ifndef LV_INDEV_READ_PERIOD +#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ +#endif +#ifndef LV_INDEV_POINT_MARKER +#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/ +#endif +#ifndef LV_INDEV_DRAG_LIMIT +#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ +#endif +#ifndef LV_INDEV_DRAG_THROW +#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%] (must be > 0). Greater value means faster slow-down */ +#endif +#ifndef LV_INDEV_LONG_PRESS_TIME +#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/ +#endif +#ifndef LV_INDEV_LONG_PRESS_REP_TIME +#define LV_INDEV_LONG_PRESS_REP_TIME 100 /*Repeated trigger period in long press [ms] */ +#endif + +/*Color settings*/ +#ifndef LV_COLOR_DEPTH +#define LV_COLOR_DEPTH 16 /*Color depth: 1/8/16/32*/ +#endif +#ifndef LV_COLOR_16_SWAP +#define LV_COLOR_16_SWAP 0 /*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/ +#endif +#ifndef LV_COLOR_SCREEN_TRANSP +#define LV_COLOR_SCREEN_TRANSP 0 /*1: Enable screen transparency. Useful for OSD or other overlapping GUIs. Requires ARGB8888 colors*/ +#endif +#ifndef LV_COLOR_TRANSP +#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/ +#endif + +/*Text settings*/ +#ifndef LV_TXT_UTF8 +#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */ +#endif +#ifndef LV_TXT_BREAK_CHARS +#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ +#endif +#ifndef LV_TXT_LINE_BREAK_LONG_LEN +#define LV_TXT_LINE_BREAK_LONG_LEN 12 /* If a character is at least this long, will break wherever "prettiest" */ +#endif +#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 /* Minimum number of characters of a word to put on a line before a break */ +#endif +#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 1 /* Minimum number of characters of a word to put on a line after a break */ +#endif + +/*Feature usage*/ +#ifndef USE_LV_ANIMATION +#define USE_LV_ANIMATION 1 /*1: Enable all animations*/ +#endif +#ifndef USE_LV_SHADOW +#define USE_LV_SHADOW 1 /*1: Enable shadows*/ +#endif +#ifndef USE_LV_GROUP +#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ +#endif +#ifndef USE_LV_GPU +#define USE_LV_GPU 1 /*1: Enable GPU interface*/ +#endif +#ifndef USE_LV_REAL_DRAW +#define USE_LV_REAL_DRAW 1 /*1: Enable function which draw directly to the frame buffer instead of VDB (required if LV_VDB_SIZE = 0)*/ +#endif +#ifndef USE_LV_FILESYSTEM +#define USE_LV_FILESYSTEM 1 /*1: Enable file system (might be required for images*/ +#endif +#ifndef USE_LV_MULTI_LANG +#define USE_LV_MULTI_LANG 0 /* Number of languages for labels to store (0: to disable this feature)*/ +#endif + +/*Compiler settings*/ +#ifndef LV_ATTRIBUTE_TICK_INC +#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to `lv_tick_inc` function */ +#endif +#ifndef LV_ATTRIBUTE_TASK_HANDLER +#define LV_ATTRIBUTE_TASK_HANDLER /* Define a custom attribute to `lv_task_handler` function */ +#endif +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN /* With size optimization (-Os) the compiler might not align data to 4 or 8 byte boundary. This alignment will be explicitly applied where needed.*/ +#endif +#ifndef LV_COMPILER_VLA_SUPPORTED +#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/ +#endif +#ifndef LV_COMPILER_NON_CONST_INIT_SUPPORTED +#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 1 /* 1: Initialization with non constant values are supported */ +#endif + +/*HAL settings*/ +#ifndef LV_TICK_CUSTOM +#define LV_TICK_CUSTOM 0 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */ +#endif +#if LV_TICK_CUSTOM == 1 +#ifndef LV_TICK_CUSTOM_INCLUDE +#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/ +#endif +#ifndef LV_TICK_CUSTOM_SYS_TIME_EXPR +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/ +#endif +#endif /*LV_TICK_CUSTOM*/ + + +/*Log settings*/ +#ifndef USE_LV_LOG +#define USE_LV_LOG 1 /*Enable/disable the log module*/ +#endif +#if USE_LV_LOG +/* How important log should be added: + * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + * LV_LOG_LEVEL_INFO Log important events + * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't caused problem + * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + */ +#ifndef LV_LOG_LEVEL +# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN +#endif +/* 1: Print the log with 'printf'; 0: user need to register a callback*/ + +#ifndef LV_LOG_PRINTF +# define LV_LOG_PRINTF 0 +#endif +#endif /*USE_LV_LOG*/ + +/*================ + * THEME USAGE + *================*/ +#ifndef LV_THEME_LIVE_UPDATE +#define LV_THEME_LIVE_UPDATE 1 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/ +#endif + +#ifndef USE_LV_THEME_TEMPL +#define USE_LV_THEME_TEMPL 0 /*Just for test*/ +#endif +#ifndef USE_LV_THEME_DEFAULT +#define USE_LV_THEME_DEFAULT 1 /*Built mainly from the built-in styles. Consumes very few RAM*/ +#endif +#ifndef USE_LV_THEME_ALIEN +#define USE_LV_THEME_ALIEN 1 /*Dark futuristic theme*/ +#endif +#ifndef USE_LV_THEME_NIGHT +#define USE_LV_THEME_NIGHT 1 /*Dark elegant theme*/ +#endif +#ifndef USE_LV_THEME_MONO +#define USE_LV_THEME_MONO 1 /*Mono color theme for monochrome displays*/ +#endif +#ifndef USE_LV_THEME_MATERIAL +#define USE_LV_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ +#endif +#ifndef USE_LV_THEME_ZEN +#define USE_LV_THEME_ZEN 1 /*Peaceful, mainly light theme */ +#endif +#ifndef USE_LV_THEME_NEMO +#define USE_LV_THEME_NEMO 1 /*Water-like theme based on the movie "Finding Nemo"*/ +#endif + +/*================== + * FONT USAGE + *===================*/ + +/* More info about fonts: https://docs.littlevgl.com/#Fonts + * To enable a built-in font use 1,2,4 or 8 values + * which will determine the bit-per-pixel. Higher value means smoother fonts */ +#ifndef USE_LV_FONT_DEJAVU_10 +#define USE_LV_FONT_DEJAVU_10 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_10_LATIN_SUP +#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_10_CYRILLIC +#define USE_LV_FONT_DEJAVU_10_CYRILLIC 4 +#endif +#ifndef USE_LV_FONT_SYMBOL_10 +#define USE_LV_FONT_SYMBOL_10 4 +#endif + +#ifndef USE_LV_FONT_DEJAVU_20 +#define USE_LV_FONT_DEJAVU_20 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_20_LATIN_SUP +#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_20_CYRILLIC +#define USE_LV_FONT_DEJAVU_20_CYRILLIC 4 +#endif +#ifndef USE_LV_FONT_SYMBOL_20 +#define USE_LV_FONT_SYMBOL_20 4 +#endif + +#ifndef USE_LV_FONT_DEJAVU_30 +#define USE_LV_FONT_DEJAVU_30 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_30_LATIN_SUP +#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_30_CYRILLIC +#define USE_LV_FONT_DEJAVU_30_CYRILLIC 4 +#endif +#ifndef USE_LV_FONT_SYMBOL_30 +#define USE_LV_FONT_SYMBOL_30 4 +#endif + +#ifndef USE_LV_FONT_DEJAVU_40 +#define USE_LV_FONT_DEJAVU_40 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_40_LATIN_SUP +#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 4 +#endif +#ifndef USE_LV_FONT_DEJAVU_40_CYRILLIC +#define USE_LV_FONT_DEJAVU_40_CYRILLIC 4 +#endif +#ifndef USE_LV_FONT_SYMBOL_40 +#define USE_LV_FONT_SYMBOL_40 4 +#endif + +#ifndef USE_LV_FONT_MONOSPACE_8 +#define USE_LV_FONT_MONOSPACE_8 1 +#endif + +/* Optionally declare your custom fonts here. + * You can use these fonts as default font too + * and they will be available globally. E.g. + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ + * LV_FONT_DECLARE(my_font_2) \ + */ +#ifndef LV_FONT_CUSTOM_DECLARE +#define LV_FONT_CUSTOM_DECLARE +#endif + + +#ifndef LV_FONT_DEFAULT +#define LV_FONT_DEFAULT &lv_font_dejavu_20 /*Always set a default font from the built-in fonts*/ +#endif + +/*=================== + * LV_OBJ SETTINGS + *==================*/ +#ifndef LV_OBJ_FREE_NUM_TYPE +#define LV_OBJ_FREE_NUM_TYPE uint32_t /*Type of free number attribute (comment out disable free number)*/ +#endif +#ifndef LV_OBJ_FREE_PTR +#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/ +#endif +#ifndef LV_OBJ_REALIGN +#define LV_OBJ_REALIGN 1 /*Enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/ +#endif + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://docs.littlevgl.com/#Object-types + */ + +/***************** + * Simple object + *****************/ + +/*Label (dependencies: -*/ +#ifndef USE_LV_LABEL +#define USE_LV_LABEL 1 +#endif +#if USE_LV_LABEL != 0 +#ifndef LV_LABEL_SCROLL_SPEED +# define LV_LABEL_SCROLL_SPEED 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/ +#endif +#endif + +/*Image (dependencies: lv_label*/ +#ifndef USE_LV_IMG +#define USE_LV_IMG 1 +#endif +#if USE_LV_IMG != 0 +#ifndef LV_IMG_CF_INDEXED +# define LV_IMG_CF_INDEXED 1 /*Enable indexed (palette) images*/ +#endif +#ifndef LV_IMG_CF_ALPHA +# define LV_IMG_CF_ALPHA 1 /*Enable alpha indexed images*/ +#endif +#endif + +/*Line (dependencies: -*/ +#ifndef USE_LV_LINE +#define USE_LV_LINE 1 +#endif + +/*Arc (dependencies: -)*/ +#ifndef USE_LV_ARC +#define USE_LV_ARC 1 +#endif + +/******************* + * Container objects + *******************/ + +/*Container (dependencies: -*/ +#ifndef USE_LV_CONT +#define USE_LV_CONT 1 +#endif + +/*Page (dependencies: lv_cont)*/ +#ifndef USE_LV_PAGE +#define USE_LV_PAGE 1 +#endif + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#ifndef USE_LV_WIN +#define USE_LV_WIN 1 +#endif + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#ifndef USE_LV_TABVIEW +#define USE_LV_TABVIEW 1 +#endif +# if USE_LV_TABVIEW != 0 +#ifndef LV_TABVIEW_ANIM_TIME +# define LV_TABVIEW_ANIM_TIME 300 /*Time of slide animation [ms] (0: no animation)*/ +#endif +#endif + +/*Tileview (dependencies: lv_page) */ +#ifndef USE_LV_TILEVIEW +#define USE_LV_TILEVIEW 1 +#endif +#if USE_LV_TILEVIEW +#ifndef LV_TILEVIEW_ANIM_TIME +# define LV_TILEVIEW_ANIM_TIME 300 /*Time of slide animation [ms] (0: no animation)*/ +#endif +#endif + +/************************* + * Data visualizer objects + *************************/ + +/*Bar (dependencies: -)*/ +#ifndef USE_LV_BAR +#define USE_LV_BAR 1 +#endif + +/*Line meter (dependencies: *;)*/ +#ifndef USE_LV_LMETER +#define USE_LV_LMETER 1 +#endif + +/*Gauge (dependencies:lv_bar, lv_lmeter)*/ +#ifndef USE_LV_GAUGE +#define USE_LV_GAUGE 1 +#endif + +/*Chart (dependencies: -)*/ +#ifndef USE_LV_CHART +#define USE_LV_CHART 1 +#endif + +/*Table (dependencies: lv_label)*/ +#ifndef USE_LV_TABLE +#define USE_LV_TABLE 1 +#endif +#if USE_LV_TABLE +#ifndef LV_TABLE_COL_MAX +# define LV_TABLE_COL_MAX 12 +#endif +#endif + +/*LED (dependencies: -)*/ +#ifndef USE_LV_LED +#define USE_LV_LED 1 +#endif + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#ifndef USE_LV_MBOX +#define USE_LV_MBOX 1 +#endif + +/*Text area (dependencies: lv_label, lv_page)*/ +#ifndef USE_LV_TA +#define USE_LV_TA 1 +#endif +#if USE_LV_TA != 0 +#ifndef LV_TA_CURSOR_BLINK_TIME +# define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/ +#endif +#ifndef LV_TA_PWD_SHOW_TIME +# define LV_TA_PWD_SHOW_TIME 1500 /*ms*/ +#endif +#endif + +/*Spinbox (dependencies: lv_ta)*/ +#ifndef USE_LV_SPINBOX +#define USE_LV_SPINBOX 1 +#endif + +/*Calendar (dependencies: -)*/ +#ifndef USE_LV_CALENDAR +#define USE_LV_CALENDAR 1 +#endif + +/*Preload (dependencies: lv_arc)*/ +#ifndef USE_LV_PRELOAD +#define USE_LV_PRELOAD 1 +#endif +#if USE_LV_PRELOAD != 0 +#ifndef LV_PRELOAD_DEF_ARC_LENGTH +# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/ +#endif +#ifndef LV_PRELOAD_DEF_SPIN_TIME +# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ +#endif +#ifndef LV_PRELOAD_DEF_ANIM +# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC +#endif +#endif + +/*Canvas (dependencies: lv_img)*/ +#ifndef USE_LV_CANVAS +#define USE_LV_CANVAS 1 +#endif +/************************* + * User input objects + *************************/ + +/*Button (dependencies: lv_cont*/ +#ifndef USE_LV_BTN +#define USE_LV_BTN 1 +#endif +#if USE_LV_BTN != 0 +#ifndef LV_BTN_INK_EFFECT +# define LV_BTN_INK_EFFECT 1 /*Enable button-state animations - draw a circle on click (dependencies: USE_LV_ANIMATION)*/ +#endif +#endif + +/*Image Button (dependencies: lv_btn*/ +#ifndef USE_LV_IMGBTN +#define USE_LV_IMGBTN 1 +#endif +#if USE_LV_IMGBTN +#ifndef LV_IMGBTN_TILED +# define LV_IMGBTN_TILED 0 /*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ +#endif +#endif + +/*Button matrix (dependencies: -)*/ +#ifndef USE_LV_BTNM +#define USE_LV_BTNM 1 +#endif + +/*Keyboard (dependencies: lv_btnm)*/ +#ifndef USE_LV_KB +#define USE_LV_KB 1 +#endif + +/*Check box (dependencies: lv_btn, lv_label)*/ +#ifndef USE_LV_CB +#define USE_LV_CB 1 +#endif + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ +#ifndef USE_LV_LIST +#define USE_LV_LIST 1 +#endif +#if USE_LV_LIST != 0 +#ifndef LV_LIST_FOCUS_TIME +# define LV_LIST_FOCUS_TIME 100 /*Default animation time of focusing to a list element [ms] (0: no animation) */ +#endif +#endif + +/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ +#ifndef USE_LV_DDLIST +#define USE_LV_DDLIST 1 +#endif +#if USE_LV_DDLIST != 0 +#ifndef LV_DDLIST_ANIM_TIME +# define LV_DDLIST_ANIM_TIME 200 /*Open and close default animation time [ms] (0: no animation)*/ +#endif +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#ifndef USE_LV_ROLLER +#define USE_LV_ROLLER 1 +#endif +#if USE_LV_ROLLER != 0 +#ifndef LV_ROLLER_ANIM_TIME +# define LV_ROLLER_ANIM_TIME 200 /*Focus animation time [ms] (0: no animation)*/ +#endif +#endif + +/*Slider (dependencies: lv_bar)*/ +#ifndef USE_LV_SLIDER +#define USE_LV_SLIDER 1 +#endif + +/*Switch (dependencies: lv_slider)*/ +#ifndef USE_LV_SW +#define USE_LV_SW 1 +#endif + +/************************* + * Non-user section + *************************/ + +#if LV_INDEV_DRAG_THROW <= 0 +#warning "LV_INDEV_DRAG_THROW must be greater than 0" +#undef LV_INDEV_DRAG_THROW +#ifndef LV_INDEV_DRAG_THROW +#define LV_INDEV_DRAG_THROW 1 +#endif +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ +#ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +#endif +#endif + + +#endif /*LV_CONF_CHECKER_H*/ diff --git a/include/liblvgl/lv_conf_internal.h b/include/liblvgl/lv_conf_internal.h index c694dd6..97807fe 100644 --- a/include/liblvgl/lv_conf_internal.h +++ b/include/liblvgl/lv_conf_internal.h @@ -38,7 +38,7 @@ #elif defined(LV_CONF_INCLUDE_SIMPLE) /*Or simply include lv_conf.h is enabled*/ #include "lv_conf.h" #else - #include "liblvgl/lv_conf.h" /*Else assume lv_conf.h is next to the lvgl folder*/ + #include "../../lv_conf.h" /*Else assume lv_conf.h is next to the lvgl folder*/ #endif #if !defined(LV_CONF_H) && !defined(LV_CONF_SUPPRESS_DEFINE_CHECK) /* #include will sometimes silently fail when __has_include is used */ @@ -253,9 +253,6 @@ #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ #endif #endif - /*If using lvgl as ESP32 component*/ - // #define LV_TICK_CUSTOM_INCLUDE "esp_timer.h" - // #define LV_TICK_CUSTOM_SYS_TIME_EXPR ((esp_timer_get_time() / 1000LL)) #endif /*LV_TICK_CUSTOM*/ /*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. @@ -435,7 +432,7 @@ #endif #if LV_USE_GPU_STM32_DMA2D /*Must be defined to include path of CMSIS header of target processor - e.g. "stm32f7xx.h" or "stm32f4xx.h"*/ + e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ #ifndef LV_GPU_DMA2D_CMSIS_INCLUDE #ifdef CONFIG_LV_GPU_DMA2D_CMSIS_INCLUDE #define LV_GPU_DMA2D_CMSIS_INCLUDE CONFIG_LV_GPU_DMA2D_CMSIS_INCLUDE diff --git a/include/liblvgl/lv_version.h b/include/liblvgl/lv_version.h new file mode 100644 index 0000000..1e62e1e --- /dev/null +++ b/include/liblvgl/lv_version.h @@ -0,0 +1,66 @@ +/** + * @file lv_version.h + * + */ + +#ifndef LV_VERSION_H +#define LV_VERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +/*Current version of LittlevGL*/ +#define LVGL_VERSION_MAJOR 5 +#define LVGL_VERSION_MINOR 3 +#define LVGL_VERSION_PATCH 0 +#define LVGL_VERSION_INFO "" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ +/* Gives 1 if the x.y.z version is supported in the current version + * Usage: + * + * - Require v6 + * #if LV_VERSION_CHECK(6,0,0) + * new_func_in_v6(); + * #endif + * + * + * - Require at least v5.3 + * #if LV_VERSION_CHECK(5,3,0) + * new_feature_from_v5_3(); + * #endif + * + * + * - Require v5.3.2 bugfixes + * #if LV_VERSION_CHECK(5,3,2) + * bugfix_in_v5_3_2(); + * #endif + * + * */ +#define LV_VERSION_CHECK(x,y,z) (x == LVGL_VERSION_MAJOR && (y < LVGL_VERSION_MINOR || (y == LVGL_VERSION_MINOR && z <= LVGL_VERSION_PATCH))) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_VERSION_H*/ diff --git a/include/liblvgl/lvgl.h b/include/liblvgl/lvgl.h index c178c9e..60d29f5 100644 --- a/include/liblvgl/lvgl.h +++ b/include/liblvgl/lvgl.h @@ -15,8 +15,8 @@ extern "C" { ***************************/ #define LVGL_VERSION_MAJOR 8 #define LVGL_VERSION_MINOR 3 -#define LVGL_VERSION_PATCH 6 -#define LVGL_VERSION_INFO "" +#define LVGL_VERSION_PATCH 4 +#define LVGL_VERSION_INFO "dev" /********************* * INCLUDES diff --git a/include/liblvgl/misc/lv_anim.h b/include/liblvgl/misc/lv_anim.h index faef727..cb460ab 100644 --- a/include/liblvgl/misc/lv_anim.h +++ b/include/liblvgl/misc/lv_anim.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_area.h b/include/liblvgl/misc/lv_area.h index 137931a..036767b 100644 --- a/include/liblvgl/misc/lv_area.h +++ b/include/liblvgl/misc/lv_area.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_assert.h b/include/liblvgl/misc/lv_assert.h index 48db744..4625297 100644 --- a/include/liblvgl/misc/lv_assert.h +++ b/include/liblvgl/misc/lv_assert.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include "lv_log.h" #include "lv_mem.h" #include LV_ASSERT_HANDLER_INCLUDE diff --git a/include/liblvgl/misc/lv_bidi.h b/include/liblvgl/misc/lv_bidi.h index a27b580..fafb4a2 100644 --- a/include/liblvgl/misc/lv_bidi.h +++ b/include/liblvgl/misc/lv_bidi.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_color.h b/include/liblvgl/misc/lv_color.h index 2cc92f2..8e80a61 100644 --- a/include/liblvgl/misc/lv_color.h +++ b/include/liblvgl/misc/lv_color.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include "lv_assert.h" #include "lv_math.h" #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_fs.h b/include/liblvgl/misc/lv_fs.h index 9f65e1b..13b2eeb 100644 --- a/include/liblvgl/misc/lv_fs.h +++ b/include/liblvgl/misc/lv_fs.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_gc.h b/include/liblvgl/misc/lv_gc.h index 9d7d1bb..7a98d10 100644 --- a/include/liblvgl/misc/lv_gc.h +++ b/include/liblvgl/misc/lv_gc.h @@ -13,15 +13,15 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include "lv_mem.h" #include "lv_ll.h" #include "lv_timer.h" #include "lv_types.h" -#include "../draw/lv_img_cache.h" -#include "../draw/lv_draw_mask.h" -#include "../core/lv_obj_pos.h" +#include "liblvgl/draw/lv_img_cache.h" +#include "liblvgl/draw/lv_draw_mask.h" +#include "liblvgl/core/lv_obj_pos.h" /********************* * DEFINES diff --git a/include/liblvgl/misc/lv_log.h b/include/liblvgl/misc/lv_log.h index 9a00993..cd61905 100644 --- a/include/liblvgl/misc/lv_log.h +++ b/include/liblvgl/misc/lv_log.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_lru.h b/include/liblvgl/misc/lv_lru.h index 2d0134e..3e9729e 100644 --- a/include/liblvgl/misc/lv_lru.h +++ b/include/liblvgl/misc/lv_lru.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_math.h b/include/liblvgl/misc/lv_math.h index 4b2860a..24f9ea6 100644 --- a/include/liblvgl/misc/lv_math.h +++ b/include/liblvgl/misc/lv_math.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include /********************* diff --git a/include/liblvgl/misc/lv_mem.h b/include/liblvgl/misc/lv_mem.h index 7a83b3d..fd202ab 100644 --- a/include/liblvgl/misc/lv_mem.h +++ b/include/liblvgl/misc/lv_mem.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include diff --git a/include/liblvgl/misc/lv_misc.mk b/include/liblvgl/misc/lv_misc.mk deleted file mode 100644 index 1dfd4ee..0000000 --- a/include/liblvgl/misc/lv_misc.mk +++ /dev/null @@ -1,26 +0,0 @@ -CSRCS += lv_anim.c -CSRCS += lv_anim_timeline.c -CSRCS += lv_area.c -CSRCS += lv_async.c -CSRCS += lv_bidi.c -CSRCS += lv_color.c -CSRCS += lv_fs.c -CSRCS += lv_gc.c -CSRCS += lv_ll.c -CSRCS += lv_log.c -CSRCS += lv_lru.c -CSRCS += lv_math.c -CSRCS += lv_mem.c -CSRCS += lv_printf.c -CSRCS += lv_style.c -CSRCS += lv_style_gen.c -CSRCS += lv_timer.c -CSRCS += lv_tlsf.c -CSRCS += lv_txt.c -CSRCS += lv_txt_ap.c -CSRCS += lv_utils.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc" diff --git a/include/liblvgl/misc/lv_style.h b/include/liblvgl/misc/lv_style.h index 5cf0b19..44a542d 100644 --- a/include/liblvgl/misc/lv_style.h +++ b/include/liblvgl/misc/lv_style.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include #include -#include "../font/lv_font.h" +#include "liblvgl/font/lv_font.h" #include "lv_color.h" #include "lv_area.h" #include "lv_anim.h" diff --git a/include/liblvgl/misc/lv_timer.h b/include/liblvgl/misc/lv_timer.h index a9a8e50..16572d3 100644 --- a/include/liblvgl/misc/lv_timer.h +++ b/include/liblvgl/misc/lv_timer.h @@ -12,8 +12,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" -#include "../hal/lv_hal_tick.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/hal/lv_hal_tick.h" #include #include diff --git a/include/liblvgl/misc/lv_txt.h b/include/liblvgl/misc/lv_txt.h index 46050dc..ae60e8b 100644 --- a/include/liblvgl/misc/lv_txt.h +++ b/include/liblvgl/misc/lv_txt.h @@ -13,12 +13,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #include #include #include "lv_area.h" -#include "../font/lv_font.h" +#include "liblvgl/font/lv_font.h" #include "lv_printf.h" #include "lv_types.h" diff --git a/include/liblvgl/misc/lv_txt_ap.h b/include/liblvgl/misc/lv_txt_ap.h index e2d94b8..3519bb6 100644 --- a/include/liblvgl/misc/lv_txt_ap.h +++ b/include/liblvgl/misc/lv_txt_ap.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include #include "lv_txt.h" -#include "../draw/lv_draw.h" +#include "liblvgl/draw/lv_draw.h" #if LV_USE_ARABIC_PERSIAN_CHARS == 1 diff --git a/include/liblvgl/widgets/lv_arc.h b/include/liblvgl/widgets/lv_arc.h index fd53fc1..96f4629 100644 --- a/include/liblvgl/widgets/lv_arc.h +++ b/include/liblvgl/widgets/lv_arc.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_ARC != 0 -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_bar.h b/include/liblvgl/widgets/lv_bar.h index 1726425..55d1711 100644 --- a/include/liblvgl/widgets/lv_bar.h +++ b/include/liblvgl/widgets/lv_bar.h @@ -13,12 +13,12 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_BAR != 0 -#include "../core/lv_obj.h" -#include "../misc/lv_anim.h" +#include "liblvgl/core/lv_obj.h" +#include "liblvgl/misc/lv_anim.h" #include "lv_btn.h" #include "lv_label.h" diff --git a/include/liblvgl/widgets/lv_btn.h b/include/liblvgl/widgets/lv_btn.h index 1d471f9..893e6a0 100644 --- a/include/liblvgl/widgets/lv_btn.h +++ b/include/liblvgl/widgets/lv_btn.h @@ -13,10 +13,10 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_BTN != 0 -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_btnmatrix.h b/include/liblvgl/widgets/lv_btnmatrix.h index 780d57b..31d62bb 100644 --- a/include/liblvgl/widgets/lv_btnmatrix.h +++ b/include/liblvgl/widgets/lv_btnmatrix.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_BTNMATRIX != 0 -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_canvas.h b/include/liblvgl/widgets/lv_canvas.h index 71f0516..f92a1c5 100644 --- a/include/liblvgl/widgets/lv_canvas.h +++ b/include/liblvgl/widgets/lv_canvas.h @@ -13,13 +13,13 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_CANVAS != 0 -#include "../core/lv_obj.h" -#include "../widgets/lv_img.h" -#include "../draw/lv_draw_img.h" +#include "liblvgl/core/lv_obj.h" +#include "liblvgl/widgets/lv_img.h" +#include "liblvgl/draw/lv_draw_img.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_checkbox.h b/include/liblvgl/widgets/lv_checkbox.h index 772f500..6b2bdc3 100644 --- a/include/liblvgl/widgets/lv_checkbox.h +++ b/include/liblvgl/widgets/lv_checkbox.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" -#include "../core/lv_obj.h" +#include "liblvgl/lv_conf_internal.h" +#include "liblvgl/core/lv_obj.h" #if LV_USE_CHECKBOX != 0 diff --git a/include/liblvgl/widgets/lv_dropdown.h b/include/liblvgl/widgets/lv_dropdown.h index 0c55e86..9848b14 100644 --- a/include/liblvgl/widgets/lv_dropdown.h +++ b/include/liblvgl/widgets/lv_dropdown.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_DROPDOWN != 0 diff --git a/include/liblvgl/widgets/lv_img.h b/include/liblvgl/widgets/lv_img.h index eb76c8d..5513a26 100644 --- a/include/liblvgl/widgets/lv_img.h +++ b/include/liblvgl/widgets/lv_img.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_IMG != 0 @@ -22,9 +22,9 @@ extern "C" { #error "lv_img: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" #endif -#include "../core/lv_obj.h" -#include "../misc/lv_fs.h" -#include "../draw/lv_draw.h" +#include "liblvgl/core/lv_obj.h" +#include "liblvgl/misc/lv_fs.h" +#include "liblvgl/draw/lv_draw.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_label.h b/include/liblvgl/widgets/lv_label.h index b31a63e..39a68db 100644 --- a/include/liblvgl/widgets/lv_label.h +++ b/include/liblvgl/widgets/lv_label.h @@ -18,11 +18,11 @@ extern "C" { #if LV_USE_LABEL != 0 #include -#include "../core/lv_obj.h" -#include "../font/lv_font.h" -#include "../font/lv_symbol_def.h" -#include "../misc/lv_txt.h" -#include "../draw/lv_draw.h" +#include "liblvgl/core/lv_obj.h" +#include "liblvgl/font/lv_font.h" +#include "liblvgl/font/lv_symbol_def.h" +#include "liblvgl/misc/lv_txt.h" +#include "liblvgl/draw/lv_draw.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_line.h b/include/liblvgl/widgets/lv_line.h index 54fa248..622ef81 100644 --- a/include/liblvgl/widgets/lv_line.h +++ b/include/liblvgl/widgets/lv_line.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_LINE != 0 -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_objx_templ.h b/include/liblvgl/widgets/lv_objx_templ.h index 9de5285..f363df4 100644 --- a/include/liblvgl/widgets/lv_objx_templ.h +++ b/include/liblvgl/widgets/lv_objx_templ.h @@ -20,11 +20,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_TEMPL != 0 -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_roller.h b/include/liblvgl/widgets/lv_roller.h index 14411de..4984c26 100644 --- a/include/liblvgl/widgets/lv_roller.h +++ b/include/liblvgl/widgets/lv_roller.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_ROLLER != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_roller: lv_label is required. Enable it in lv_conf.h (LV_USE_ROLLER 1)" #endif -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #include "lv_label.h" /********************* diff --git a/include/liblvgl/widgets/lv_slider.h b/include/liblvgl/widgets/lv_slider.h index 386950c..20c940f 100644 --- a/include/liblvgl/widgets/lv_slider.h +++ b/include/liblvgl/widgets/lv_slider.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_SLIDER != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_slider: lv_bar is required. Enable it in lv_conf.h (LV_USE_BAR 1)" #endif -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #include "lv_bar.h" /********************* diff --git a/include/liblvgl/widgets/lv_switch.h b/include/liblvgl/widgets/lv_switch.h index 83ca81b..63ec427 100644 --- a/include/liblvgl/widgets/lv_switch.h +++ b/include/liblvgl/widgets/lv_switch.h @@ -13,11 +13,11 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_SWITCH != 0 -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" /********************* * DEFINES diff --git a/include/liblvgl/widgets/lv_table.h b/include/liblvgl/widgets/lv_table.h index 9106270..311d914 100644 --- a/include/liblvgl/widgets/lv_table.h +++ b/include/liblvgl/widgets/lv_table.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_TABLE != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_table: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" #endif -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #include "lv_label.h" /********************* diff --git a/include/liblvgl/widgets/lv_textarea.h b/include/liblvgl/widgets/lv_textarea.h index 4b3289b..cfa47e4 100644 --- a/include/liblvgl/widgets/lv_textarea.h +++ b/include/liblvgl/widgets/lv_textarea.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" +#include "liblvgl/lv_conf_internal.h" #if LV_USE_TEXTAREA != 0 @@ -22,7 +22,7 @@ extern "C" { #error "lv_ta: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1)" #endif -#include "../core/lv_obj.h" +#include "liblvgl/core/lv_obj.h" #include "lv_label.h" /********************* diff --git a/include/liblvgl/widgets/lv_widgets.mk b/include/liblvgl/widgets/lv_widgets.mk deleted file mode 100644 index 4e62dc5..0000000 --- a/include/liblvgl/widgets/lv_widgets.mk +++ /dev/null @@ -1,20 +0,0 @@ -CSRCS += lv_arc.c -CSRCS += lv_bar.c -CSRCS += lv_btn.c -CSRCS += lv_btnmatrix.c -CSRCS += lv_canvas.c -CSRCS += lv_checkbox.c -CSRCS += lv_dropdown.c -CSRCS += lv_img.c -CSRCS += lv_label.c -CSRCS += lv_line.c -CSRCS += lv_roller.c -CSRCS += lv_slider.c -CSRCS += lv_switch.c -CSRCS += lv_table.c -CSRCS += lv_textarea.c - -DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets -VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets - -CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets" diff --git a/include/main.h b/include/main.h index a54a276..9407e1e 100644 --- a/include/main.h +++ b/include/main.h @@ -4,7 +4,7 @@ * Contains common definitions and header files used throughout your PROS * project. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public @@ -34,11 +34,12 @@ */ #define PROS_USE_LITERALS +#include "api.h" + /** - * Add includes here + * You should add more #includes here */ -#include "api.h" -#include "robodash/api.h" +//#include "okapi/api.hpp" /** * If you find doing pros::Motor() to be tedious and you'd prefer just to do @@ -50,6 +51,7 @@ */ // using namespace pros; // using namespace pros::literals; +// using namespace okapi; /** * Prototypes for the competition control tasks are redefined here to ensure @@ -72,7 +74,7 @@ void opcontrol(void); /** * You can add C++-only headers here */ -#include +//#include #endif -#endif // _PROS_MAIN_H_ +#endif // _PROS_MAIN_H_ diff --git a/include/pros/abstract_motor.hpp b/include/pros/abstract_motor.hpp index 46210b6..1468f35 100644 --- a/include/pros/abstract_motor.hpp +++ b/include/pros/abstract_motor.hpp @@ -1,1163 +1,1163 @@ -/** - * \file abstract_motor.hpp - * \ingroup cpp-abstract-motor - * - * Contains prototypes for AbstractMotor, the abstract base class of both - * motors and motor groups. Abstract motors cannot be directly constructed, but - * you can use motors and motor groups as abstract motors. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef _PROS_ABSTRACT_MOTORS_HPP_ -#define _PROS_ABSTRACT_MOTORS_HPP_ - -#include -#include - -#include "pros/device.hpp" -#include "pros/motors.h" -#include "rtos.hpp" - -namespace pros { -inline namespace v5 { - -/** - * \enum motor_brake - * Indicates the current 'brake mode' of a motor. - */ -enum class MotorBrake { - coast = 0, ///< Motor coasts when stopped, traditional behavior - brake = 1, ///< Motor brakes when stopped - hold = 2, ///< Motor actively holds position when stopped - invalid = INT32_MAX ///< Invalid brake mode -}; - -/** - * \enum Motor_Encoder_Units - * Indicates the units used by the motor encoders. - */ -enum class MotorEncoderUnits { - degrees = 0, ///< Position is recorded as angle in degrees as a floating point number - deg = 0, ///< Position is recorded as angle in degrees as a floating point number - rotations = 1, ///< Position is recorded as angle in rotations as a floating point number - counts = 2, ///< Position is recorded as raw encoder ticks as a whole number - invalid = INT32_MAX ///< Invalid motor encoder units -}; - -// Alias for Motor_Encoder_Units -using MotorUnits = MotorEncoderUnits; - -enum class MotorGears { - ratio_36_to_1 = 0, ///< 36:1, 100 RPM, Red gear set - red = ratio_36_to_1, ///< 36:1, 100 RPM, Red gear set - rpm_100 = ratio_36_to_1, ///< 36:1, 100 RPM, Red gear set - ratio_18_to_1 = 1, ///< 18:1, 200 RPM, Green gear set - green = ratio_18_to_1, ///< 18:1, 200 RPM, Green gear set - rpm_200 = ratio_18_to_1, ///< 18:1, 200 RPM, Green gear set - ratio_6_to_1 = 2, ///< 6:1, 600 RPM, Blue gear set - blue = ratio_6_to_1, ///< 6:1, 600 RPM, Blue gear set - rpm_600 = ratio_6_to_1, ///< 6:1, 600 RPM, Blue gear set - invalid = INT32_MAX ///< Error return code -}; - - -// Provide Aliases for Motor_Gears -using MotorGearset = MotorGears; -using MotorCart = MotorGears; -using MotorCartridge = MotorGears; -using MotorGear = MotorGears; - -/** - * \ingroup cpp-abstract-motor - */ -class AbstractMotor { - /** - * \addtogroup cpp-abstract-motor - * @{ - */ - public: - /// \name Motor movement functions - /// These functions allow programmers to make motors move - ///@{ - - /** - * Sets the voltage for the motor from -127 to 127. - * - * This is designed to map easily to the input from the controller's analog - * stick for simple opcontrol use. The actual behavior of the motor is - * analogous to use of pros::Motor::move(). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param voltage - * The new motor voltage from -127 to 127 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t operator=(std::int32_t voltage) const = 0; - - /** - * Sets the voltage for the motor from -127 to 127. - * - * This is designed to map easily to the input from the controller's analog - * stick for simple opcontrol use. The actual behavior of the motor is - * analogous to use of motor_move(), or motorSet() from the PROS 2 API. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param voltage - * The new motor voltage from -127 to 127 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t move(std::int32_t voltage) const = 0; - - /** - * Sets the target absolute position for the motor to move to. - * - * This movement is relative to the position of the motor when initialized or - * the position when it was most recently reset with - * pros::Motor::set_zero_position(). - * - * \note This function simply sets the target for the motor, it does not block - * program execution until the movement finishes. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param position - * The absolute position to move to in the motor's encoder units - * \param velocity - * The maximum allowable velocity for the movement in RPM - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t move_absolute(const double position, const std::int32_t velocity) const = 0; - - /** - * Sets the relative target position for the motor to move to. - * - * This movement is relative to the current position of the motor as given in - * pros::Motor::motor_get_position(). Providing 10.0 as the position parameter - * would result in the motor moving clockwise 10 units, no matter what the - * current position is. - * - * \note This function simply sets the target for the motor, it does not block - * program execution until the movement finishes. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param position - * The relative position to move to in the motor's encoder units - * \param velocity - * The maximum allowable velocity for the movement in RPM - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t move_relative(const double position, const std::int32_t velocity) const = 0; - - /** - * Sets the velocity for the motor. - * - * This velocity corresponds to different actual speeds depending on the - * gearset used for the motor. This results in a range of +-100 for - * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for - * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent - * speed, as opposed to setting the motor's voltage. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param velocity - * The new motor velocity from -+-100, +-200, or +-600 depending on the - * motor's gearset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t move_velocity(const std::int32_t velocity) const = 0; - - /** - * Sets the output voltage for the motor from -12000 to 12000 in millivolts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1-21 - * \param voltage - * The new voltage value from -12000 to 12000 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t move_voltage(const std::int32_t voltage) const = 0; - - /** - * Stops the motor using the currently configured brake mode. - * - * This function sets motor velocity to zero, which will cause it to act - * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, - * this function may behave differently than calling move_absolute(0) - * or motor_move_relative(0). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - */ - virtual std::int32_t brake(void) const = 0; - - /** - * Changes the output velocity for a profiled movement (motor_move_absolute or - * motor_move_relative). This will have no effect if the motor is not following - * a profiled movement. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param velocity - * The new motor velocity from +-100, +-200, or +-600 depending on the - * motor's gearset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t modify_profiled_velocity(const std::int32_t velocity) const = 0; - - /** - * Gets the target position set for the motor by the user, with a parameter - * for the motor index. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The target position in its encoder units or PROS_ERR_F if the - * operation failed, setting errno. - */ - virtual double get_target_position(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the target position(s) set for the motor(s) by the user - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * - * \return A vector containing the target position(s) in its encoder units or PROS_ERR_F if the - * operation failed, setting errno. - */ - virtual std::vector get_target_position_all(void) const = 0; - - /** - * Gets the velocity commanded to the motor by the user. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The commanded motor velocity from +-100, +-200, or +-600, or - * PROS_ERR if the operation failed, setting errno. - */ - virtual std::int32_t get_target_velocity(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the velocity/velocities commanded to the motor(s) by the user - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing the commanded motor velocity/velocities from +-100, - * +-200, or +-600, or PROS_ERR if the operation failed, setting errno. - */ - virtual std::vector get_target_velocity_all(void) const = 0; - - ///@} - - /// \name Motor telemetry functions - /// \addtogroup cpp-motor-telemetry - /// These functions allow programmers to collect telemetry from motors - ///@{ - - /** - * Gets the actual velocity of the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation - * failed, setting errno. - */ - virtual double get_actual_velocity(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the actual velocity/velocities of the motor(s) - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing the motor's/motors' actual velocity/velocities in RPM or PROS_ERR_F - * if the operation failed, setting errno. - */ - virtual std::vector get_actual_velocity_all(void) const = 0; - - /** - * Gets the current drawn by the motor in mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's current in mA or PROS_ERR if the operation failed, - * setting errno. - */ - virtual std::int32_t get_current_draw(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the current(s) drawn by the motor(s) in mA. - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * - * \return A vector conatining the motor's/motors' current(s) in mA or PROS_ERR if the operation failed, - * setting errno. - */ - virtual std::vector get_current_draw_all(void) const = 0; - - /** - * Gets the direction of movement for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 for moving in the positive direction, -1 for moving in the - * negative direction, and PROS_ERR if the operation failed, setting errno. - */ - virtual std::int32_t get_direction(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the direction(s) of movement for the motor(s). - * - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * - * \return A vector containing 1 for moving in the positive direction, -1 for moving in the - * negative direction, and PROS_ERR if the operation failed, setting errno. - */ - virtual std::vector get_direction_all(void) const = 0; - - /** - * Gets the efficiency of the motor in percent. - * - * An efficiency of 100% means that the motor is moving electrically while - * drawing no electrical power, and an efficiency of 0% means that the motor - * is drawing power but not moving. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's efficiency in percent or PROS_ERR_F if the operation - * failed, setting errno. - */ - virtual double get_efficiency(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the efficiency/efficiencies of the motor(s) in percent. - * - * An efficiency of 100% means that the motor is moving electrically while - * drawing no electrical power, and an efficiency of 0% means that the motor - * is drawing power but not moving. - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * - * \return A vector containing the motor's/motors' efficiency/efficiencies in percent or PROS_ERR_F if the operation - * failed, setting errno. - */ - virtual std::vector get_efficiency_all(void) const = 0; - - /** - * Gets the faults experienced by the motor. - * - * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A bitfield containing the motor's faults. - */ - virtual std::uint32_t get_faults(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the faults experienced by the motor(s). - * - * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * \return A bitfield containing the motor's/motors' faults. - */ - virtual std::vector get_faults_all(void) const = 0; - /** - * Gets the flags set by the motor's operation. - * - * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A bitfield containing the motor's flags. - */ - virtual std::uint32_t get_flags(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the flags set by the motor's/motors' operation. - * - * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * - * \return A bitfield containing the motor's/motors' flags. - */ - virtual std::vector get_flags_all(void) const = 0; - - /** - * Gets the absolute position of the motor in its encoder units. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's absolute position in its encoder units or PROS_ERR_F - * if the operation failed, setting errno. - */ - virtual double get_position(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the absolute position(s) of the motor(s) in its encoder units. - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - - * - * \return A vector containing the motor's/motors' absolute position(s) in its encoder units or PROS_ERR_F - * if the operation failed, setting errno. - */ - virtual std::vector get_position_all(void) const = 0; - - /** - * Gets the power drawn by the motor in Watts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's power draw in Watts or PROS_ERR_F if the operation - * failed, setting errno. - */ - virtual double get_power(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector containing the power(s) drawn by the motor(s) in Watts. - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing the motor's/motors' power draw in Watts or PROS_ERR_F if the operation - * failed, setting errno. - */ - virtual std::vector get_power_all(void) const = 0; - - /** - * Gets the raw encoder count of the motor at a given timestamp. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param[in] timestamp - * A pointer to a time in milliseconds for which the encoder count - * will be returned. If NULL, the timestamp at which the encoder - * count was read will not be supplied - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The raw encoder count at the given timestamp or PROS_ERR if the - * operation failed. - */ - virtual std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the raw encoder count(s) of the motor(s) at a given timestamp. - * - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * \param timestamp - * A pointer to a time in milliseconds for which the encoder count - * will be returned. If NULL, the timestamp at which the encoder - * count was read will not be supplied - * - * \return A vector containing the raw encoder count(s) at the given timestamp or PROS_ERR if the - * operation failed. - */ - virtual std::vector get_raw_position_all(std::uint32_t* const timestamp) const = 0; - - /** - * Gets the temperature of the motor in degrees Celsius. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the - * operation failed, setting errno. - */ - virtual double get_temperature(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the temperature(s) of the motor(s) in degrees Celsius. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector containing the motor's/motors' temperature(s) in degrees Celsius or PROS_ERR_F if the - * operation failed, setting errno. - */ - virtual std::vector get_temperature_all(void) const = 0; - /** - * Gets the torque generated by the motor in Newton Meters (Nm). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, - * setting errno. - */ - virtual double get_torque(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the torque(s) generated by the motor(s) in Newton Meters (Nm). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector containing the motor's/motors' torque(s) in Nm or PROS_ERR_F if the operation failed, - * setting errno. - */ - virtual std::vector get_torque_all(void) const = 0; - /** - * Gets the voltage delivered to the motor in millivolts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, - * setting errno. - */ - virtual std::int32_t get_voltage(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the voltage(s) delivered to the motor(s) in millivolts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector containing the motor's/motors' voltage(s) in mV or PROS_ERR_F if the operation failed, - * setting errno. - */ - virtual std::vector get_voltage_all(void) const = 0; - - /** - * Checks if the motor is drawing over its current limit. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the motor's current limit is being exceeded and 0 if the - * current limit is not exceeded, or PROS_ERR if the operation failed, setting - * errno. - */ - virtual std::int32_t is_over_current(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of whether each motor is drawing over its current limit. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the motor's current limit is being exceeded and 0 if the - * current limit is not exceeded, or PROS_ERR if the operation failed, setting - * errno. - */ - virtual std::vector is_over_current_all(void) const = 0; - - /** - * Gets the temperature limit flag for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the temperature limit is exceeded and 0 if the temperature is - * below the limit, or PROS_ERR if the operation failed, setting errno. - */ - virtual std::int32_t is_over_temp(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the temperature limit flag(s) for the motor(s). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the temperature limit is exceeded and 0 if the temperature is - * below the limit, or PROS_ERR if the operation failed, setting errno. - */ - virtual std::vector is_over_temp_all(void) const = 0; - - ///@} - - /// \name Motor configuration functions - /// \addtogroup cpp-motor-configuration - /// These functions allow programmers to configure the behavior of motors - ///@{ - - /** - * Gets the brake mode that was set for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return One of Motor_Brake, according to what was set for the - * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. - */ - virtual MotorBrake get_brake_mode(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the brake mode(s) that was set for the motor(s). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector containing Motor_Brake(s), according to what was set for the - * motor(s), or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. - */ - virtual std::vector get_brake_mode_all(void) const = 0; - - /** - * Gets the current limit for the motor in mA. - * - * The default value is 2500 mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's current limit in mA or PROS_ERR if the operation failed, - * setting errno. - */ - virtual std::int32_t get_current_limit(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the current limit(s) for the motor(s) in mA. - * - * The default value is 2500 mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector containing the motor's/motors' current limit(s) in mA or PROS_ERR if the operation failed, - * setting errno. - */ - virtual std::vector get_current_limit_all(void) const = 0; - - /** - * Gets the encoder units that were set for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return One of Motor_Units according to what is set for the - * motor or E_MOTOR_ENCODER_INVALID if the operation failed. - */ - virtual MotorUnits get_encoder_units(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the encoder units that were set for the motor(s). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector of Motor_Units according to what is set for the - * motor(s) or E_MOTOR_ENCODER_INVALID if the operation failed. - */ - virtual std::vector get_encoder_units_all(void) const = 0; - - /** - * Gets the gearset that was set for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return One of Motor_Gears according to what is set for the motor, - * or pros::Motor_Gears::invalid if the operation failed. - */ - virtual MotorGears get_gearing(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the gearset(s) that was/were set for the motor(s). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector of Motor_Gears according to what is set for the motor(s), - * or pros::Motor_Gears::invalid if the operation failed. - */ - virtual std::vector get_gearing_all(void) const = 0; - - /** - * @brief Gets returns a vector with all the port numbers in the motor group. - * - * @return std::vector - */ - virtual std::vector get_port_all(void) const = 0; - - /** - * Gets the voltage limit set by the user. - * - * Default value is 0V, which means that there is no software limitation - * imposed on the voltage. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return The motor's voltage limit in V or PROS_ERR if the operation failed, - * setting errno. - */ - virtual std::int32_t get_voltage_limit(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the voltage limit(s) set by the user. - * - * Default value is 0V, which means that there is no software limitation - * imposed on the voltage. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return A vector containing the motor's/motors' voltage limit(s) in V or PROS_ERR if the operation failed, - * setting errno. - */ - virtual std::vector get_voltage_limit_all(void) const = 0; - - /** - * Gets the operation direction of the motor as set by the user. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the motor has been reversed and 0 if the motor was not - * reversed, or PROS_ERR if the operation failed, setting errno. - */ - virtual std::int32_t is_reversed(const std::uint8_t index = 0) const = 0; - - /** - * Gets a vector of the operation direction(s) of the motor(s) as set by the user. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the motor has been reversed and 0 if the motor was not - * reversed, or PROS_ERR if the operation failed, setting errno. - */ - virtual std::vector is_reversed_all(void) const = 0; - - /** - * Sets one of Motor_Brake to the motor. Works with the C enum - * and the C++ enum class. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param mode - * The Motor_Brake to set for the motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_brake_mode_all(const MotorBrake mode) const = 0; - virtual std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const = 0; - /** - * Sets the current limit for the motor in mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param limit - * The new current limit in mA - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_current_limit_all(const std::int32_t limit) const = 0; - /** - * Sets one of Motor_Units for the motor encoder. Works with the C - * enum and the C++ enum class. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param units - * The new motor encoder units - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_encoder_units_all(const MotorUnits units) const = 0; - virtual std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const = 0; - /** - * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with - * the C++ enum class and the C enum. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param gearset - * The new motor gearset - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_gearing_all(const MotorGears gearset) const = 0; - virtual std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const = 0; - - /** - * Sets the reverse flag for the motor. - * - * This will invert its movements and the values returned for its position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param reverse - * True reverses the motor, false is default - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0) = 0; - virtual std::int32_t set_reversed_all(const bool reverse) = 0; - - /** - * Sets the voltage limit for the motor in Volts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param limit - * The new voltage limit in Volts - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_voltage_limit_all(const std::int32_t limit) const = 0; - - /** - * Sets the position for the motor in its encoder units. - * - * This will be the future reference point for the motor's "absolute" - * position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param position - * The new reference position in its encoder units - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const = 0; - virtual std::int32_t set_zero_position_all(const double position) const = 0; - - /** - * Sets the "absolute" zero position of the motor to its current position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param index Optional parameter. - * The index of the motor to get the target position of. - * By default index is 0, and will return an error for an out of bounds index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ - virtual std::int32_t tare_position(const std::uint8_t index = 0) const = 0; - virtual std::int32_t tare_position_all(void) const = 0; - virtual std::int8_t get_port(const std::uint8_t index = 0) const = 0; - /** - * @brief Returns the number of objects - * - * @return std::int8_t - */ - virtual std::int8_t size(void) const = 0; - - ///@} - private: -}; - -} // namespace v5 -} // namespace pros - -///@} - -#endif +/** + * \file abstract_motor.hpp + * \ingroup cpp-abstract-motor + * + * Contains prototypes for AbstractMotor, the abstract base class of both + * motors and motor groups. Abstract motors cannot be directly constructed, but + * you can use motors and motor groups as abstract motors. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_ABSTRACT_MOTORS_HPP_ +#define _PROS_ABSTRACT_MOTORS_HPP_ + +#include +#include + +#include "pros/device.hpp" +#include "pros/motors.h" +#include "rtos.hpp" + +namespace pros { +inline namespace v5 { + +/** + * \enum motor_brake + * Indicates the current 'brake mode' of a motor. + */ +enum class MotorBrake { + coast = 0, ///< Motor coasts when stopped, traditional behavior + brake = 1, ///< Motor brakes when stopped + hold = 2, ///< Motor actively holds position when stopped + invalid = INT32_MAX ///< Invalid brake mode +}; + +/** + * \enum Motor_Encoder_Units + * Indicates the units used by the motor encoders. + */ +enum class MotorEncoderUnits { + degrees = 0, ///< Position is recorded as angle in degrees as a floating point number + deg = 0, ///< Position is recorded as angle in degrees as a floating point number + rotations = 1, ///< Position is recorded as angle in rotations as a floating point number + counts = 2, ///< Position is recorded as raw encoder ticks as a whole number + invalid = INT32_MAX ///< Invalid motor encoder units +}; + +// Alias for Motor_Encoder_Units +using MotorUnits = MotorEncoderUnits; + +enum class MotorGears { + ratio_36_to_1 = 0, ///< 36:1, 100 RPM, Red gear set + red = ratio_36_to_1, ///< 36:1, 100 RPM, Red gear set + rpm_100 = ratio_36_to_1, ///< 36:1, 100 RPM, Red gear set + ratio_18_to_1 = 1, ///< 18:1, 200 RPM, Green gear set + green = ratio_18_to_1, ///< 18:1, 200 RPM, Green gear set + rpm_200 = ratio_18_to_1, ///< 18:1, 200 RPM, Green gear set + ratio_6_to_1 = 2, ///< 6:1, 600 RPM, Blue gear set + blue = ratio_6_to_1, ///< 6:1, 600 RPM, Blue gear set + rpm_600 = ratio_6_to_1, ///< 6:1, 600 RPM, Blue gear set + invalid = INT32_MAX ///< Error return code +}; + + +// Provide Aliases for Motor_Gears +using MotorGearset = MotorGears; +using MotorCart = MotorGears; +using MotorCartridge = MotorGears; +using MotorGear = MotorGears; + +/** + * \ingroup cpp-abstract-motor + */ +class AbstractMotor { + /** + * \addtogroup cpp-abstract-motor + * @{ + */ + public: + /// \name Motor movement functions + /// These functions allow programmers to make motors move + ///@{ + + /** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of pros::Motor::move(). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t operator=(std::int32_t voltage) const = 0; + + /** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of motor_move(), or motorSet() from the PROS 2 API. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move(std::int32_t voltage) const = 0; + + /** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with + * pros::Motor::set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_absolute(const double position, const std::int32_t velocity) const = 0; + + /** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * pros::Motor::motor_get_position(). Providing 10.0 as the position parameter + * would result in the motor moving clockwise 10 units, no matter what the + * current position is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_relative(const double position, const std::int32_t velocity) const = 0; + + /** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the + * gearset used for the motor. This results in a range of +-100 for + * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for + * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent + * speed, as opposed to setting the motor's voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from -+-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_velocity(const std::int32_t velocity) const = 0; + + /** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t move_voltage(const std::int32_t voltage) const = 0; + + /** + * Stops the motor using the currently configured brake mode. + * + * This function sets motor velocity to zero, which will cause it to act + * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, + * this function may behave differently than calling move_absolute(0) + * or motor_move_relative(0). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + */ + virtual std::int32_t brake(void) const = 0; + + /** + * Changes the output velocity for a profiled movement (motor_move_absolute or + * motor_move_relative). This will have no effect if the motor is not following + * a profiled movement. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t modify_profiled_velocity(const std::int32_t velocity) const = 0; + + /** + * Gets the target position set for the motor by the user, with a parameter + * for the motor index. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual double get_target_position(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the target position(s) set for the motor(s) by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the target position(s) in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual std::vector get_target_position_all(void) const = 0; + + /** + * Gets the velocity commanded to the motor by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t get_target_velocity(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the velocity/velocities commanded to the motor(s) by the user + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the commanded motor velocity/velocities from +-100, + * +-200, or +-600, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector get_target_velocity_all(void) const = 0; + + ///@} + + /// \name Motor telemetry functions + /// \addtogroup cpp-motor-telemetry + /// These functions allow programmers to collect telemetry from motors + ///@{ + + /** + * Gets the actual velocity of the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual double get_actual_velocity(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the actual velocity/velocities of the motor(s) + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's/motors' actual velocity/velocities in RPM or PROS_ERR_F + * if the operation failed, setting errno. + */ + virtual std::vector get_actual_velocity_all(void) const = 0; + + /** + * Gets the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::int32_t get_current_draw(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the current(s) drawn by the motor(s) in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector conatining the motor's/motors' current(s) in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::vector get_current_draw_all(void) const = 0; + + /** + * Gets the direction of movement for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t get_direction(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the direction(s) of movement for the motor(s). + * + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector get_direction_all(void) const = 0; + + /** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual double get_efficiency(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the efficiency/efficiencies of the motor(s) in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the motor's/motors' efficiency/efficiencies in percent or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual std::vector get_efficiency_all(void) const = 0; + + /** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A bitfield containing the motor's faults. + */ + virtual std::uint32_t get_faults(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the faults experienced by the motor(s). + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A bitfield containing the motor's/motors' faults. + */ + virtual std::vector get_faults_all(void) const = 0; + /** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A bitfield containing the motor's flags. + */ + virtual std::uint32_t get_flags(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the flags set by the motor's/motors' operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A bitfield containing the motor's/motors' flags. + */ + virtual std::vector get_flags_all(void) const = 0; + + /** + * Gets the absolute position of the motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + */ + virtual double get_position(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the absolute position(s) of the motor(s) in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + + * + * \return A vector containing the motor's/motors' absolute position(s) in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + */ + virtual std::vector get_position_all(void) const = 0; + + /** + * Gets the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual double get_power(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector containing the power(s) drawn by the motor(s) in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's/motors' power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + */ + virtual std::vector get_power_all(void) const = 0; + + /** + * Gets the raw encoder count of the motor at a given timestamp. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param[in] timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + */ + virtual std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the raw encoder count(s) of the motor(s) at a given timestamp. + * + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return A vector containing the raw encoder count(s) at the given timestamp or PROS_ERR if the + * operation failed. + */ + virtual std::vector get_raw_position_all(std::uint32_t* const timestamp) const = 0; + + /** + * Gets the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual double get_temperature(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the temperature(s) of the motor(s) in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' temperature(s) in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual std::vector get_temperature_all(void) const = 0; + /** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual double get_torque(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the torque(s) generated by the motor(s) in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' torque(s) in Nm or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual std::vector get_torque_all(void) const = 0; + /** + * Gets the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual std::int32_t get_voltage(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the voltage(s) delivered to the motor(s) in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' voltage(s) in mV or PROS_ERR_F if the operation failed, + * setting errno. + */ + virtual std::vector get_voltage_all(void) const = 0; + + /** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + */ + virtual std::int32_t is_over_current(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of whether each motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + */ + virtual std::vector is_over_current_all(void) const = 0; + + /** + * Gets the temperature limit flag for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t is_over_temp(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the temperature limit flag(s) for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector is_over_temp_all(void) const = 0; + + ///@} + + /// \name Motor configuration functions + /// \addtogroup cpp-motor-configuration + /// These functions allow programmers to configure the behavior of motors + ///@{ + + /** + * Gets the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of Motor_Brake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + */ + virtual MotorBrake get_brake_mode(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the brake mode(s) that was set for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing Motor_Brake(s), according to what was set for the + * motor(s), or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + */ + virtual std::vector get_brake_mode_all(void) const = 0; + + /** + * Gets the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::int32_t get_current_limit(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the current limit(s) for the motor(s) in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' current limit(s) in mA or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::vector get_current_limit_all(void) const = 0; + + /** + * Gets the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of Motor_Units according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + */ + virtual MotorUnits get_encoder_units(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the encoder units that were set for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector of Motor_Units according to what is set for the + * motor(s) or E_MOTOR_ENCODER_INVALID if the operation failed. + */ + virtual std::vector get_encoder_units_all(void) const = 0; + + /** + * Gets the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return One of Motor_Gears according to what is set for the motor, + * or pros::Motor_Gears::invalid if the operation failed. + */ + virtual MotorGears get_gearing(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the gearset(s) that was/were set for the motor(s). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector of Motor_Gears according to what is set for the motor(s), + * or pros::Motor_Gears::invalid if the operation failed. + */ + virtual std::vector get_gearing_all(void) const = 0; + + /** + * @brief Gets returns a vector with all the port numbers in the motor group. + * + * @return std::vector + */ + virtual std::vector get_port_all(void) const = 0; + + /** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::int32_t get_voltage_limit(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the voltage limit(s) set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return A vector containing the motor's/motors' voltage limit(s) in V or PROS_ERR if the operation failed, + * setting errno. + */ + virtual std::vector get_voltage_limit_all(void) const = 0; + + /** + * Gets the operation direction of the motor as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::int32_t is_reversed(const std::uint8_t index = 0) const = 0; + + /** + * Gets a vector of the operation direction(s) of the motor(s) as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + */ + virtual std::vector is_reversed_all(void) const = 0; + + /** + * Sets one of Motor_Brake to the motor. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param mode + * The Motor_Brake to set for the motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_brake_mode_all(const MotorBrake mode) const = 0; + virtual std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const = 0; + /** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new current limit in mA + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_current_limit_all(const std::int32_t limit) const = 0; + /** + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param units + * The new motor encoder units + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_encoder_units_all(const MotorUnits units) const = 0; + virtual std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const = 0; + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_gearing_all(const MotorGears gearset) const = 0; + virtual std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const = 0; + + /** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param reverse + * True reverses the motor, false is default + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0) = 0; + virtual std::int32_t set_reversed_all(const bool reverse) = 0; + + /** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new voltage limit in Volts + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_voltage_limit_all(const std::int32_t limit) const = 0; + + /** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The new reference position in its encoder units + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_zero_position_all(const double position) const = 0; + + /** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index Optional parameter. + * The index of the motor to get the target position of. + * By default index is 0, and will return an error for an out of bounds index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + */ + virtual std::int32_t tare_position(const std::uint8_t index = 0) const = 0; + virtual std::int32_t tare_position_all(void) const = 0; + virtual std::int8_t get_port(const std::uint8_t index = 0) const = 0; + /** + * @brief Returns the number of objects + * + * @return std::int8_t + */ + virtual std::int8_t size(void) const = 0; + + ///@} + private: +}; + +} // namespace v5 +} // namespace pros + +///@} + +#endif diff --git a/include/pros/adi.h b/include/pros/adi.h index 288fd02..f1bbe37 100644 --- a/include/pros/adi.h +++ b/include/pros/adi.h @@ -1,1383 +1,1383 @@ -/** - * \file pros/adi.h - * \ingroup c-adi - * - * Contains prototypes for interfacing with the ADI. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-adi ADI (TriPort) C API - * \note The external ADI API can be found [here.](@ref ext-adi) - * \note Additional example code for this module can be found in its [Tutorial.](@ref adi) - */ - -#ifndef _PROS_ADI_H_ -#define _PROS_ADI_H_ - -#include -#include -#ifndef PROS_ERR -#define PROS_ERR (INT32_MAX) -#endif - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/** - * \ingroup c-adi - */ - -/** - * \addtogroup c-adi - * @{ - */ - -/** - * \enum adi_port_config_e - * Represents the port type for an ADI port. - */ -typedef enum adi_port_config_e { - E_ADI_ANALOG_IN = 0, - E_ADI_ANALOG_OUT = 1, - E_ADI_DIGITAL_IN = 2, - E_ADI_DIGITAL_OUT = 3, - -#ifdef _INTELLISENSE -#define _DEPRECATE_DIGITAL_IN = E_ADI_DIGITAL_IN -#define _DEPRECATE_ANALOG_IN = E_ADI_ANALOG_IN -#else -#define _DEPRECATE_DIGITAL_IN __attribute__((deprecated("use E_ADI_DIGITAL_IN instead"))) = E_ADI_DIGITAL_IN -#define _DEPRECATE_ANALOG_IN __attribute__((deprecated("use E_ADI_ANALOG_IN instead"))) = E_ADI_ANALOG_IN -#endif - - E_ADI_SMART_BUTTON _DEPRECATE_DIGITAL_IN, - E_ADI_SMART_POT _DEPRECATE_ANALOG_IN, - - E_ADI_LEGACY_BUTTON _DEPRECATE_DIGITAL_IN, - E_ADI_LEGACY_POT _DEPRECATE_ANALOG_IN, - E_ADI_LEGACY_LINE_SENSOR _DEPRECATE_ANALOG_IN, - E_ADI_LEGACY_LIGHT_SENSOR _DEPRECATE_ANALOG_IN, - E_ADI_LEGACY_GYRO = 10, - E_ADI_LEGACY_ACCELEROMETER _DEPRECATE_ANALOG_IN, - -#undef _DEPRECATE_DIGITAL_IN -#undef _DEPRECATE_ANALOG_IN - - E_ADI_LEGACY_SERVO = 12, - E_ADI_LEGACY_PWM = 13, - - E_ADI_LEGACY_ENCODER = 14, - E_ADI_LEGACY_ULTRASONIC = 15, - - E_ADI_TYPE_UNDEFINED = 255, - E_ADI_ERR = PROS_ERR -} adi_port_config_e_t; - -/** - * \enum adi_potentiometer_type_e_t - * Represents the potentiometer version type. - */ -typedef enum adi_potentiometer_type_e { - E_ADI_POT_EDR = 0, - E_ADI_POT_V2 -} adi_potentiometer_type_e_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define ADI_ANALOG_IN pros::E_ADI_ANALOG_IN -#define ADI_ANALOG_OUT pros::E_ADI_ANALOG_OUT -#define ADI_DIGITAL_IN pros::E_ADI_DIGITAL_IN -#define ADI_DIGITAL_OUT pros::E_ADI_DIGITAL_OUT -#define ADI_SMART_BUTTON pros::E_ADI_SMART_BUTTON -#define ADI_SMART_POT pros::E_ADI_SMART_POT -#define ADI_LEGACY_BUTTON pros::E_ADI_LEGACY_BUTTON -#define ADI_LEGACY_POT pros::E_ADI_LEGACY_POT -#define ADI_LEGACY_LINE_SENSOR pros::E_ADI_LEGACY_LINE_SENSOR -#define ADI_LEGACY_LIGHT_SENSOR pros::E_ADI_LEGACY_LIGHT_SENSOR -#define ADI_LEGACY_GYRO pros::E_ADI_LEGACY_GYRO -#define ADI_LEGACY_ACCELEROMETER pros::E_ADI_LEGACY_ACCELEROMETER -#define ADI_LEGACY_SERVO pros::E_ADI_LEGACY_SERVO -#define ADI_LEGACY_PWM pros::E_ADI_LEGACY_PWM -#define ADI_LEGACY_ENCODER pros::E_ADI_LEGACY_ENCODER -#define ADI_LEGACY_ULTRASONIC pros::E_ADI_LEGACY_ULTRASONIC -#define ADI_TYPE_UNDEFINED pros::E_ADI_TYPE_UNDEFINED -#define ADI_ERR pros::E_ADI_ERR -#else -#define ADI_ANALOG_IN E_ADI_ANALOG_IN -#define ADI_ANALOG_OUT E_ADI_ANALOG_OUT -#define ADI_DIGITAL_IN E_ADI_DIGITAL_IN -#define ADI_DIGITAL_OUT E_ADI_DIGITAL_OUT -#define ADI_SMART_BUTTON E_ADI_SMART_BUTTON -#define ADI_SMART_POT E_ADI_SMART_POT -#define ADI_LEGACY_BUTTON E_ADI_LEGACY_BUTTON -#define ADI_LEGACY_POT E_ADI_LEGACY_POT -#define ADI_LEGACY_LINE_SENSOR E_ADI_LEGACY_LINE_SENSOR -#define ADI_LEGACY_LIGHT_SENSOR E_ADI_LEGACY_LIGHT_SENSOR -#define ADI_LEGACY_GYRO E_ADI_LEGACY_GYRO -#define ADI_LEGACY_ACCELEROMETER E_ADI_LEGACY_ACCELEROMETER -#define ADI_LEGACY_SERVO E_ADI_LEGACY_SERVO -#define ADI_LEGACY_PWM E_ADI_LEGACY_PWM -#define ADI_LEGACY_ENCODER E_ADI_LEGACY_ENCODER -#define ADI_LEGACY_ULTRASONIC E_ADI_LEGACY_ULTRASONIC -#define ADI_TYPE_UNDEFINED E_ADI_TYPE_UNDEFINED -#define ADI_ERR E_ADI_ERR -#endif -#endif - -#define INTERNAL_ADI_PORT 22 -#define NUM_ADI_PORTS 8 - -#ifdef __cplusplus -namespace c { -#endif - -/** @} Add to group c-adi*/ - -/** - * \ingroup c-adi - */ - -/** - * \addtogroup c-adi - * @{ - */ - -/** - * Gets the configuration for the given ADI port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports. - * - * \param port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return - * the configuration - * - * \return The ADI configuration for the given port - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void initialize() { - * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); - * // Displays the value of E_ADI_ANALOG_IN - * printf("Port Type: %d\n", adi_port_get_config(ANALOG_SENSOR_PORT)); - * } - * \endcode - */ -adi_port_config_e_t adi_port_get_config(uint8_t port); - -/** - * Gets the value for the given ADI port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports. - * - * \param port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value - * will be returned - * - * \return The value stored for the given port - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); - * printf("Port Value: %d\n", adi_get_value(ANALOG_SENSOR_PORT)); - * } - * \endcode - */ -int32_t adi_port_get_value(uint8_t port); - -/** - * Configures an ADI port to act as a given sensor type. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports. - * - * \param port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure - * \param type - * The configuration type for the port - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void initialize() { - * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); - * } - * \endcode - */ -int32_t adi_port_set_config(uint8_t port, adi_port_config_e_t type); - -/** - * Sets the value for the given ADI port. - * - * This only works on ports configured as outputs, and the behavior will change - * depending on the configuration of the port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports. - * - * \param port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value - * will be set - * \param value - * The value to set the ADI port to - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define DIGITAL_SENSOR_PORT 1 - * - * void initialize() { - * adi_port_set_config(DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); - * adi_set_value(DIGITAL_SENSOR_PORT, HIGH); - * } - * \endcode - */ -int32_t adi_port_set_value(uint8_t port, int32_t value); - -/** - * Calibrates the analog sensor on the specified port and returns the new - * calibration value. - * - * This method assumes that the true sensor value is not actively changing at - * this time and computes an average from approximately 500 samples, 1 ms apart, - * for a 0.5 s period of calibration. The average value thus calculated is - * returned and stored for later calls to the adi_analog_read_calibrated() and - * adi_analog_read_calibrated_HR() functions. These functions will return - * the difference between this value and the current sensor value when called. - * - * Do not use this function when the sensor value might be unstable - * (gyro rotation, accelerometer movement). - * - * \note The ADI currently returns data at 10ms intervals, in constrast to the - * calibrate function’s 1ms sample rate. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * - * \param port - * The ADI port to calibrate (from 1-8, 'a'-'h', 'A'-'H') - * - * \return The average sensor value computed by this function - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void initialize() { - * adi_analog_calibrate(ANALOG_SENSOR_PORT); - * printf("Calibrated Reading: %d\n", adi_analog_read_calibrated(ANALOG_SENSOR_PORT)); - * // All readings from then on will be calibrated - * } - * \endcode - */ -int32_t adi_analog_calibrate(uint8_t port); - -/** - * Gets the 12-bit value of the specified port. - * - * The value returned is undefined if the analog pin has been switched to a - * different mode. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an analog input - * - * \param port - * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be - * returned - * - * \return The analog sensor value, where a value of 0 reflects an input voltage - * of nearly 0 V and a value of 4095 reflects an input voltage of nearly 5 V - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Sensor Reading: %d\n", adi_analog_read(ANALOG_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_analog_read(uint8_t port); - -/** - * Gets the 12 bit calibrated value of an analog input port. - * - * The adi_analog_calibrate() function must be run first. This function is - * inappropriate for sensor values intended for integration, as round-off error - * can accumulate causing drift over time. Use adi_analog_read_calibrated_HR() - * instead. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an analog input - * - * \param port - * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be - * returned - * - * \return The difference of the sensor value from its calibrated default from - * -4095 to 4095 - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Sensor Reading: %d\n", adi_analog_read_calibrated(ANALOG_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_analog_read_calibrated(uint8_t port); - -/** - * Gets the 16 bit calibrated value of an analog input port. - * - * The adi_analog_calibrate() function must be run first. This is intended for - * integrated sensor values such as gyros and accelerometers to reduce drift due - * to round-off, and should not be used on a sensor such as a line tracker - * or potentiometer. - * - * The value returned actually has 16 bits of "precision", even though the ADC - * only reads 12 bits, so that error induced by the average value being between - * two values when integrated over time is trivial. Think of the value as the - * true value times 16. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an analog input - * - * \param port - * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be - * returned - * - * \return The difference of the sensor value from its calibrated default from - * -16384 to 16384 - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * adi_analog_calibrate(ANALOG_SENSOR_PORT); - * printf("Sensor Reading: %d\n", adi_analog_read_calibrated_HR(ANALOG_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_analog_read_calibrated_HR(uint8_t port); - -/** - * Gets the digital value (1 or 0) of a port configured as a digital input. - * - * If the port is configured as some other mode, the digital value which - * reflects the current state of the port is returned, which may or may not - * differ from the currently set value. The return value is undefined for ports - * configured as any mode other than a Digital Input. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a digital input - * - * \param port - * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') - * - * \return True if the pin is HIGH, or false if it is LOW - * - * \b Example - * \code - * #define DIGITAL_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Sensor Value: %d\n", adi_digital_read(DIGITAL_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_digital_read(uint8_t port); - -/** - * Gets a rising-edge case for a digital button press. - * - * This function is not thread-safe. - * Multiple tasks polling a single button may return different results under the - * same circumstances, so only one task should call this function for any given - * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call - * this function for button 3, but should not for buttons 1 or 2. A typical - * use-case for this function is to call inside opcontrol to detect new button - * presses, and not in any other tasks. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a digital input - * - * \param port - * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') - * - * \return 1 if the button is pressed and had not been pressed - * the last time this function was called, 0 otherwise. - * - * \b Example - * \code - * #define DIGITAL_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * if (adi_digital_get_new_press(DIGITAL_SENSOR_PORT)) { - * // Toggle pneumatics or other state operations - * } - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_digital_get_new_press(uint8_t port); - -/** - * Sets the digital value (1 or 0) of a port configured as a digital output. - * - * If the port is configured as some other mode, behavior is undefined. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a digital output - * - * \param port - * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') - * \param value - * An expression evaluating to "true" or "false" to set the output to - * HIGH or LOW respectively, or the constants HIGH or LOW themselves - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define DIGITAL_SENSOR_PORT - * - * void opcontrol() { - * bool state = LOW; - * while (true) { - * state != state; - * adi_digital_write(DIGITAL_SENSOR_PORT, state); - * delay(5); // toggle the sensor value every 50ms - * } - * } - * \endcode - */ -int32_t adi_digital_write(uint8_t port, bool value); - -/** - * Configures the port as an input or output with a variety of settings. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * - * \param port - * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') - * \param mode - * One of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ANALOG_SENSOR_PORT 1 - * - * void initialize() { - * adi_pin_mode(ANALOG_SENSOR_PORT, INPUT_ANALOG); - * } - * \endcode - */ -int32_t adi_pin_mode(uint8_t port, uint8_t mode); - -/** - * Sets the speed of the motor on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an motor - * - * \param port - * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') - * \param speed - * The new signed speed; -127 is full reverse and 127 is full forward, - * with 0 being off - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define MOTOR_PORT 1 - * - * void opcontrol() { - * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward - * delay(1000); - * adi_motor_set(MOTOR_PORT, 0); // Stop the motor - * } - * \endcode - */ -int32_t adi_motor_set(uint8_t port, int8_t speed); - -/** - * Gets the last set speed of the motor on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an motor - * - * \param port - * The ADI port to get (from 1-8, 'a'-'h', 'A'-'H') - * - * \return The last set speed of the motor on the given port - * - * \b Example - * \code - * #define MOTOR_PORT 1 - * - * void opcontrol() { - * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward - * printf("Commanded Motor Power: %d\n", adi_motor_get(MOTOR_PORT)); // Will display 127 - * delay(1000); - * adi_motor_set(MOTOR_PORT, 0); // Stop the motor - * } - * \endcode - */ -int32_t adi_motor_get(uint8_t port); - -/** - * Stops the motor on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an motor - * - * \param port - * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define MOTOR_PORT 1 - * - * void opcontrol() { - * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward - * delay(1000); - * // adi_motor_set(MOTOR_PORT, 0); // Stop the motor - * adi_motor_stop(MOTOR_PORT); // use this instead - * } - * \endcode - */ -int32_t adi_motor_stop(uint8_t port); - -/** - * Reference type for an initialized encoder. - * - * This merely contains the port number for the encoder. - */ -typedef int32_t adi_encoder_t; - -/** - * Gets the number of ticks recorded by the encoder. - * - * There are 360 ticks in one revolution. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an encoder - * - * \param enc - * The adi_encoder_t object from adi_encoder_init() to read - * - * \return The signed and cumulative number of counts since the last start or - * reset - * - * \b Example - * \code - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); - * while (true) { - * printf("Encoder Value: %d\n", adi_encoder_get(enc)); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_encoder_get(adi_encoder_t enc); - -/** - * Creates an encoder object and configures the specified ports accordingly. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an encoder - - * - * \param port_top - * The "top" wire from the encoder sensor with the removable cover side - * up. This should be in port 1, 3, 5, or 7 ('A', 'C', 'E', or 'G'). - * \param port_bottom - * The "bottom" wire from the encoder sensor - * \param reverse - * If "true", the sensor will count in the opposite direction - * - * \return An adi_encoder_t object to be stored and used for later calls to - * encoder functions - * - * \b Example - * \code - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); - * while (true) { - * printf("Encoder Value: %d\n", adi_encoder_get(enc)); - * delay(5); - * } - * } - * \endcode - */ -adi_encoder_t adi_encoder_init(uint8_t port_top, uint8_t port_bottom, bool reverse); - -/** - * Sets the encoder value to zero. - * - * It is safe to use this method while an encoder is enabled. It is not - * necessary to call this method before stopping or starting an encoder. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an encoder - - * - * \param enc - * The adi_encoder_t object from adi_encoder_init() to reset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); - * delay(1000); // Move the encoder around in this time - * adi_encoder_reset(enc); // The encoder is now zero again - * } - * \endcode - */ -int32_t adi_encoder_reset(adi_encoder_t enc); - -/** - * Disables the encoder and voids the configuration on its ports. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an encoder - * - * \param enc - * The adi_encoder_t object from adi_encoder_init() to stop - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); - * // Use the encoder - * adi_encoder_shutdown(enc); - * } - * \endcode - */ -int32_t adi_encoder_shutdown(adi_encoder_t enc); - -/** - * Reference type for an initialized ultrasonic. - * - * This merely contains the port number for the ultrasonic. - */ -typedef int32_t adi_ultrasonic_t; - -/** - * Gets the current ultrasonic sensor value in centimeters. - * - * If no object was found, zero is returned. If the ultrasonic sensor was never - * started, the return value is undefined. Round and fluffy objects can cause - * inaccurate values to be returned. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an ultrasonic - * - * \param ult - * The adi_ultrasonic_t object from adi_ultrasonic_init() to read - * - * \return The distance to the nearest object in m^-4 (10000 indicates 1 meter), - * measured from the sensor's mounting points. - * - * \b Example - * \code - * #define PORT_PING 1 - * #define PORT_ECHO 2 - * - * void opcontrol() { - * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); - * while (true) { - * // Print the distance read by the ultrasonic - * printf("Distance: %d\n", adi_ultrasonic_get(ult)); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_ultrasonic_get(adi_ultrasonic_t ult); - -/** - * Creates an ultrasonic object and configures the specified ports accordingly. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an ultrasonic - * - * \param port_ping - * The port connected to the orange OUTPUT cable. This should be in port - * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). - * \param port_echo - * The port connected to the yellow INPUT cable. This should be in the - * next highest port following port_ping. - * - * \return An adi_ultrasonic_t object to be stored and used for later calls to - * ultrasonic functions - * - * \b Example - * \code - * #define PORT_PING 1 - * #define PORT_ECHO 2 - * - * void opcontrol() { - * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); - * while (true) { - * // Print the distance read by the ultrasonic - * printf("Distance: %d\n", adi_ultrasonic_get(ult)); - * delay(5); - * } - * } - * \endcode - */ -adi_ultrasonic_t adi_ultrasonic_init(uint8_t port_ping, uint8_t port_echo); - -/** - * Disables the ultrasonic sensor and voids the configuration on its ports. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as an ultrasonic - * - * \param ult - * The adi_ultrasonic_t object from adi_ultrasonic_init() to stop - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define PORT_PING 1 - * #define PORT_ECHO 2 - * - * void opcontrol() { - * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); - * while (true) { - * // Print the distance read by the ultrasonic - * printf("Distance: %d\n", adi_ultrasonic_get(ult)); - * delay(5); - * } - * adi_ultrasonic_shutdown(ult); - * } - * \endcode - */ -int32_t adi_ultrasonic_shutdown(adi_ultrasonic_t ult); - -/** - * Reference type for an initialized gyroscope. - * - * This merely contains the port number for the gyroscope. - */ -typedef int32_t adi_gyro_t; - -/** - * Gets the current gyro angle in tenths of a degree. Unless a multiplier is - * applied to the gyro, the return value will be a whole number representing - * the number of degrees of rotation times 10. - * - * There are 360 degrees in a circle, thus the gyro will return 3600 for one - * whole rotation. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a gyro - * - * \param gyro - * The adi_gyro_t object for which the angle will be returned - * - * \return The gyro angle in degrees. - * - * \b Example - * \code - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * - * void opcontrol() { - * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", adi_gyro_get(gyro)); - * delay(5); - * } - * } - * \endcode - */ -double adi_gyro_get(adi_gyro_t gyro); - -/** - * Initializes a gyroscope on the given port. If the given port has not - * previously been configured as a gyro, then this function starts a 1300 ms - * calibration period. - * - * It is highly recommended that this function be called from initialize() when - * the robot is stationary to ensure proper calibration. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a gyro - * - * \param port - * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') - * \param multiplier - * A scalar value that will be multiplied by the gyro heading value - * supplied by the ADI - * - * \return An adi_gyro_t object containing the given port, or PROS_ERR if the - * initialization failed. - * - * \b Example - * \code - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * - * void opcontrol() { - * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", adi_gyro_get(gyro)); - * delay(5); - * } - * } - * \endcode - */ -adi_gyro_t adi_gyro_init(uint8_t port, double multiplier); - -/** - * Resets the gyroscope value to zero. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a gyro - * - * \param gyro - * The adi_gyro_t object for which the angle will be returned - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * - * void opcontrol() { - * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); - * uint32_t now = millis(); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", adi_gyro_get(gyro)); - * - * if (millis() - now > 2000) { - * // Reset the gyro every 2 seconds - * adi_gyro_reset(gyro); - * now = millis(); - * } - * - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_gyro_reset(adi_gyro_t gyro); - -/** - * Disables the gyro and voids the configuration on its port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a gyro - * - * \param gyro - * The adi_gyro_t object to be shut down - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * - * void opcontrol() { - * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); - * uint32_t now = millis(); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", adi_gyro_get(gyro)); - * - * if (millis() - now > 2000) { - * adi_gyro_shutdown(gyro); - * // Shut down the gyro after two seconds - * break; - * } - * - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_gyro_shutdown(adi_gyro_t gyro); - -/** - * Reference type for an initialized potentiometer. - * - * This merely contains the port number for the potentiometer. - */ -typedef int32_t adi_potentiometer_t; - -/** - * Initializes a potentiometer on the given port of the original potentiometer. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a potentiometer - * - * \param port - * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') - * - * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the - * initialization failed. - * - * \b Example - * \code - * #define POTENTIOMETER_PORT 1 - * - * void opcontrol() { - * adi_potentiometer_t potentiometer = adi_potentiometer_init(POTENTIOMETER_PORT); - * while (true) { - * // Print the potentiometer's angle - * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); - * delay(5); - * } - * } - * \endcode - */ -adi_potentiometer_t adi_potentiometer_init(uint8_t port); - -/** - * Initializes a potentiometer on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a potentiometer - * - * \param port - * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') - * \param potentiometer_type - * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type - * - * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the - * initialization failed. - * - * \b Example - * \code - * #define POTENTIOMETER_PORT 1 - * #define POTENTIOMETER_TYPE E_ADI_POT_EDR - * - * void opcontrol() { - * adi_potentiometer_t potentiometer = adi_potentiometer_type_init(POTENTIOMETER_PORT, POTENTIOMETER_TYPE); - * while (true) { - * // Print the potentiometer's angle - * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); - * delay(5); - * } - * } - * \endcode - */ -adi_potentiometer_t adi_potentiometer_type_init(uint8_t port, adi_potentiometer_type_e_t potentiometer_type); - -/** - * Gets the current potentiometer angle in tenths of a degree. - * - * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. - * Potentiometer V2 rotates 330 degrees thus returning an angle between 0-330 degrees. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a potentiometer - * - * \param potentiometer - * The adi_potentiometer_t object for which the angle will be returned - * - * \return The potentiometer angle in degrees. - * - * \b Example - * \code - * #define POTENTIOMETER_PORT 1 - * - * void opcontrol() { - * adi_potentiometer_t potentiometer = adi_potentiometer_t(POTENTIOMETER_PORT); - * while (true) { - * // Print the potnetiometer's angle - * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); - * delay(5); - * } - * } - * \endcode - */ -double adi_potentiometer_get_angle(adi_potentiometer_t potentiometer); - -/** - * Reference type for an initialized addressable led. - * - * This merely contains the port number for the led, unlike its use as an - * object to store led data in the C++ API. - */ -typedef int32_t adi_led_t; - -/** - * Initializes a led on the given port of the original led. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - The ADI port given is not a valid port as defined below - * EADDRINUSE - The port is not configured for ADI output - * - * \param port - * The ADI port to initialize as a led (from 1-8, 'a'-'h', 'A'-'H') - * - * \return An adi_led_t object containing the given port, or PROS_ERR if the - * initialization failed, setting errno - * - * \b Example - * \code - * #define LED_PORT 1 - * - * void opcontrol() { - * adi_led_t led = adi_led_init(LED_PORT); - * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; - * while (true) { - * // Set the led to the colors in the buffer - * adi_led_set(led, buffer, 10); - * delay(5); - * } - * } - * \endcode - */ -adi_led_t adi_led_init(uint8_t port); - -/** - * @brief Clear the entire led strip of color - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of buffer to clear - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example - * \code - * #define LED_PORT 1 - * - * void opcontrol() { - * adi_led_t led = adi_led_init(LED_PORT); - * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; - * while (true) { - * // Set the led to the colors in the buffer - * adi_led_set(led, buffer, 10); - * delay(5); - * - * // Clear the led strip - * adi_led_clear(led); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_led_clear_all(adi_led_t led, uint32_t* buffer, uint32_t buffer_length); - -/** - * @brief Set the entire led strip using the colors contained in the buffer - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of buffer to clear - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example - * \code - * #define LED_PORT 1 - * - * void opcontrol() { - * adi_led_t led = adi_led_init(LED_PORT); - * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; - * while (true) { - * // Set the led strip to the colors in the buffer - * adi_led_set(led, buffer, 10); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_led_set(adi_led_t led, uint32_t* buffer, uint32_t buffer_length); - -/** - * @brief Set the entire led strip to one color - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of buffer to clear - * @param color color to set all the led strip value to - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example - * \code - * #define LED_PORT 1 - * - * void opcontrol() { - * adi_led_t led = adi_led_init(LED_PORT); - * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; - * while (true) { - * // Set the led strip to red - * adi_led_set_all(led, buffer, 10, 0xFF0000); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_led_set_all(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color); - -/** - * @brief Set one pixel on the led strip - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of the input buffer - * @param color color to clear all the led strip to - * @param pixel_position position of the pixel to clear - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example - * \code - * #define LED_PORT 1 - * - * void opcontrol() { - * adi_led_t led = adi_led_init(LED_PORT); - * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; - * while (true) { - * // Set the first pixel to red - * adi_led_set_pixel(led, buffer, 10, 0xFF0000, 0); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_led_set_pixel(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color, uint32_t pixel_position); - -/** - * @brief Clear one pixel on the led strip - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of the input buffer - * @param pixel_position position of the pixel to clear - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example - * \code - * #define LED_PORT 1 - * - * void opcontrol() { - * adi_led_t led = adi_led_init(LED_PORT); - * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; - * while (true) { - * // Set the first pixel to red - * adi_led_set_pixel(led, buffer, 10, 0xFF0000, 0); - * delay(5); - * - * // Clear the first pixel - * adi_led_clear_pixel(led, buffer, 10, 0); - * delay(5); - * } - * } - * \endcode - */ -int32_t adi_led_clear_pixel(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t pixel_position); - -/** - * \name Ease of use macro definitions - * These functions provide ease of use definitions for the ADI functions. - * @{ - */ - -/** - * Used for adi_digital_write() to specify a logic HIGH state to output. - * - * In reality, using any non-zero expression or "true" will work to set a pin to - * HIGH. - */ -#define HIGH 1 -/** - * Used for adi_digital_write() to specify a logic LOW state to output. - * - * In reality, using a zero expression or "false" will work to set a pin to LOW. - */ -#define LOW 0 - -/** - * adi_pin_mode() state for a digital input. - */ -#define INPUT 0x00 -/** - * adi_pin_mode() state for a digital output. - */ -#define OUTPUT 0x01 -/** - * adi_pin_mode() state for an analog input. - */ -#define INPUT_ANALOG 0x02 - -/** - * adi_pin_mode() state for an analog output. - */ -#define OUTPUT_ANALOG 0x03 - -/** @} Name: Ease of use macro definitions*/ - -/** @} Add to group: c-adi*/ - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - -#endif // _PROS_ADI_H_ +/** + * \file pros/adi.h + * \ingroup c-adi + * + * Contains prototypes for interfacing with the ADI. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-adi ADI (TriPort) C API + * \note The external ADI API can be found [here.](@ref ext-adi) + * \note Additional example code for this module can be found in its [Tutorial.](@ref adi) + */ + +#ifndef _PROS_ADI_H_ +#define _PROS_ADI_H_ + +#include +#include +#ifndef PROS_ERR +#define PROS_ERR (INT32_MAX) +#endif + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-adi + */ + +/** + * \addtogroup c-adi + * @{ + */ + +/** + * \enum adi_port_config_e + * Represents the port type for an ADI port. + */ +typedef enum adi_port_config_e { + E_ADI_ANALOG_IN = 0, + E_ADI_ANALOG_OUT = 1, + E_ADI_DIGITAL_IN = 2, + E_ADI_DIGITAL_OUT = 3, + +#ifdef _INTELLISENSE +#define _DEPRECATE_DIGITAL_IN = E_ADI_DIGITAL_IN +#define _DEPRECATE_ANALOG_IN = E_ADI_ANALOG_IN +#else +#define _DEPRECATE_DIGITAL_IN __attribute__((deprecated("use E_ADI_DIGITAL_IN instead"))) = E_ADI_DIGITAL_IN +#define _DEPRECATE_ANALOG_IN __attribute__((deprecated("use E_ADI_ANALOG_IN instead"))) = E_ADI_ANALOG_IN +#endif + + E_ADI_SMART_BUTTON _DEPRECATE_DIGITAL_IN, + E_ADI_SMART_POT _DEPRECATE_ANALOG_IN, + + E_ADI_LEGACY_BUTTON _DEPRECATE_DIGITAL_IN, + E_ADI_LEGACY_POT _DEPRECATE_ANALOG_IN, + E_ADI_LEGACY_LINE_SENSOR _DEPRECATE_ANALOG_IN, + E_ADI_LEGACY_LIGHT_SENSOR _DEPRECATE_ANALOG_IN, + E_ADI_LEGACY_GYRO = 10, + E_ADI_LEGACY_ACCELEROMETER _DEPRECATE_ANALOG_IN, + +#undef _DEPRECATE_DIGITAL_IN +#undef _DEPRECATE_ANALOG_IN + + E_ADI_LEGACY_SERVO = 12, + E_ADI_LEGACY_PWM = 13, + + E_ADI_LEGACY_ENCODER = 14, + E_ADI_LEGACY_ULTRASONIC = 15, + + E_ADI_TYPE_UNDEFINED = 255, + E_ADI_ERR = PROS_ERR +} adi_port_config_e_t; + +/** + * \enum adi_potentiometer_type_e_t + * Represents the potentiometer version type. + */ +typedef enum adi_potentiometer_type_e { + E_ADI_POT_EDR = 0, + E_ADI_POT_V2 +} adi_potentiometer_type_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define ADI_ANALOG_IN pros::E_ADI_ANALOG_IN +#define ADI_ANALOG_OUT pros::E_ADI_ANALOG_OUT +#define ADI_DIGITAL_IN pros::E_ADI_DIGITAL_IN +#define ADI_DIGITAL_OUT pros::E_ADI_DIGITAL_OUT +#define ADI_SMART_BUTTON pros::E_ADI_SMART_BUTTON +#define ADI_SMART_POT pros::E_ADI_SMART_POT +#define ADI_LEGACY_BUTTON pros::E_ADI_LEGACY_BUTTON +#define ADI_LEGACY_POT pros::E_ADI_LEGACY_POT +#define ADI_LEGACY_LINE_SENSOR pros::E_ADI_LEGACY_LINE_SENSOR +#define ADI_LEGACY_LIGHT_SENSOR pros::E_ADI_LEGACY_LIGHT_SENSOR +#define ADI_LEGACY_GYRO pros::E_ADI_LEGACY_GYRO +#define ADI_LEGACY_ACCELEROMETER pros::E_ADI_LEGACY_ACCELEROMETER +#define ADI_LEGACY_SERVO pros::E_ADI_LEGACY_SERVO +#define ADI_LEGACY_PWM pros::E_ADI_LEGACY_PWM +#define ADI_LEGACY_ENCODER pros::E_ADI_LEGACY_ENCODER +#define ADI_LEGACY_ULTRASONIC pros::E_ADI_LEGACY_ULTRASONIC +#define ADI_TYPE_UNDEFINED pros::E_ADI_TYPE_UNDEFINED +#define ADI_ERR pros::E_ADI_ERR +#else +#define ADI_ANALOG_IN E_ADI_ANALOG_IN +#define ADI_ANALOG_OUT E_ADI_ANALOG_OUT +#define ADI_DIGITAL_IN E_ADI_DIGITAL_IN +#define ADI_DIGITAL_OUT E_ADI_DIGITAL_OUT +#define ADI_SMART_BUTTON E_ADI_SMART_BUTTON +#define ADI_SMART_POT E_ADI_SMART_POT +#define ADI_LEGACY_BUTTON E_ADI_LEGACY_BUTTON +#define ADI_LEGACY_POT E_ADI_LEGACY_POT +#define ADI_LEGACY_LINE_SENSOR E_ADI_LEGACY_LINE_SENSOR +#define ADI_LEGACY_LIGHT_SENSOR E_ADI_LEGACY_LIGHT_SENSOR +#define ADI_LEGACY_GYRO E_ADI_LEGACY_GYRO +#define ADI_LEGACY_ACCELEROMETER E_ADI_LEGACY_ACCELEROMETER +#define ADI_LEGACY_SERVO E_ADI_LEGACY_SERVO +#define ADI_LEGACY_PWM E_ADI_LEGACY_PWM +#define ADI_LEGACY_ENCODER E_ADI_LEGACY_ENCODER +#define ADI_LEGACY_ULTRASONIC E_ADI_LEGACY_ULTRASONIC +#define ADI_TYPE_UNDEFINED E_ADI_TYPE_UNDEFINED +#define ADI_ERR E_ADI_ERR +#endif +#endif + +#define INTERNAL_ADI_PORT 22 +#define NUM_ADI_PORTS 8 + +#ifdef __cplusplus +namespace c { +#endif + +/** @} Add to group c-adi*/ + +/** + * \ingroup c-adi + */ + +/** + * \addtogroup c-adi + * @{ + */ + +/** + * Gets the configuration for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return + * the configuration + * + * \return The ADI configuration for the given port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * // Displays the value of E_ADI_ANALOG_IN + * printf("Port Type: %d\n", adi_port_get_config(ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +adi_port_config_e_t adi_port_get_config(uint8_t port); + +/** + * Gets the value for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value + * will be returned + * + * \return The value stored for the given port + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * printf("Port Value: %d\n", adi_get_value(ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +int32_t adi_port_get_value(uint8_t port); + +/** + * Configures an ADI port to act as a given sensor type. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param type + * The configuration type for the port + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_port_set_config(ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * } + * \endcode + */ +int32_t adi_port_set_config(uint8_t port, adi_port_config_e_t type); + +/** + * Sets the value for the given ADI port. + * + * This only works on ports configured as outputs, and the behavior will change + * depending on the configuration of the port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports. + * + * \param port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value + * will be set + * \param value + * The value to set the ADI port to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void initialize() { + * adi_port_set_config(DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); + * adi_set_value(DIGITAL_SENSOR_PORT, HIGH); + * } + * \endcode + */ +int32_t adi_port_set_value(uint8_t port, int32_t value); + +/** + * Calibrates the analog sensor on the specified port and returns the new + * calibration value. + * + * This method assumes that the true sensor value is not actively changing at + * this time and computes an average from approximately 500 samples, 1 ms apart, + * for a 0.5 s period of calibration. The average value thus calculated is + * returned and stored for later calls to the adi_analog_read_calibrated() and + * adi_analog_read_calibrated_HR() functions. These functions will return + * the difference between this value and the current sensor value when called. + * + * Do not use this function when the sensor value might be unstable + * (gyro rotation, accelerometer movement). + * + * \note The ADI currently returns data at 10ms intervals, in constrast to the + * calibrate function’s 1ms sample rate. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * + * \param port + * The ADI port to calibrate (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The average sensor value computed by this function + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_analog_calibrate(ANALOG_SENSOR_PORT); + * printf("Calibrated Reading: %d\n", adi_analog_read_calibrated(ANALOG_SENSOR_PORT)); + * // All readings from then on will be calibrated + * } + * \endcode + */ +int32_t adi_analog_calibrate(uint8_t port); + +/** + * Gets the 12-bit value of the specified port. + * + * The value returned is undefined if the analog pin has been switched to a + * different mode. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an analog input + * + * \param port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The analog sensor value, where a value of 0 reflects an input voltage + * of nearly 0 V and a value of 4095 reflects an input voltage of nearly 5 V + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", adi_analog_read(ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_analog_read(uint8_t port); + +/** + * Gets the 12 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This function is + * inappropriate for sensor values intended for integration, as round-off error + * can accumulate causing drift over time. Use adi_analog_read_calibrated_HR() + * instead. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an analog input + * + * \param port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -4095 to 4095 + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", adi_analog_read_calibrated(ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_analog_read_calibrated(uint8_t port); + +/** + * Gets the 16 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This is intended for + * integrated sensor values such as gyros and accelerometers to reduce drift due + * to round-off, and should not be used on a sensor such as a line tracker + * or potentiometer. + * + * The value returned actually has 16 bits of "precision", even though the ADC + * only reads 12 bits, so that error induced by the average value being between + * two values when integrated over time is trivial. Think of the value as the + * true value times 16. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an analog input + * + * \param port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -16384 to 16384 + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * adi_analog_calibrate(ANALOG_SENSOR_PORT); + * printf("Sensor Reading: %d\n", adi_analog_read_calibrated_HR(ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_analog_read_calibrated_HR(uint8_t port); + +/** + * Gets the digital value (1 or 0) of a port configured as a digital input. + * + * If the port is configured as some other mode, the digital value which + * reflects the current state of the port is returned, which may or may not + * differ from the currently set value. The return value is undefined for ports + * configured as any mode other than a Digital Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a digital input + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return True if the pin is HIGH, or false if it is LOW + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Value: %d\n", adi_digital_read(DIGITAL_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_digital_read(uint8_t port); + +/** + * Gets a rising-edge case for a digital button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under the + * same circumstances, so only one task should call this function for any given + * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call + * this function for button 3, but should not for buttons 1 or 2. A typical + * use-case for this function is to call inside opcontrol to detect new button + * presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a digital input + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the button is pressed and had not been pressed + * the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * if (adi_digital_get_new_press(DIGITAL_SENSOR_PORT)) { + * // Toggle pneumatics or other state operations + * } + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_digital_get_new_press(uint8_t port); + +/** + * Sets the digital value (1 or 0) of a port configured as a digital output. + * + * If the port is configured as some other mode, behavior is undefined. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a digital output + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * \param value + * An expression evaluating to "true" or "false" to set the output to + * HIGH or LOW respectively, or the constants HIGH or LOW themselves + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define DIGITAL_SENSOR_PORT + * + * void opcontrol() { + * bool state = LOW; + * while (true) { + * state != state; + * adi_digital_write(DIGITAL_SENSOR_PORT, state); + * delay(5); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ +int32_t adi_digital_write(uint8_t port, bool value); + +/** + * Configures the port as an input or output with a variety of settings. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * + * \param port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * \param mode + * One of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * adi_pin_mode(ANALOG_SENSOR_PORT, INPUT_ANALOG); + * } + * \endcode + */ +int32_t adi_pin_mode(uint8_t port, uint8_t mode); + +/** + * Sets the speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an motor + * + * \param port + * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') + * \param speed + * The new signed speed; -127 is full reverse and 127 is full forward, + * with 0 being off + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * adi_motor_set(MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t adi_motor_set(uint8_t port, int8_t speed); + +/** + * Gets the last set speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an motor + * + * \param port + * The ADI port to get (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The last set speed of the motor on the given port + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward + * printf("Commanded Motor Power: %d\n", adi_motor_get(MOTOR_PORT)); // Will display 127 + * delay(1000); + * adi_motor_set(MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t adi_motor_get(uint8_t port); + +/** + * Stops the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an motor + * + * \param port + * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * adi_motor_set(MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * // adi_motor_set(MOTOR_PORT, 0); // Stop the motor + * adi_motor_stop(MOTOR_PORT); // use this instead + * } + * \endcode + */ +int32_t adi_motor_stop(uint8_t port); + +/** + * Reference type for an initialized encoder. + * + * This merely contains the port number for the encoder. + */ +typedef int32_t adi_encoder_t; + +/** + * Gets the number of ticks recorded by the encoder. + * + * There are 360 ticks in one revolution. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to read + * + * \return The signed and cumulative number of counts since the last start or + * reset + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf("Encoder Value: %d\n", adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_encoder_get(adi_encoder_t enc); + +/** + * Creates an encoder object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + + * + * \param port_top + * The "top" wire from the encoder sensor with the removable cover side + * up. This should be in port 1, 3, 5, or 7 ('A', 'C', 'E', or 'G'). + * \param port_bottom + * The "bottom" wire from the encoder sensor + * \param reverse + * If "true", the sensor will count in the opposite direction + * + * \return An adi_encoder_t object to be stored and used for later calls to + * encoder functions + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf("Encoder Value: %d\n", adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +adi_encoder_t adi_encoder_init(uint8_t port_top, uint8_t port_bottom, bool reverse); + +/** + * Sets the encoder value to zero. + * + * It is safe to use this method while an encoder is enabled. It is not + * necessary to call this method before stopping or starting an encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to reset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * delay(1000); // Move the encoder around in this time + * adi_encoder_reset(enc); // The encoder is now zero again + * } + * \endcode + */ +int32_t adi_encoder_reset(adi_encoder_t enc); + +/** + * Disables the encoder and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * adi_encoder_t enc = adi_encoder_init(PORT_TOP, PORT_BOTTOM, false); + * // Use the encoder + * adi_encoder_shutdown(enc); + * } + * \endcode + */ +int32_t adi_encoder_shutdown(adi_encoder_t enc); + +/** + * Reference type for an initialized ultrasonic. + * + * This merely contains the port number for the ultrasonic. + */ +typedef int32_t adi_ultrasonic_t; + +/** + * Gets the current ultrasonic sensor value in centimeters. + * + * If no object was found, zero is returned. If the ultrasonic sensor was never + * started, the return value is undefined. Round and fluffy objects can cause + * inaccurate values to be returned. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to read + * + * \return The distance to the nearest object in m^-4 (10000 indicates 1 meter), + * measured from the sensor's mounting points. + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_ultrasonic_get(adi_ultrasonic_t ult); + +/** + * Creates an ultrasonic object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param port_ping + * The port connected to the orange OUTPUT cable. This should be in port + * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). + * \param port_echo + * The port connected to the yellow INPUT cable. This should be in the + * next highest port following port_ping. + * + * \return An adi_ultrasonic_t object to be stored and used for later calls to + * ultrasonic functions + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +adi_ultrasonic_t adi_ultrasonic_init(uint8_t port_ping, uint8_t port_echo); + +/** + * Disables the ultrasonic sensor and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * + * void opcontrol() { + * adi_ultrasonic_t ult = adi_ultrasonic_init(PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", adi_ultrasonic_get(ult)); + * delay(5); + * } + * adi_ultrasonic_shutdown(ult); + * } + * \endcode + */ +int32_t adi_ultrasonic_shutdown(adi_ultrasonic_t ult); + +/** + * Reference type for an initialized gyroscope. + * + * This merely contains the port number for the gyroscope. + */ +typedef int32_t adi_gyro_t; + +/** + * Gets the current gyro angle in tenths of a degree. Unless a multiplier is + * applied to the gyro, the return value will be a whole number representing + * the number of degrees of rotation times 10. + * + * There are 360 degrees in a circle, thus the gyro will return 3600 for one + * whole rotation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return The gyro angle in degrees. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +double adi_gyro_get(adi_gyro_t gyro); + +/** + * Initializes a gyroscope on the given port. If the given port has not + * previously been configured as a gyro, then this function starts a 1300 ms + * calibration period. + * + * It is highly recommended that this function be called from initialize() when + * the robot is stationary to ensure proper calibration. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param multiplier + * A scalar value that will be multiplied by the gyro heading value + * supplied by the ADI + * + * \return An adi_gyro_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +adi_gyro_t adi_gyro_init(uint8_t port, double multiplier); + +/** + * Resets the gyroscope value to zero. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * // Reset the gyro every 2 seconds + * adi_gyro_reset(gyro); + * now = millis(); + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_gyro_reset(adi_gyro_t gyro); + +/** + * Disables the gyro and voids the configuration on its port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object to be shut down + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * + * void opcontrol() { + * adi_gyro_t gyro = adi_gyro_init(GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * adi_gyro_shutdown(gyro); + * // Shut down the gyro after two seconds + * break; + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_gyro_shutdown(adi_gyro_t gyro); + +/** + * Reference type for an initialized potentiometer. + * + * This merely contains the port number for the potentiometer. + */ +typedef int32_t adi_potentiometer_t; + +/** + * Initializes a potentiometer on the given port of the original potentiometer. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * + * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * + * void opcontrol() { + * adi_potentiometer_t potentiometer = adi_potentiometer_init(POTENTIOMETER_PORT); + * while (true) { + * // Print the potentiometer's angle + * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); + * delay(5); + * } + * } + * \endcode + */ +adi_potentiometer_t adi_potentiometer_init(uint8_t port); + +/** + * Initializes a potentiometer on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param potentiometer_type + * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type + * + * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * #define POTENTIOMETER_TYPE E_ADI_POT_EDR + * + * void opcontrol() { + * adi_potentiometer_t potentiometer = adi_potentiometer_type_init(POTENTIOMETER_PORT, POTENTIOMETER_TYPE); + * while (true) { + * // Print the potentiometer's angle + * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); + * delay(5); + * } + * } + * \endcode + */ +adi_potentiometer_t adi_potentiometer_type_init(uint8_t port, adi_potentiometer_type_e_t potentiometer_type); + +/** + * Gets the current potentiometer angle in tenths of a degree. + * + * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. + * Potentiometer V2 rotates 330 degrees thus returning an angle between 0-330 degrees. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param potentiometer + * The adi_potentiometer_t object for which the angle will be returned + * + * \return The potentiometer angle in degrees. + * + * \b Example + * \code + * #define POTENTIOMETER_PORT 1 + * + * void opcontrol() { + * adi_potentiometer_t potentiometer = adi_potentiometer_t(POTENTIOMETER_PORT); + * while (true) { + * // Print the potnetiometer's angle + * printf("Angle: %lf\n", adi_potentiometer_get_angle(potentiometer)); + * delay(5); + * } + * } + * \endcode + */ +double adi_potentiometer_get_angle(adi_potentiometer_t potentiometer); + +/** + * Reference type for an initialized addressable led. + * + * This merely contains the port number for the led, unlike its use as an + * object to store led data in the C++ API. + */ +typedef int32_t adi_led_t; + +/** + * Initializes a led on the given port of the original led. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - The ADI port given is not a valid port as defined below + * EADDRINUSE - The port is not configured for ADI output + * + * \param port + * The ADI port to initialize as a led (from 1-8, 'a'-'h', 'A'-'H') + * + * \return An adi_led_t object containing the given port, or PROS_ERR if the + * initialization failed, setting errno + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led to the colors in the buffer + * adi_led_set(led, buffer, 10); + * delay(5); + * } + * } + * \endcode + */ +adi_led_t adi_led_init(uint8_t port); + +/** + * @brief Clear the entire led strip of color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led to the colors in the buffer + * adi_led_set(led, buffer, 10); + * delay(5); + * + * // Clear the led strip + * adi_led_clear(led); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_clear_all(adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip using the colors contained in the buffer + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led strip to the colors in the buffer + * adi_led_set(led, buffer, 10); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_set(adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip to one color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @param color color to set all the led strip value to + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the led strip to red + * adi_led_set_all(led, buffer, 10, 0xFF0000); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_set_all(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color); + +/** + * @brief Set one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param color color to clear all the led strip to + * @param pixel_position position of the pixel to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the first pixel to red + * adi_led_set_pixel(led, buffer, 10, 0xFF0000, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_set_pixel(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color, uint32_t pixel_position); + +/** + * @brief Clear one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param pixel_position position of the pixel to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example + * \code + * #define LED_PORT 1 + * + * void opcontrol() { + * adi_led_t led = adi_led_init(LED_PORT); + * uint32_t buffer[10] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFFFFF, 0x000000, 0x000000, 0x000000}; + * while (true) { + * // Set the first pixel to red + * adi_led_set_pixel(led, buffer, 10, 0xFF0000, 0); + * delay(5); + * + * // Clear the first pixel + * adi_led_clear_pixel(led, buffer, 10, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t adi_led_clear_pixel(adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t pixel_position); + +/** + * \name Ease of use macro definitions + * These functions provide ease of use definitions for the ADI functions. + * @{ + */ + +/** + * Used for adi_digital_write() to specify a logic HIGH state to output. + * + * In reality, using any non-zero expression or "true" will work to set a pin to + * HIGH. + */ +#define HIGH 1 +/** + * Used for adi_digital_write() to specify a logic LOW state to output. + * + * In reality, using a zero expression or "false" will work to set a pin to LOW. + */ +#define LOW 0 + +/** + * adi_pin_mode() state for a digital input. + */ +#define INPUT 0x00 +/** + * adi_pin_mode() state for a digital output. + */ +#define OUTPUT 0x01 +/** + * adi_pin_mode() state for an analog input. + */ +#define INPUT_ANALOG 0x02 + +/** + * adi_pin_mode() state for an analog output. + */ +#define OUTPUT_ANALOG 0x03 + +/** @} Name: Ease of use macro definitions*/ + +/** @} Add to group: c-adi*/ + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_ADI_H_ diff --git a/include/pros/apix.h b/include/pros/apix.h index 8662bd5..165c054 100644 --- a/include/pros/apix.h +++ b/include/pros/apix.h @@ -1,939 +1,939 @@ -/** - * \file pros/apix.h - * \ingroup apix - * - * PROS Extended API header - * - * Contains additional declarations for use by advaned users of PROS. These - * functions do not typically have as much error handling or require deeper - * knowledge of real time operating systems. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup apix Extended API - * \note Also included in the Extended API is [LVGL.](https://lvgl.io/) - */ - -#ifndef _PROS_API_EXTENDED_H_ -#define _PROS_API_EXTENDED_H_ - -#include "api.h" -#include "pros/device.h" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wall" -#pragma GCC diagnostic pop -#include "pros/serial.h" - -#ifdef __cplusplus -#include "pros/serial.hpp" -namespace pros::c { -extern "C" { -#endif - -/** - * \ingroup apix - */ - -/** - * \addtogroup apix - * @{ - */ - -/// \name RTOS Facilities -///@{ - -typedef void* queue_t; -typedef void* sem_t; - -/** - * Unblocks a task in the Blocked state (e.g. waiting for a delay, on a - * semaphore, etc.). - * - * \param task - * The task to unblock - * - * \return True if the task was unblocked, false otherwise - * - * \b Example: - * \code - * task_t task = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * task_delay(1000); - * // in another task somewhere else, this will abort the task_delay bove: - * task_abort_delay(task); - * \endcode - */ -bool task_abort_delay(task_t task); - -/** - * Notify a task when a target task is being deleted. - * - * \param target_task - * The task being watched for deletion - * \param task_to_notify - * The task to notify when target_task is deleted - * \param value - * The value to supply to task_notify_ext - * \param notify_action - * The action to supply to task_notify_ext - * - * \b Example: - * \code - * task_t task_to_delete = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * task_t task_to_notify = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn2"); - * - * task_notify_ext(task_to_notify, 0, NOTIFY_ACTION_INCREMENT, NULL); - * - * task_notify_when_deleting(task_to_delete, task_get_current(), 0, NOTIFY_ACTION_NONE); - * task_delete(task_to_delete); - * \endcode - */ -void task_notify_when_deleting(task_t target_task, task_t task_to_notify, uint32_t value, - notify_action_e_t notify_action); - -/** - * Creates a recursive mutex which can be locked recursively by the owner. - * - * \return A newly created recursive mutex. - * - * \b Example: - * \code - * mutex_t mutex = mutex_recursive_create(); - * - * void task_fn(void* param) { - * while(1) { - * mutex_recursive_take(mutex, 1000); - * // critical section - * mutex_recursive_give(mutex); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * \endcode - */ -mutex_t mutex_recursive_create(void); - -/** - * Takes a recursive mutex. - * - * \param mutex - * A mutex handle created by mutex_recursive_create - * \param wait_time - * Amount of time to wait before timing out - * - * \return 1 if the mutex was obtained, 0 otherwise - * - * \b Example: - * \code - * mutex_t mutex = mutex_recursive_create(); - * - * void task_fn(void* param) { - * while(1) { - * mutex_recursive_take(mutex, 1000); - * // critical section - * mutex_recursive_give(mutex); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * \endcode - */ -bool mutex_recursive_take(mutex_t mutex, uint32_t timeout); - -/** - * Gives a recursive mutex. - * - * \param mutex - * A mutex handle created by mutex_recursive_create - * - * \return 1 if the mutex was obtained, 0 otherwise - * - * \b Example: - * \code - * mutex_t mutex = mutex_recursive_create(); - * - * void task_fn(void* param) { - * while(1) { - * mutex_recursive_take(mutex, 1000); - * // critical section - * mutex_recursive_give(mutex); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * \endcode - */ -bool mutex_recursive_give(mutex_t mutex); - -/** - * Returns a handle to the current owner of a mutex. - * - * \param mutex - * A mutex handle - * - * \return A handle to the current task that owns the mutex, or NULL if the - * mutex isn't owned. - * - * \b Example: - * \code - * mutex_t mutex = mutex_create(); - * - * void task_fn(void* param) { - * while(1) { - * mutex_take(mutex, 1000); - * // critical section - * mutex_give(mutex); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * void opcontrol(void) { -* while (1) { -* if (joystick_get_digital(1, 7, JOY_UP)) { -* task_t owner = mutex_get_owner(mutex); -* if (owner != NULL) { -* printf("Mutex is owned by task %s", task_get_name(owner)); -* } else { -* printf("Mutex is not owned"); -* } -* } -* task_delay(20); -* } -* } - * \endcode - */ -task_t mutex_get_owner(mutex_t mutex); - -/** - * Creates a counting sempahore. - * - * \param max_count - * The maximum count value that can be reached. - * \param init_count - * The initial count value assigned to the new semaphore. - * - * \return A newly created semaphore. If an error occurred, NULL will be - * returned and errno can be checked for hints as to why sem_create failed. - * - * \b Example: - * \code - * // Binary semaphore acts as a mutex - * sem_t sem = sem_create(1, 0); - * - * void task_fn(void* param) { - * while(1) { - * sem_take(sem, 1000); - * // critical section - * sem_give(sem); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * \endcode - */ -sem_t sem_create(uint32_t max_count, uint32_t init_count); - -/** - * Deletes a semaphore (or binary semaphore) - * - * \param sem - * Semaphore to delete - * - * \b Example: - * \code - * // Binary semaphore acts as a mutex - * sem_t sem = sem_create(1, 0); - * - * void task_fn(void* param) { - * while(1) { - * sem_take(sem, 1000); - * // critical section - * sem_give(sem); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * void opcontrol(void) { - * while (1) { - * if (joystick_get_digital(1, 7, JOY_UP)) { - * // honestly this is a bad example because you should never - * // delete a semaphore like this - * sem_delete(sem); - * } - * task_delay(20); - * } - * } - * - * \endcode - */ -void sem_delete(sem_t sem); - -/** - * Creates a binary semaphore. - * - * \return A newly created semaphore. - * - * \b Example: - * \code - * // Binary semaphore acts as a mutex - * sem_t sem = sem_binary_create(); - * - * void task_fn(void* param) { - * while(1) { - * sem_take(sem, 1000); - * // critical section - * sem_give(sem); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * \endcode - */ -sem_t sem_binary_create(void); - -/** - * Waits for the semaphore's value to be greater than 0. If the value is already - * greater than 0, this function immediately returns. - * - * \param sem - * Semaphore to wait on - * \param timeout - * Time to wait before the semaphore's becomes available. A timeout of 0 - * can be used to poll the sempahore. TIMEOUT_MAX can be used to block - * indefinitely. - * - * \return True if the semaphore was successfully take, false otherwise. If - * false is returned, then errno is set with a hint about why the sempahore - * couldn't be taken. - * - * \b Example: - * \code - * // Binary semaphore acts as a mutex - * sem_t sem = sem_create(1, 0); - * - * void task_fn(void* param) { - * while(1) { - * if(!sem_wait(sem, 1000)) { - * printf("Failed to take semaphore"); - * task_delay(1000); - * continue; - * } - * // critical section - * sem_give(sem); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * void opcontrol(void) { - * while (1) { - * if (sem_wait(sem, 0))) { - * printf("Semaphore is available"); - * } - * task_delay(20); - * } - * } - * \endcode - */ -bool sem_wait(sem_t sem, uint32_t timeout); - -/** - * Increments a semaphore's value. - * - * \param sem - * Semaphore to post - * - * \return True if the value was incremented, false otherwise. If false is - * returned, then errno is set with a hint about why the semaphore couldn't be - * taken. - * - * \b Example: - * \code - * // Binary semaphore acts as a mutex - * sem_t sem = sem_create(1, 0); - * - * void task_fn(void* param) { - * while(1) { - * sem_post(sem); // increments, mimicking to "claim" - * // critical section - * sem_give(sem); - * task_delay(1000); - * } - * } - * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "task_fn"); - * - * \endcode - */ -bool sem_post(sem_t sem); - -/** - * Returns the current value of the semaphore. - * - * \param sem - * A semaphore handle - * - * \return The current value of the semaphore (e.g. the number of resources - * available) - * - * \b Example of sem_get_count: - * \code - * // Binary semaphore acts as a mutex - * sem_t sem = sem_create(1, 0); - * printf("semaphore count: %d", sem_get_count(sem)); - * // semaphore count: 0 - * sem_take(sem, 1000); - * printf("semaphore count: %d", sem_get_count(sem)); - * // semaphore count: 1 - * sem_give(sem); - * printf("semaphore count: %d", sem_get_count(sem)); - * // semaphore count: 0 - * - * \endcode - */ -uint32_t sem_get_count(sem_t sem); - -/** - * Creates a queue. - * - * \param length - * The maximum number of items that the queue can contain. - * \param item_size - * The number of bytes each item in the queue will require. - * - * \return A handle to a newly created queue, or NULL if the queue cannot be - * created. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * printf("queue length: %d", queue_get_length(queue)); - * } - * \endcode - */ -queue_t queue_create(uint32_t length, uint32_t item_size); - -/** - * Posts an item to the front of a queue. The item is queued by copy, not by - * reference. - * - * \param queue - * The queue handle - * \param item - * A pointer to the item that will be placed on the queue. - * \param timeout - * Time to wait for space to become available. A timeout of 0 can be used - * to attempt to post without blocking. TIMEOUT_MAX can be used to block - * indefinitely. - * - * \return True if the item was preprended, false otherwise. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * printf("queue length: %d", queue_get_length(queue)); - * } - */ -bool queue_prepend(queue_t queue, const void* item, uint32_t timeout); - -/** - * Posts an item to the end of a queue. The item is queued by copy, not by - * reference. - * - * \param queue - * The queue handle - * \param item - * A pointer to the item that will be placed on the queue. - * \param timeout - * Time to wait for space to become available. A timeout of 0 can be used - * to attempt to post without blocking. TIMEOUT_MAX can be used to block - * indefinitely. - * - * \return True if the item was preprended, false otherwise. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * printf("queue length: %d", queue_get_length(queue)); - * } - * \endcode - */ -bool queue_append(queue_t queue, const void* item, uint32_t timeout); - -/** - * Receive an item from a queue without removing the item from the queue. - * - * \param queue - * The queue handle - * \param buffer - * Pointer to a buffer to which the received item will be copied - * \param timeout - * The maximum amount of time the task should block waiting for an item to receive should the queue be empty at - * the time of the call. TIMEOUT_MAX can be used to block indefinitely. - * - * \return True if an item was copied into the buffer, false otherwise. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * char* item = "Hello! this is a test"; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * char* recv = malloc(sizeof("Hello! this is a test")); - * queue_peek(queue, recv, 1000); - * printf("Queue: %s", recv); - * free(recv); - * } - * \endcode - */ -bool queue_peek(queue_t queue, void* const buffer, uint32_t timeout); - -/** - * Receive an item from the queue. - * - * \param queue - * The queue handle - * \param buffer - * Pointer to a buffer to which the received item will be copied - * \param timeout - * The maximum amount of time the task should block - * waiting for an item to receive should the queue be empty at the time - * of the call. queue_recv() will return immediately if timeout - * is zero and the queue is empty. - * - * \return True if an item was copied into the buffer, false otherwise. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * char* item = "Hello! this is a test"; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * char* recv = malloc(sizeof("Hello! this is a test")); - * queue_recv(queue, recv, 1000); - * printf("Queue: %s", recv); - * free(recv); - * } - * \endcode - */ -bool queue_recv(queue_t queue, void* const buffer, uint32_t timeout); - -/** - * Return the number of messages stored in a queue. - * - * \param queue - * The queue handle. - * - * \return The number of messages available in the queue. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * - * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * printf("queue waiting: %d", queue_get_waiting(queue)); - * } - * \endcode - */ -uint32_t queue_get_waiting(const queue_t queue); - -/** - * Return the number of spaces left in a queue. - * - * \param queue - * The queue handle. - * - * \return The number of spaces available in the queue. - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * - * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * printf("queue available: %d", queue_get_available(queue)); - * } - * \endcode - */ -uint32_t queue_get_available(const queue_t queue); - -/** - * Delete a queue. - * - * \param queue - * Queue handle to delete - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * queue_delete(queue); - * } - * \endcode - */ -void queue_delete(queue_t queue); - -/** - * Resets a queue to an empty state - * - * \param queue - * Queue handle to reset - * - * \b Example: - * \code - * void opcontrol(void) { - * queue_t queue = queue_create(10, sizeof(int)); - * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - * queue_prepend(queue, item, 1000); - * queue_append(queue, item, 1000); - * queue_reset(queue); - * } - * \endcode - */ -void queue_reset(queue_t queue); - -///@} - -/// \name Device Registration -///@{ - -/** - * Registers a device in the given zero-indexed port - * - * Registers a device of the given type in the given port into the registry, if - * that type of device is detected to be plugged in to that port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (0-20), or a - * a different device than specified is plugged in. - * EADDRINUSE - The port is already registered to another device. - * - * \param port - * The port number to register the device - * \param device - * The type of device to register - * - * \return 1 upon success, PROS_ERR upon failure - * - * \b Example: - * \code - * void opcontrol(void) { - * registry_bind_port(1, E_DEVICE_MOTOR); - * } - * \endcode - */ -int registry_bind_port(uint8_t port, v5_device_e_t device_type); - -/** - * Deregisters a devices from the given zero-indexed port - * - * Removes the device registed in the given port, if there is one. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (0-20). - * - * \param port - * The port number to deregister - * - * \return 1 upon success, PROS_ERR upon failure - * - * \b Example: - * \code - * void opcontrol(void) { - * registry_bind_port(1, E_DEVICE_MOTOR); - * registry_unbind_port(1); - * } - * \endcode - */ -int registry_unbind_port(uint8_t port); - -/** - * Returns the type of device registered to the zero-indexed port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (0-20). - * - * \param port - * The V5 port number from 0-20 - * - * \return The type of device that is registered into the port (NOT what is - * plugged in) - * - * \b Example: - * \code - * void opcontrol(void) { - * registry_bind_port(1, E_DEVICE_MOTOR); - * printf("port 1 is registered to a motor: %d", registry_get_bound_type(1) == E_DEVICE_MOTOR); - * } - * \endcode - */ -v5_device_e_t registry_get_bound_type(uint8_t port); - -/** - * Returns the type of the device plugged into the zero-indexed port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (0-20). - * - * \param port - * The V5 port number from 0-20 - * - * \return The type of device that is plugged into the port (NOT what is - * registered) - * - * \b Example: - * \code - * void opcontrol(void) { - * registry_bind_port(1, E_DEVICE_MOTOR); - * printf("port 1 is registered to a motor: %d", registry_get_plugged_type(1) == E_DEVICE_MOTOR); - * } - * \endcode - */ -v5_device_e_t registry_get_plugged_type(uint8_t port); - -///@} - -/// \name Filesystem -///@{ - -/** - * Control settings of the serial driver. - * - * \param action - * An action to perform on the serial driver. See the SERCTL_* macros for - * details on the different actions. - * \param extra_arg - * An argument to pass in based on the action - * - * \b Example: - * \code - * void opcontrol(void) { - * serctl(SERCTL_SET_BAUDRATE, (void*) 9600); - * } - */ -int32_t serctl(const uint32_t action, void* const extra_arg); - -/* - * Control settings of the microSD card driver. - * - * \param action - * An action to perform on the microSD card driver. See the USDCTL_* macros - * for details on the different actions. - * \param extra_arg - * An argument to pass in based on the action - */ -// Not yet implemented -// int32_t usdctl(const uint32_t action, void* const extra_arg); - -/** - * Control settings of the way the file's driver treats the file - * - * \param file - * A valid file descriptor number - * \param action - * An action to perform on the file's driver. See the *CTL_* macros for - * details on the different actions. Note that the action passed in must - * match the correct driver (e.g. don't perform a SERCTL_* action on a - * microSD card file) - * \param extra_arg - * An argument to pass in based on the action - * - * \b Example: - * \code - * void opcontrol(void) { - * int32_t fd = open("serial", O_RDWR); - * fdctl(fd, SERCTL_SET_BAUDRATE, (void*) 9600); - * } - * \endcode - */ -int32_t fdctl(int file, const uint32_t action, void* const extra_arg); - -/** - * Sets the reverse flag for the motor. - * - * This will invert its movements and the values returned for its position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1-21 - * \param reverse - * True reverses the motor, false is default - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_set_reversed(1, true); - * printf("Is this motor reversed? %d\n", motor_is_reversed(1)); - * } - * \endcode - */ -int32_t motor_set_reversed(int8_t port, const bool reverse); - -/** - * Gets the operation direction of the motor as set by the user. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1-21 - * - * \return 1 if the motor has been reversed and 0 if the motor was not reversed, - * or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * void initialize() { - * printf("Is the motor reversed? %d\n", motor_is_reversed(1)); - * // Prints "Is the motor reversed? 0" - * } - * \endcode - */ -int32_t motor_is_reversed(int8_t port); - -/** - * Action macro to pass into serctl or fdctl that activates the stream - * identifier. - * - * When used with serctl, the extra argument must be the little endian - * representation of the stream identifier (e.g. "sout" -> 0x74756f73) - * - */ -#define SERCTL_ACTIVATE 10 - -/** - * Action macro to pass into serctl or fdctl that deactivates the stream - * identifier. - * - * When used with serctl, the extra argument must be the little endian - * representation of the stream identifier (e.g. "sout" -> 0x74756f73) - * - */ -#define SERCTL_DEACTIVATE 11 - -/** - * Action macro to pass into fdctl that enables blocking writes for the file - * - * The extra argument is not used with this action, provide any value (e.g. - * NULL) instead - * - */ -#define SERCTL_BLKWRITE 12 - -/** - * Action macro to pass into fdctl that makes writes non-blocking for the file - * - * The extra argument is not used with this action, provide any value (e.g. - * NULL) instead - * - */ -#define SERCTL_NOBLKWRITE 13 - -/** - * Action macro to pass into serctl that enables advanced stream multiplexing - * capabilities - * - * The extra argument is not used with this action, provide any value (e.g. - * NULL) instead - * - */ -#define SERCTL_ENABLE_COBS 14 - -/** - * Action macro to pass into serctl that disables advanced stream multiplexing - * capabilities - * - * The extra argument is not used with this action, provide any value (e.g. - * NULL) instead - * - */ -#define SERCTL_DISABLE_COBS 15 - -/** - * Action macro to check if there is data available from the Generic Serial - * Device - * - */ -#define DEVCTL_FIONREAD 16 - -/** - * Action macro to check if there is space available in the Generic Serial - * Device's output buffer - * - */ -#define DEVCTL_FIONWRITE 18 - -/** - * Action macro to set the Generic Serial Device's baudrate. - * - * The extra argument is the baudrate. - */ -#define DEVCTL_SET_BAUDRATE 17 - -///@} - -///@} - -#ifdef __cplusplus -} -} -#endif - -#endif // _PROS_API_EXTENDED_H_ +/** + * \file pros/apix.h + * \ingroup apix + * + * PROS Extended API header + * + * Contains additional declarations for use by advaned users of PROS. These + * functions do not typically have as much error handling or require deeper + * knowledge of real time operating systems. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup apix Extended API + * \note Also included in the Extended API is [LVGL.](https://lvgl.io/) + */ + +#ifndef _PROS_API_EXTENDED_H_ +#define _PROS_API_EXTENDED_H_ + +#include "api.h" +#include "pros/device.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wall" +#pragma GCC diagnostic pop +#include "pros/serial.h" + +#ifdef __cplusplus +#include "pros/serial.hpp" +namespace pros::c { +extern "C" { +#endif + +/** + * \ingroup apix + */ + +/** + * \addtogroup apix + * @{ + */ + +/// \name RTOS Facilities +///@{ + +typedef void* queue_t; +typedef void* sem_t; + +/** + * Unblocks a task in the Blocked state (e.g. waiting for a delay, on a + * semaphore, etc.). + * + * \param task + * The task to unblock + * + * \return True if the task was unblocked, false otherwise + * + * \b Example: + * \code + * task_t task = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * task_delay(1000); + * // in another task somewhere else, this will abort the task_delay bove: + * task_abort_delay(task); + * \endcode + */ +bool task_abort_delay(task_t task); + +/** + * Notify a task when a target task is being deleted. + * + * \param target_task + * The task being watched for deletion + * \param task_to_notify + * The task to notify when target_task is deleted + * \param value + * The value to supply to task_notify_ext + * \param notify_action + * The action to supply to task_notify_ext + * + * \b Example: + * \code + * task_t task_to_delete = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * task_t task_to_notify = task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn2"); + * + * task_notify_ext(task_to_notify, 0, NOTIFY_ACTION_INCREMENT, NULL); + * + * task_notify_when_deleting(task_to_delete, task_get_current(), 0, NOTIFY_ACTION_NONE); + * task_delete(task_to_delete); + * \endcode + */ +void task_notify_when_deleting(task_t target_task, task_t task_to_notify, uint32_t value, + notify_action_e_t notify_action); + +/** + * Creates a recursive mutex which can be locked recursively by the owner. + * + * \return A newly created recursive mutex. + * + * \b Example: + * \code + * mutex_t mutex = mutex_recursive_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_recursive_take(mutex, 1000); + * // critical section + * mutex_recursive_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +mutex_t mutex_recursive_create(void); + +/** + * Takes a recursive mutex. + * + * \param mutex + * A mutex handle created by mutex_recursive_create + * \param wait_time + * Amount of time to wait before timing out + * + * \return 1 if the mutex was obtained, 0 otherwise + * + * \b Example: + * \code + * mutex_t mutex = mutex_recursive_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_recursive_take(mutex, 1000); + * // critical section + * mutex_recursive_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +bool mutex_recursive_take(mutex_t mutex, uint32_t timeout); + +/** + * Gives a recursive mutex. + * + * \param mutex + * A mutex handle created by mutex_recursive_create + * + * \return 1 if the mutex was obtained, 0 otherwise + * + * \b Example: + * \code + * mutex_t mutex = mutex_recursive_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_recursive_take(mutex, 1000); + * // critical section + * mutex_recursive_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +bool mutex_recursive_give(mutex_t mutex); + +/** + * Returns a handle to the current owner of a mutex. + * + * \param mutex + * A mutex handle + * + * \return A handle to the current task that owns the mutex, or NULL if the + * mutex isn't owned. + * + * \b Example: + * \code + * mutex_t mutex = mutex_create(); + * + * void task_fn(void* param) { + * while(1) { + * mutex_take(mutex, 1000); + * // critical section + * mutex_give(mutex); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * void opcontrol(void) { +* while (1) { +* if (joystick_get_digital(1, 7, JOY_UP)) { +* task_t owner = mutex_get_owner(mutex); +* if (owner != NULL) { +* printf("Mutex is owned by task %s", task_get_name(owner)); +* } else { +* printf("Mutex is not owned"); +* } +* } +* task_delay(20); +* } +* } + * \endcode + */ +task_t mutex_get_owner(mutex_t mutex); + +/** + * Creates a counting sempahore. + * + * \param max_count + * The maximum count value that can be reached. + * \param init_count + * The initial count value assigned to the new semaphore. + * + * \return A newly created semaphore. If an error occurred, NULL will be + * returned and errno can be checked for hints as to why sem_create failed. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * sem_take(sem, 1000); + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +sem_t sem_create(uint32_t max_count, uint32_t init_count); + +/** + * Deletes a semaphore (or binary semaphore) + * + * \param sem + * Semaphore to delete + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * sem_take(sem, 1000); + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * void opcontrol(void) { + * while (1) { + * if (joystick_get_digital(1, 7, JOY_UP)) { + * // honestly this is a bad example because you should never + * // delete a semaphore like this + * sem_delete(sem); + * } + * task_delay(20); + * } + * } + * + * \endcode + */ +void sem_delete(sem_t sem); + +/** + * Creates a binary semaphore. + * + * \return A newly created semaphore. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_binary_create(); + * + * void task_fn(void* param) { + * while(1) { + * sem_take(sem, 1000); + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +sem_t sem_binary_create(void); + +/** + * Waits for the semaphore's value to be greater than 0. If the value is already + * greater than 0, this function immediately returns. + * + * \param sem + * Semaphore to wait on + * \param timeout + * Time to wait before the semaphore's becomes available. A timeout of 0 + * can be used to poll the sempahore. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the semaphore was successfully take, false otherwise. If + * false is returned, then errno is set with a hint about why the sempahore + * couldn't be taken. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * if(!sem_wait(sem, 1000)) { + * printf("Failed to take semaphore"); + * task_delay(1000); + * continue; + * } + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * void opcontrol(void) { + * while (1) { + * if (sem_wait(sem, 0))) { + * printf("Semaphore is available"); + * } + * task_delay(20); + * } + * } + * \endcode + */ +bool sem_wait(sem_t sem, uint32_t timeout); + +/** + * Increments a semaphore's value. + * + * \param sem + * Semaphore to post + * + * \return True if the value was incremented, false otherwise. If false is + * returned, then errno is set with a hint about why the semaphore couldn't be + * taken. + * + * \b Example: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * + * void task_fn(void* param) { + * while(1) { + * sem_post(sem); // increments, mimicking to "claim" + * // critical section + * sem_give(sem); + * task_delay(1000); + * } + * } + * task_create(task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "task_fn"); + * + * \endcode + */ +bool sem_post(sem_t sem); + +/** + * Returns the current value of the semaphore. + * + * \param sem + * A semaphore handle + * + * \return The current value of the semaphore (e.g. the number of resources + * available) + * + * \b Example of sem_get_count: + * \code + * // Binary semaphore acts as a mutex + * sem_t sem = sem_create(1, 0); + * printf("semaphore count: %d", sem_get_count(sem)); + * // semaphore count: 0 + * sem_take(sem, 1000); + * printf("semaphore count: %d", sem_get_count(sem)); + * // semaphore count: 1 + * sem_give(sem); + * printf("semaphore count: %d", sem_get_count(sem)); + * // semaphore count: 0 + * + * \endcode + */ +uint32_t sem_get_count(sem_t sem); + +/** + * Creates a queue. + * + * \param length + * The maximum number of items that the queue can contain. + * \param item_size + * The number of bytes each item in the queue will require. + * + * \return A handle to a newly created queue, or NULL if the queue cannot be + * created. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue length: %d", queue_get_length(queue)); + * } + * \endcode + */ +queue_t queue_create(uint32_t length, uint32_t item_size); + +/** + * Posts an item to the front of a queue. The item is queued by copy, not by + * reference. + * + * \param queue + * The queue handle + * \param item + * A pointer to the item that will be placed on the queue. + * \param timeout + * Time to wait for space to become available. A timeout of 0 can be used + * to attempt to post without blocking. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the item was preprended, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue length: %d", queue_get_length(queue)); + * } + */ +bool queue_prepend(queue_t queue, const void* item, uint32_t timeout); + +/** + * Posts an item to the end of a queue. The item is queued by copy, not by + * reference. + * + * \param queue + * The queue handle + * \param item + * A pointer to the item that will be placed on the queue. + * \param timeout + * Time to wait for space to become available. A timeout of 0 can be used + * to attempt to post without blocking. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the item was preprended, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue length: %d", queue_get_length(queue)); + * } + * \endcode + */ +bool queue_append(queue_t queue, const void* item, uint32_t timeout); + +/** + * Receive an item from a queue without removing the item from the queue. + * + * \param queue + * The queue handle + * \param buffer + * Pointer to a buffer to which the received item will be copied + * \param timeout + * The maximum amount of time the task should block waiting for an item to receive should the queue be empty at + * the time of the call. TIMEOUT_MAX can be used to block indefinitely. + * + * \return True if an item was copied into the buffer, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * char* item = "Hello! this is a test"; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * char* recv = malloc(sizeof("Hello! this is a test")); + * queue_peek(queue, recv, 1000); + * printf("Queue: %s", recv); + * free(recv); + * } + * \endcode + */ +bool queue_peek(queue_t queue, void* const buffer, uint32_t timeout); + +/** + * Receive an item from the queue. + * + * \param queue + * The queue handle + * \param buffer + * Pointer to a buffer to which the received item will be copied + * \param timeout + * The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. queue_recv() will return immediately if timeout + * is zero and the queue is empty. + * + * \return True if an item was copied into the buffer, false otherwise. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * char* item = "Hello! this is a test"; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * char* recv = malloc(sizeof("Hello! this is a test")); + * queue_recv(queue, recv, 1000); + * printf("Queue: %s", recv); + * free(recv); + * } + * \endcode + */ +bool queue_recv(queue_t queue, void* const buffer, uint32_t timeout); + +/** + * Return the number of messages stored in a queue. + * + * \param queue + * The queue handle. + * + * \return The number of messages available in the queue. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue waiting: %d", queue_get_waiting(queue)); + * } + * \endcode + */ +uint32_t queue_get_waiting(const queue_t queue); + +/** + * Return the number of spaces left in a queue. + * + * \param queue + * The queue handle. + * + * \return The number of spaces available in the queue. + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * printf("queue available: %d", queue_get_available(queue)); + * } + * \endcode + */ +uint32_t queue_get_available(const queue_t queue); + +/** + * Delete a queue. + * + * \param queue + * Queue handle to delete + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * queue_delete(queue); + * } + * \endcode + */ +void queue_delete(queue_t queue); + +/** + * Resets a queue to an empty state + * + * \param queue + * Queue handle to reset + * + * \b Example: + * \code + * void opcontrol(void) { + * queue_t queue = queue_create(10, sizeof(int)); + * int item[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * queue_prepend(queue, item, 1000); + * queue_append(queue, item, 1000); + * queue_reset(queue); + * } + * \endcode + */ +void queue_reset(queue_t queue); + +///@} + +/// \name Device Registration +///@{ + +/** + * Registers a device in the given zero-indexed port + * + * Registers a device of the given type in the given port into the registry, if + * that type of device is detected to be plugged in to that port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20), or a + * a different device than specified is plugged in. + * EADDRINUSE - The port is already registered to another device. + * + * \param port + * The port number to register the device + * \param device + * The type of device to register + * + * \return 1 upon success, PROS_ERR upon failure + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * } + * \endcode + */ +int registry_bind_port(uint8_t port, v5_device_e_t device_type); + +/** + * Deregisters a devices from the given zero-indexed port + * + * Removes the device registed in the given port, if there is one. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20). + * + * \param port + * The port number to deregister + * + * \return 1 upon success, PROS_ERR upon failure + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * registry_unbind_port(1); + * } + * \endcode + */ +int registry_unbind_port(uint8_t port); + +/** + * Returns the type of device registered to the zero-indexed port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20). + * + * \param port + * The V5 port number from 0-20 + * + * \return The type of device that is registered into the port (NOT what is + * plugged in) + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * printf("port 1 is registered to a motor: %d", registry_get_bound_type(1) == E_DEVICE_MOTOR); + * } + * \endcode + */ +v5_device_e_t registry_get_bound_type(uint8_t port); + +/** + * Returns the type of the device plugged into the zero-indexed port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (0-20). + * + * \param port + * The V5 port number from 0-20 + * + * \return The type of device that is plugged into the port (NOT what is + * registered) + * + * \b Example: + * \code + * void opcontrol(void) { + * registry_bind_port(1, E_DEVICE_MOTOR); + * printf("port 1 is registered to a motor: %d", registry_get_plugged_type(1) == E_DEVICE_MOTOR); + * } + * \endcode + */ +v5_device_e_t registry_get_plugged_type(uint8_t port); + +///@} + +/// \name Filesystem +///@{ + +/** + * Control settings of the serial driver. + * + * \param action + * An action to perform on the serial driver. See the SERCTL_* macros for + * details on the different actions. + * \param extra_arg + * An argument to pass in based on the action + * + * \b Example: + * \code + * void opcontrol(void) { + * serctl(SERCTL_SET_BAUDRATE, (void*) 9600); + * } + */ +int32_t serctl(const uint32_t action, void* const extra_arg); + +/* + * Control settings of the microSD card driver. + * + * \param action + * An action to perform on the microSD card driver. See the USDCTL_* macros + * for details on the different actions. + * \param extra_arg + * An argument to pass in based on the action + */ +// Not yet implemented +// int32_t usdctl(const uint32_t action, void* const extra_arg); + +/** + * Control settings of the way the file's driver treats the file + * + * \param file + * A valid file descriptor number + * \param action + * An action to perform on the file's driver. See the *CTL_* macros for + * details on the different actions. Note that the action passed in must + * match the correct driver (e.g. don't perform a SERCTL_* action on a + * microSD card file) + * \param extra_arg + * An argument to pass in based on the action + * + * \b Example: + * \code + * void opcontrol(void) { + * int32_t fd = open("serial", O_RDWR); + * fdctl(fd, SERCTL_SET_BAUDRATE, (void*) 9600); + * } + * \endcode + */ +int32_t fdctl(int file, const uint32_t action, void* const extra_arg); + +/** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param reverse + * True reverses the motor, false is default + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_set_reversed(1, true); + * printf("Is this motor reversed? %d\n", motor_is_reversed(1)); + * } + * \endcode + */ +int32_t motor_set_reversed(int8_t port, const bool reverse); + +/** + * Gets the operation direction of the motor as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the motor has been reversed and 0 if the motor was not reversed, + * or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * printf("Is the motor reversed? %d\n", motor_is_reversed(1)); + * // Prints "Is the motor reversed? 0" + * } + * \endcode + */ +int32_t motor_is_reversed(int8_t port); + +/** + * Action macro to pass into serctl or fdctl that activates the stream + * identifier. + * + * When used with serctl, the extra argument must be the little endian + * representation of the stream identifier (e.g. "sout" -> 0x74756f73) + * + */ +#define SERCTL_ACTIVATE 10 + +/** + * Action macro to pass into serctl or fdctl that deactivates the stream + * identifier. + * + * When used with serctl, the extra argument must be the little endian + * representation of the stream identifier (e.g. "sout" -> 0x74756f73) + * + */ +#define SERCTL_DEACTIVATE 11 + +/** + * Action macro to pass into fdctl that enables blocking writes for the file + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_BLKWRITE 12 + +/** + * Action macro to pass into fdctl that makes writes non-blocking for the file + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_NOBLKWRITE 13 + +/** + * Action macro to pass into serctl that enables advanced stream multiplexing + * capabilities + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_ENABLE_COBS 14 + +/** + * Action macro to pass into serctl that disables advanced stream multiplexing + * capabilities + * + * The extra argument is not used with this action, provide any value (e.g. + * NULL) instead + * + */ +#define SERCTL_DISABLE_COBS 15 + +/** + * Action macro to check if there is data available from the Generic Serial + * Device + * + */ +#define DEVCTL_FIONREAD 16 + +/** + * Action macro to check if there is space available in the Generic Serial + * Device's output buffer + * + */ +#define DEVCTL_FIONWRITE 18 + +/** + * Action macro to set the Generic Serial Device's baudrate. + * + * The extra argument is the baudrate. + */ +#define DEVCTL_SET_BAUDRATE 17 + +///@} + +///@} + +#ifdef __cplusplus +} +} +#endif + +#endif // _PROS_API_EXTENDED_H_ diff --git a/include/pros/colors.h b/include/pros/colors.h index 13be076..b70a8f9 100644 --- a/include/pros/colors.h +++ b/include/pros/colors.h @@ -1,204 +1,204 @@ -/** - * \file pros/colors.h - * - * Contains macro definitions of colors (as `uint32_t`) - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * Copyright (c) 2017-2020 Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License v. 2.0. If a copy of the MPL was not distributed with this - * file You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-colors Colors C API - */ - -/** - * \ingroup c-colors - * \note These functions can be used for dynamic device instantiation. - */ - -/** - * \addtogroup c-colors - * @{ - */ - -#ifndef _PROS_COLORS_H_ -#define _PROS_COLORS_H_ - -#define RGB2COLOR(R, G, B) ((R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff)) -#define COLOR2R(COLOR) ((COLOR >> 16) & 0xff) -#define COLOR2G(COLOR) ((COLOR >> 8) & 0xff) -#define COLOR2B(COLOR) (COLOR & 0xff) - -#ifdef __cplusplus -namespace pros { -namespace c { -#endif - -/** - * \enum color_e_t - * @brief - * Enum of possible colors - * - * Contains common colors, all members are self descriptive. - */ -typedef enum color_e { - COLOR_ALICE_BLUE = 0x00F0F8FF, - COLOR_ANTIQUE_WHITE = 0x00FAEBD7, - COLOR_AQUA = 0x0000FFFF, - COLOR_AQUAMARINE = 0x007FFFD4, - COLOR_AZURE = 0x00F0FFFF, - COLOR_BEIGE = 0x00F5F5DC, - COLOR_BISQUE = 0x00FFE4C4, - COLOR_BLACK = 0x00000000, - COLOR_BLANCHED_ALMOND = 0x00FFEBCD, - COLOR_BLUE = 0x000000FF, - COLOR_BLUE_VIOLET = 0x008A2BE2, - COLOR_BROWN = 0x00A52A2A, - COLOR_BURLY_WOOD = 0x00DEB887, - COLOR_CADET_BLUE = 0x005F9EA0, - COLOR_CHARTREUSE = 0x007FFF00, - COLOR_CHOCOLATE = 0x00D2691E, - COLOR_CORAL = 0x00FF7F50, - COLOR_CORNFLOWER_BLUE = 0x006495ED, - COLOR_CORNSILK = 0x00FFF8DC, - COLOR_CRIMSON = 0x00DC143C, - COLOR_CYAN = 0x0000FFFF, - COLOR_DARK_BLUE = 0x0000008B, - COLOR_DARK_CYAN = 0x00008B8B, - COLOR_DARK_GOLDENROD = 0x00B8860B, - COLOR_DARK_GRAY = 0x00A9A9A9, - COLOR_DARK_GREY = COLOR_DARK_GRAY, - COLOR_DARK_GREEN = 0x00006400, - COLOR_DARK_KHAKI = 0x00BDB76B, - COLOR_DARK_MAGENTA = 0x008B008B, - COLOR_DARK_OLIVE_GREEN = 0x00556B2F, - COLOR_DARK_ORANGE = 0x00FF8C00, - COLOR_DARK_ORCHID = 0x009932CC, - COLOR_DARK_RED = 0x008B0000, - COLOR_DARK_SALMON = 0x00E9967A, - COLOR_DARK_SEA_GREEN = 0x008FBC8F, - COLOR_DARK_SLATE_GRAY = 0x002F4F4F, - COLOR_DARK_SLATE_GREY = COLOR_DARK_SLATE_GRAY, - COLOR_DARK_TURQUOISE = 0x0000CED1, - COLOR_DARK_VIOLET = 0x009400D3, - COLOR_DEEP_PINK = 0x00FF1493, - COLOR_DEEP_SKY_BLUE = 0x0000BFFF, - COLOR_DIM_GRAY = 0x00696969, - COLOR_DIM_GREY = COLOR_DIM_GRAY, - COLOR_DODGER_BLUE = 0x001E90FF, - COLOR_FIRE_BRICK = 0x00B22222, - COLOR_FLORAL_WHITE = 0x00FFFAF0, - COLOR_FOREST_GREEN = 0x00228B22, - COLOR_FUCHSIA = 0x00FF00FF, - COLOR_GAINSBORO = 0x00DCDCDC, - COLOR_GHOST_WHITE = 0x00F8F8FF, - COLOR_GOLD = 0x00FFD700, - COLOR_GOLDENROD = 0x00DAA520, - COLOR_GRAY = 0x00808080, - COLOR_GREY = COLOR_GRAY, - COLOR_GREEN = 0x00008000, - COLOR_GREEN_YELLOW = 0x00ADFF2F, - COLOR_HONEYDEW = 0x00F0FFF0, - COLOR_HOT_PINK = 0x00FF69B4, - COLOR_INDIAN_RED = 0x00CD5C5C, - COLOR_INDIGO = 0x004B0082, - COLOR_IVORY = 0x00FFFFF0, - COLOR_KHAKI = 0x00F0E68C, - COLOR_LAVENDER = 0x00E6E6FA, - COLOR_LAVENDER_BLUSH = 0x00FFF0F5, - COLOR_LAWN_GREEN = 0x007CFC00, - COLOR_LEMON_CHIFFON = 0x00FFFACD, - COLOR_LIGHT_BLUE = 0x00ADD8E6, - COLOR_LIGHT_CORAL = 0x00F08080, - COLOR_LIGHT_CYAN = 0x00E0FFFF, - COLOR_LIGHT_GOLDENROD_YELLOW = 0x00FAFAD2, - COLOR_LIGHT_GREEN = 0x0090EE90, - COLOR_LIGHT_GRAY = 0x00D3D3D3, - COLOR_LIGHT_GREY = COLOR_LIGHT_GRAY, - COLOR_LIGHT_PINK = 0x00FFB6C1, - COLOR_LIGHT_SALMON = 0x00FFA07A, - COLOR_LIGHT_SEA_GREEN = 0x0020B2AA, - COLOR_LIGHT_SKY_BLUE = 0x0087CEFA, - COLOR_LIGHT_SLATE_GRAY = 0x00778899, - COLOR_LIGHT_SLATE_GREY = COLOR_LIGHT_SLATE_GRAY, - COLOR_LIGHT_STEEL_BLUE = 0x00B0C4DE, - COLOR_LIGHT_YELLOW = 0x00FFFFE0, - COLOR_LIME = 0x0000FF00, - COLOR_LIME_GREEN = 0x0032CD32, - COLOR_LINEN = 0x00FAF0E6, - COLOR_MAGENTA = 0x00FF00FF, - COLOR_MAROON = 0x00800000, - COLOR_MEDIUM_AQUAMARINE = 0x0066CDAA, - COLOR_MEDIUM_BLUE = 0x000000CD, - COLOR_MEDIUM_ORCHID = 0x00BA55D3, - COLOR_MEDIUM_PURPLE = 0x009370DB, - COLOR_MEDIUM_SEA_GREEN = 0x003CB371, - COLOR_MEDIUM_SLATE_BLUE = 0x007B68EE, - COLOR_MEDIUM_SPRING_GREEN = 0x0000FA9A, - COLOR_MEDIUM_TURQUOISE = 0x0048D1CC, - COLOR_MEDIUM_VIOLET_RED = 0x00C71585, - COLOR_MIDNIGHT_BLUE = 0x00191970, - COLOR_MINT_CREAM = 0x00F5FFFA, - COLOR_MISTY_ROSE = 0x00FFE4E1, - COLOR_MOCCASIN = 0x00FFE4B5, - COLOR_NAVAJO_WHITE = 0x00FFDEAD, - COLOR_NAVY = 0x00000080, - COLOR_OLD_LACE = 0x00FDF5E6, - COLOR_OLIVE = 0x00808000, - COLOR_OLIVE_DRAB = 0x006B8E23, - COLOR_ORANGE = 0x00FFA500, - COLOR_ORANGE_RED = 0x00FF4500, - COLOR_ORCHID = 0x00DA70D6, - COLOR_PALE_GOLDENROD = 0x00EEE8AA, - COLOR_PALE_GREEN = 0x0098FB98, - COLOR_PALE_TURQUOISE = 0x00AFEEEE, - COLOR_PALE_VIOLET_RED = 0x00DB7093, - COLOR_PAPAY_WHIP = 0x00FFEFD5, - COLOR_PEACH_PUFF = 0x00FFDAB9, - COLOR_PERU = 0x00CD853F, - COLOR_PINK = 0x00FFC0CB, - COLOR_PLUM = 0x00DDA0DD, - COLOR_POWDER_BLUE = 0x00B0E0E6, - COLOR_PURPLE = 0x00800080, - COLOR_RED = 0x00FF0000, - COLOR_ROSY_BROWN = 0x00BC8F8F, - COLOR_ROYAL_BLUE = 0x004169E1, - COLOR_SADDLE_BROWN = 0x008B4513, - COLOR_SALMON = 0x00FA8072, - COLOR_SANDY_BROWN = 0x00F4A460, - COLOR_SEA_GREEN = 0x002E8B57, - COLOR_SEASHELL = 0x00FFF5EE, - COLOR_SIENNA = 0x00A0522D, - COLOR_SILVER = 0x00C0C0C0, - COLOR_SKY_BLUE = 0x0087CEEB, - COLOR_SLATE_BLUE = 0x006A5ACD, - COLOR_SLATE_GRAY = 0x00708090, - COLOR_SLATE_GREY = COLOR_SLATE_GRAY, - COLOR_SNOW = 0x00FFFAFA, - COLOR_SPRING_GREEN = 0x0000FF7F, - COLOR_STEEL_BLUE = 0x004682B4, - COLOR_TAN = 0x00D2B48C, - COLOR_TEAL = 0x00008080, - COLOR_THISTLE = 0x00D8BFD8, - COLOR_TOMATO = 0x00FF6347, - COLOR_TURQUOISE = 0x0040E0D0, - COLOR_VIOLET = 0x00EE82EE, - COLOR_WHEAT = 0x00F5DEB3, - COLOR_WHITE = 0x00FFFFFF, - COLOR_WHITE_SMOKE = 0x00F5F5F5, - COLOR_YELLOW = 0x00FFFF00, - COLOR_YELLOW_GREEN = 0x009ACD32, -} color_e_t; - - ///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -#endif - -#endif // _PROS_COLORS_H_ +/** + * \file pros/colors.h + * + * Contains macro definitions of colors (as `uint32_t`) + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * Copyright (c) 2017-2020 Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License v. 2.0. If a copy of the MPL was not distributed with this + * file You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-colors Colors C API + */ + +/** + * \ingroup c-colors + * \note These functions can be used for dynamic device instantiation. + */ + +/** + * \addtogroup c-colors + * @{ + */ + +#ifndef _PROS_COLORS_H_ +#define _PROS_COLORS_H_ + +#define RGB2COLOR(R, G, B) ((R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff)) +#define COLOR2R(COLOR) ((COLOR >> 16) & 0xff) +#define COLOR2G(COLOR) ((COLOR >> 8) & 0xff) +#define COLOR2B(COLOR) (COLOR & 0xff) + +#ifdef __cplusplus +namespace pros { +namespace c { +#endif + +/** + * \enum color_e_t + * @brief + * Enum of possible colors + * + * Contains common colors, all members are self descriptive. + */ +typedef enum color_e { + COLOR_ALICE_BLUE = 0x00F0F8FF, + COLOR_ANTIQUE_WHITE = 0x00FAEBD7, + COLOR_AQUA = 0x0000FFFF, + COLOR_AQUAMARINE = 0x007FFFD4, + COLOR_AZURE = 0x00F0FFFF, + COLOR_BEIGE = 0x00F5F5DC, + COLOR_BISQUE = 0x00FFE4C4, + COLOR_BLACK = 0x00000000, + COLOR_BLANCHED_ALMOND = 0x00FFEBCD, + COLOR_BLUE = 0x000000FF, + COLOR_BLUE_VIOLET = 0x008A2BE2, + COLOR_BROWN = 0x00A52A2A, + COLOR_BURLY_WOOD = 0x00DEB887, + COLOR_CADET_BLUE = 0x005F9EA0, + COLOR_CHARTREUSE = 0x007FFF00, + COLOR_CHOCOLATE = 0x00D2691E, + COLOR_CORAL = 0x00FF7F50, + COLOR_CORNFLOWER_BLUE = 0x006495ED, + COLOR_CORNSILK = 0x00FFF8DC, + COLOR_CRIMSON = 0x00DC143C, + COLOR_CYAN = 0x0000FFFF, + COLOR_DARK_BLUE = 0x0000008B, + COLOR_DARK_CYAN = 0x00008B8B, + COLOR_DARK_GOLDENROD = 0x00B8860B, + COLOR_DARK_GRAY = 0x00A9A9A9, + COLOR_DARK_GREY = COLOR_DARK_GRAY, + COLOR_DARK_GREEN = 0x00006400, + COLOR_DARK_KHAKI = 0x00BDB76B, + COLOR_DARK_MAGENTA = 0x008B008B, + COLOR_DARK_OLIVE_GREEN = 0x00556B2F, + COLOR_DARK_ORANGE = 0x00FF8C00, + COLOR_DARK_ORCHID = 0x009932CC, + COLOR_DARK_RED = 0x008B0000, + COLOR_DARK_SALMON = 0x00E9967A, + COLOR_DARK_SEA_GREEN = 0x008FBC8F, + COLOR_DARK_SLATE_GRAY = 0x002F4F4F, + COLOR_DARK_SLATE_GREY = COLOR_DARK_SLATE_GRAY, + COLOR_DARK_TURQUOISE = 0x0000CED1, + COLOR_DARK_VIOLET = 0x009400D3, + COLOR_DEEP_PINK = 0x00FF1493, + COLOR_DEEP_SKY_BLUE = 0x0000BFFF, + COLOR_DIM_GRAY = 0x00696969, + COLOR_DIM_GREY = COLOR_DIM_GRAY, + COLOR_DODGER_BLUE = 0x001E90FF, + COLOR_FIRE_BRICK = 0x00B22222, + COLOR_FLORAL_WHITE = 0x00FFFAF0, + COLOR_FOREST_GREEN = 0x00228B22, + COLOR_FUCHSIA = 0x00FF00FF, + COLOR_GAINSBORO = 0x00DCDCDC, + COLOR_GHOST_WHITE = 0x00F8F8FF, + COLOR_GOLD = 0x00FFD700, + COLOR_GOLDENROD = 0x00DAA520, + COLOR_GRAY = 0x00808080, + COLOR_GREY = COLOR_GRAY, + COLOR_GREEN = 0x00008000, + COLOR_GREEN_YELLOW = 0x00ADFF2F, + COLOR_HONEYDEW = 0x00F0FFF0, + COLOR_HOT_PINK = 0x00FF69B4, + COLOR_INDIAN_RED = 0x00CD5C5C, + COLOR_INDIGO = 0x004B0082, + COLOR_IVORY = 0x00FFFFF0, + COLOR_KHAKI = 0x00F0E68C, + COLOR_LAVENDER = 0x00E6E6FA, + COLOR_LAVENDER_BLUSH = 0x00FFF0F5, + COLOR_LAWN_GREEN = 0x007CFC00, + COLOR_LEMON_CHIFFON = 0x00FFFACD, + COLOR_LIGHT_BLUE = 0x00ADD8E6, + COLOR_LIGHT_CORAL = 0x00F08080, + COLOR_LIGHT_CYAN = 0x00E0FFFF, + COLOR_LIGHT_GOLDENROD_YELLOW = 0x00FAFAD2, + COLOR_LIGHT_GREEN = 0x0090EE90, + COLOR_LIGHT_GRAY = 0x00D3D3D3, + COLOR_LIGHT_GREY = COLOR_LIGHT_GRAY, + COLOR_LIGHT_PINK = 0x00FFB6C1, + COLOR_LIGHT_SALMON = 0x00FFA07A, + COLOR_LIGHT_SEA_GREEN = 0x0020B2AA, + COLOR_LIGHT_SKY_BLUE = 0x0087CEFA, + COLOR_LIGHT_SLATE_GRAY = 0x00778899, + COLOR_LIGHT_SLATE_GREY = COLOR_LIGHT_SLATE_GRAY, + COLOR_LIGHT_STEEL_BLUE = 0x00B0C4DE, + COLOR_LIGHT_YELLOW = 0x00FFFFE0, + COLOR_LIME = 0x0000FF00, + COLOR_LIME_GREEN = 0x0032CD32, + COLOR_LINEN = 0x00FAF0E6, + COLOR_MAGENTA = 0x00FF00FF, + COLOR_MAROON = 0x00800000, + COLOR_MEDIUM_AQUAMARINE = 0x0066CDAA, + COLOR_MEDIUM_BLUE = 0x000000CD, + COLOR_MEDIUM_ORCHID = 0x00BA55D3, + COLOR_MEDIUM_PURPLE = 0x009370DB, + COLOR_MEDIUM_SEA_GREEN = 0x003CB371, + COLOR_MEDIUM_SLATE_BLUE = 0x007B68EE, + COLOR_MEDIUM_SPRING_GREEN = 0x0000FA9A, + COLOR_MEDIUM_TURQUOISE = 0x0048D1CC, + COLOR_MEDIUM_VIOLET_RED = 0x00C71585, + COLOR_MIDNIGHT_BLUE = 0x00191970, + COLOR_MINT_CREAM = 0x00F5FFFA, + COLOR_MISTY_ROSE = 0x00FFE4E1, + COLOR_MOCCASIN = 0x00FFE4B5, + COLOR_NAVAJO_WHITE = 0x00FFDEAD, + COLOR_NAVY = 0x00000080, + COLOR_OLD_LACE = 0x00FDF5E6, + COLOR_OLIVE = 0x00808000, + COLOR_OLIVE_DRAB = 0x006B8E23, + COLOR_ORANGE = 0x00FFA500, + COLOR_ORANGE_RED = 0x00FF4500, + COLOR_ORCHID = 0x00DA70D6, + COLOR_PALE_GOLDENROD = 0x00EEE8AA, + COLOR_PALE_GREEN = 0x0098FB98, + COLOR_PALE_TURQUOISE = 0x00AFEEEE, + COLOR_PALE_VIOLET_RED = 0x00DB7093, + COLOR_PAPAY_WHIP = 0x00FFEFD5, + COLOR_PEACH_PUFF = 0x00FFDAB9, + COLOR_PERU = 0x00CD853F, + COLOR_PINK = 0x00FFC0CB, + COLOR_PLUM = 0x00DDA0DD, + COLOR_POWDER_BLUE = 0x00B0E0E6, + COLOR_PURPLE = 0x00800080, + COLOR_RED = 0x00FF0000, + COLOR_ROSY_BROWN = 0x00BC8F8F, + COLOR_ROYAL_BLUE = 0x004169E1, + COLOR_SADDLE_BROWN = 0x008B4513, + COLOR_SALMON = 0x00FA8072, + COLOR_SANDY_BROWN = 0x00F4A460, + COLOR_SEA_GREEN = 0x002E8B57, + COLOR_SEASHELL = 0x00FFF5EE, + COLOR_SIENNA = 0x00A0522D, + COLOR_SILVER = 0x00C0C0C0, + COLOR_SKY_BLUE = 0x0087CEEB, + COLOR_SLATE_BLUE = 0x006A5ACD, + COLOR_SLATE_GRAY = 0x00708090, + COLOR_SLATE_GREY = COLOR_SLATE_GRAY, + COLOR_SNOW = 0x00FFFAFA, + COLOR_SPRING_GREEN = 0x0000FF7F, + COLOR_STEEL_BLUE = 0x004682B4, + COLOR_TAN = 0x00D2B48C, + COLOR_TEAL = 0x00008080, + COLOR_THISTLE = 0x00D8BFD8, + COLOR_TOMATO = 0x00FF6347, + COLOR_TURQUOISE = 0x0040E0D0, + COLOR_VIOLET = 0x00EE82EE, + COLOR_WHEAT = 0x00F5DEB3, + COLOR_WHITE = 0x00FFFFFF, + COLOR_WHITE_SMOKE = 0x00F5F5F5, + COLOR_YELLOW = 0x00FFFF00, + COLOR_YELLOW_GREEN = 0x009ACD32, +} color_e_t; + + ///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +#endif + +#endif // _PROS_COLORS_H_ diff --git a/include/pros/colors.hpp b/include/pros/colors.hpp index 39a3e2b..970c2cf 100644 --- a/include/pros/colors.hpp +++ b/include/pros/colors.hpp @@ -1,190 +1,190 @@ -/** - * \file pros/colors.hpp - * - * Contains enum class definitions of colors - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * Copyright (c) 2017-2022 Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License v. 2.0. If a copy of the MPL was not distributed with this - * file You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup cpp-colors C++ Color API - */ -#ifndef _PROS_COLORS_HPP_ -#define _PROS_COLORS_HPP_ - - -namespace pros{ -/** - * \ingroup cpp-colors - */ - -/** - * \addtogroup cpp-colors - * @{ - */ - -/** - * \enum Color - * @brief - * Enum class of possible colors - * - * Contains common colors, all members are self descriptive. - */ -enum class Color { - alice_blue = 0x00F0F8FF, - antique_white = 0x00FAEBD7, - aqua = 0x0000FFFF, - aquamarine = 0x007FFFD4, - azure = 0x00F0FFFF, - beige = 0x00F5F5DC, - bisque = 0x00FFE4C4, - black = 0x00000000, - blanched_almond = 0x00FFEBCD, - blue = 0x000000FF, - blue_violet = 0x008A2BE2, - brown = 0x00A52A2A, - burly_wood = 0x00DEB887, - cadet_blue = 0x005F9EA0, - chartreuse = 0x007FFF00, - chocolate = 0x00D2691E, - coral = 0x00FF7F50, - cornflower_blue = 0x006495ED, - cornsilk = 0x00FFF8DC, - crimson = 0x00DC143C, - cyan = 0x0000FFFF, - dark_blue = 0x0000008B, - dark_cyan = 0x00008B8B, - dark_goldenrod = 0x00B8860B, - dark_gray = 0x00A9A9A9, - dark_grey = dark_gray, - dark_green = 0x00006400, - dark_khaki = 0x00BDB76B, - dark_magenta = 0x008B008B, - dark_olive_green = 0x00556B2F, - dark_orange = 0x00FF8C00, - dark_orchid = 0x009932CC, - dark_red = 0x008B0000, - dark_salmon = 0x00E9967A, - dark_sea_green = 0x008FBC8F, - dark_slate_gray = 0x002F4F4F, - dark_slate_grey = dark_slate_gray, - dark_turquoise = 0x0000CED1, - dark_violet = 0x009400D3, - deep_pink = 0x00FF1493, - deep_sky_blue = 0x0000BFFF, - dim_gray = 0x00696969, - dim_grey = dim_gray, - dodger_blue = 0x001E90FF, - fire_brick = 0x00B22222, - floral_white = 0x00FFFAF0, - forest_green = 0x00228B22, - fuchsia = 0x00FF00FF, - gainsboro = 0x00DCDCDC, - ghost_white = 0x00F8F8FF, - gold = 0x00FFD700, - goldenrod = 0x00DAA520, - gray = 0x00808080, - grey = gray, - green = 0x00008000, - green_yellow = 0x00ADFF2F, - honeydew = 0x00F0FFF0, - hot_pink = 0x00FF69B4, - indian_red = 0x00CD5C5C, - indigo = 0x004B0082, - ivory = 0x00FFFFF0, - khaki = 0x00F0E68C, - lavender = 0x00E6E6FA, - lavender_blush = 0x00FFF0F5, - lawn_green = 0x007CFC00, - lemon_chiffon = 0x00FFFACD, - light_blue = 0x00ADD8E6, - light_coral = 0x00F08080, - light_cyan = 0x00E0FFFF, - light_goldenrod_yellow = 0x00FAFAD2, - light_green = 0x0090EE90, - light_gray = 0x00D3D3D3, - light_grey = light_gray, - light_pink = 0x00FFB6C1, - light_salmon = 0x00FFA07A, - light_sea_green = 0x0020B2AA, - light_sky_blue = 0x0087CEFA, - light_slate_gray = 0x00778899, - light_slate_grey = light_slate_gray, - light_steel_blue = 0x00B0C4DE, - light_yellow = 0x00FFFFE0, - lime = 0x0000FF00, - lime_green = 0x0032CD32, - linen = 0x00FAF0E6, - magenta = 0x00FF00FF, - maroon = 0x00800000, - medium_aquamarine = 0x0066CDAA, - medium_blue = 0x000000CD, - medium_orchid = 0x00BA55D3, - medium_purple = 0x009370DB, - medium_sea_green = 0x003CB371, - medium_slate_blue = 0x007B68EE, - medium_spring_green = 0x0000FA9A, - medium_turquoise = 0x0048D1CC, - medium_violet_red = 0x00C71585, - midnight_blue = 0x00191970, - mint_cream = 0x00F5FFFA, - misty_rose = 0x00FFE4E1, - moccasin = 0x00FFE4B5, - navajo_white = 0x00FFDEAD, - navy = 0x00000080, - old_lace = 0x00FDF5E6, - olive = 0x00808000, - olive_drab = 0x006B8E23, - orange = 0x00FFA500, - orange_red = 0x00FF4500, - orchid = 0x00DA70D6, - pale_goldenrod = 0x00EEE8AA, - pale_green = 0x0098FB98, - pale_turquoise = 0x00AFEEEE, - pale_violet_red = 0x00DB7093, - papay_whip = 0x00FFEFD5, - peach_puff = 0x00FFDAB9, - peru = 0x00CD853F, - pink = 0x00FFC0CB, - plum = 0x00DDA0DD, - powder_blue = 0x00B0E0E6, - purple = 0x00800080, - red = 0x00FF0000, - rosy_brown = 0x00BC8F8F, - royal_blue = 0x004169E1, - saddle_brown = 0x008B4513, - salmon = 0x00FA8072, - sandy_brown = 0x00F4A460, - sea_green = 0x002E8B57, - seashell = 0x00FFF5EE, - sienna = 0x00A0522D, - silver = 0x00C0C0C0, - sky_blue = 0x0087CEEB, - slate_blue = 0x006A5ACD, - slate_gray = 0x00708090, - slate_grey = slate_gray, - snow = 0x00FFFAFA, - spring_green = 0x0000FF7F, - steel_blue = 0x004682B4, - tan = 0x00D2B48C, - teal = 0x00008080, - thistle = 0x00D8BFD8, - tomato = 0x00FF6347, - turquoise = 0x0040E0D0, - violet = 0x00EE82EE, - wheat = 0x00F5DEB3, - white = 0x00FFFFFF, - white_smoke = 0x00F5F5F5, - yellow = 0x00FFFF00, - yellow_green = 0x009ACD32, -}; -} // namespace pros - - ///@} - -#endif //_PROS_COLORS_HPP_ +/** + * \file pros/colors.hpp + * + * Contains enum class definitions of colors + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * Copyright (c) 2017-2022 Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License v. 2.0. If a copy of the MPL was not distributed with this + * file You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-colors C++ Color API + */ +#ifndef _PROS_COLORS_HPP_ +#define _PROS_COLORS_HPP_ + + +namespace pros{ +/** + * \ingroup cpp-colors + */ + +/** + * \addtogroup cpp-colors + * @{ + */ + +/** + * \enum Color + * @brief + * Enum class of possible colors + * + * Contains common colors, all members are self descriptive. + */ +enum class Color { + alice_blue = 0x00F0F8FF, + antique_white = 0x00FAEBD7, + aqua = 0x0000FFFF, + aquamarine = 0x007FFFD4, + azure = 0x00F0FFFF, + beige = 0x00F5F5DC, + bisque = 0x00FFE4C4, + black = 0x00000000, + blanched_almond = 0x00FFEBCD, + blue = 0x000000FF, + blue_violet = 0x008A2BE2, + brown = 0x00A52A2A, + burly_wood = 0x00DEB887, + cadet_blue = 0x005F9EA0, + chartreuse = 0x007FFF00, + chocolate = 0x00D2691E, + coral = 0x00FF7F50, + cornflower_blue = 0x006495ED, + cornsilk = 0x00FFF8DC, + crimson = 0x00DC143C, + cyan = 0x0000FFFF, + dark_blue = 0x0000008B, + dark_cyan = 0x00008B8B, + dark_goldenrod = 0x00B8860B, + dark_gray = 0x00A9A9A9, + dark_grey = dark_gray, + dark_green = 0x00006400, + dark_khaki = 0x00BDB76B, + dark_magenta = 0x008B008B, + dark_olive_green = 0x00556B2F, + dark_orange = 0x00FF8C00, + dark_orchid = 0x009932CC, + dark_red = 0x008B0000, + dark_salmon = 0x00E9967A, + dark_sea_green = 0x008FBC8F, + dark_slate_gray = 0x002F4F4F, + dark_slate_grey = dark_slate_gray, + dark_turquoise = 0x0000CED1, + dark_violet = 0x009400D3, + deep_pink = 0x00FF1493, + deep_sky_blue = 0x0000BFFF, + dim_gray = 0x00696969, + dim_grey = dim_gray, + dodger_blue = 0x001E90FF, + fire_brick = 0x00B22222, + floral_white = 0x00FFFAF0, + forest_green = 0x00228B22, + fuchsia = 0x00FF00FF, + gainsboro = 0x00DCDCDC, + ghost_white = 0x00F8F8FF, + gold = 0x00FFD700, + goldenrod = 0x00DAA520, + gray = 0x00808080, + grey = gray, + green = 0x00008000, + green_yellow = 0x00ADFF2F, + honeydew = 0x00F0FFF0, + hot_pink = 0x00FF69B4, + indian_red = 0x00CD5C5C, + indigo = 0x004B0082, + ivory = 0x00FFFFF0, + khaki = 0x00F0E68C, + lavender = 0x00E6E6FA, + lavender_blush = 0x00FFF0F5, + lawn_green = 0x007CFC00, + lemon_chiffon = 0x00FFFACD, + light_blue = 0x00ADD8E6, + light_coral = 0x00F08080, + light_cyan = 0x00E0FFFF, + light_goldenrod_yellow = 0x00FAFAD2, + light_green = 0x0090EE90, + light_gray = 0x00D3D3D3, + light_grey = light_gray, + light_pink = 0x00FFB6C1, + light_salmon = 0x00FFA07A, + light_sea_green = 0x0020B2AA, + light_sky_blue = 0x0087CEFA, + light_slate_gray = 0x00778899, + light_slate_grey = light_slate_gray, + light_steel_blue = 0x00B0C4DE, + light_yellow = 0x00FFFFE0, + lime = 0x0000FF00, + lime_green = 0x0032CD32, + linen = 0x00FAF0E6, + magenta = 0x00FF00FF, + maroon = 0x00800000, + medium_aquamarine = 0x0066CDAA, + medium_blue = 0x000000CD, + medium_orchid = 0x00BA55D3, + medium_purple = 0x009370DB, + medium_sea_green = 0x003CB371, + medium_slate_blue = 0x007B68EE, + medium_spring_green = 0x0000FA9A, + medium_turquoise = 0x0048D1CC, + medium_violet_red = 0x00C71585, + midnight_blue = 0x00191970, + mint_cream = 0x00F5FFFA, + misty_rose = 0x00FFE4E1, + moccasin = 0x00FFE4B5, + navajo_white = 0x00FFDEAD, + navy = 0x00000080, + old_lace = 0x00FDF5E6, + olive = 0x00808000, + olive_drab = 0x006B8E23, + orange = 0x00FFA500, + orange_red = 0x00FF4500, + orchid = 0x00DA70D6, + pale_goldenrod = 0x00EEE8AA, + pale_green = 0x0098FB98, + pale_turquoise = 0x00AFEEEE, + pale_violet_red = 0x00DB7093, + papay_whip = 0x00FFEFD5, + peach_puff = 0x00FFDAB9, + peru = 0x00CD853F, + pink = 0x00FFC0CB, + plum = 0x00DDA0DD, + powder_blue = 0x00B0E0E6, + purple = 0x00800080, + red = 0x00FF0000, + rosy_brown = 0x00BC8F8F, + royal_blue = 0x004169E1, + saddle_brown = 0x008B4513, + salmon = 0x00FA8072, + sandy_brown = 0x00F4A460, + sea_green = 0x002E8B57, + seashell = 0x00FFF5EE, + sienna = 0x00A0522D, + silver = 0x00C0C0C0, + sky_blue = 0x0087CEEB, + slate_blue = 0x006A5ACD, + slate_gray = 0x00708090, + slate_grey = slate_gray, + snow = 0x00FFFAFA, + spring_green = 0x0000FF7F, + steel_blue = 0x004682B4, + tan = 0x00D2B48C, + teal = 0x00008080, + thistle = 0x00D8BFD8, + tomato = 0x00FF6347, + turquoise = 0x0040E0D0, + violet = 0x00EE82EE, + wheat = 0x00F5DEB3, + white = 0x00FFFFFF, + white_smoke = 0x00F5F5F5, + yellow = 0x00FFFF00, + yellow_green = 0x009ACD32, +}; +} // namespace pros + + ///@} + +#endif //_PROS_COLORS_HPP_ diff --git a/include/pros/device.h b/include/pros/device.h index fcff4c4..889e008 100644 --- a/include/pros/device.h +++ b/include/pros/device.h @@ -1,91 +1,91 @@ -/** - * \file pros/device.h - * - * Contains functions for interacting with VEX devices. - * - * - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2021, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-device VEX Generic Device C API (For Advanced Users) - */ - -#ifndef _PROS_DEVICE_H_ -#define _PROS_DEVICE_H_ - -#include - -#ifdef __cplusplus -namespace pros::c { -extern "C" { -#endif - -/** - * \ingroup c-device - * \note These functions can be used for dynamic device instantiation. - */ - -/** - * \addtogroup c-device - * @{ - */ - -/** - * \enum v5_device_e - * \brief - * List of possible v5 devices - * - * This list contains all current V5 Devices, and mirrors V5_DeviceType from the - * api. - */ -typedef enum v5_device_e { - E_DEVICE_NONE = 0, ///< No device is plugged into the port - E_DEVICE_MOTOR = 2, ///< A motor is plugged into the port - E_DEVICE_ROTATION = 4, ///< A rotation sensor is plugged into the port - E_DEVICE_IMU = 6, ///< An inertial sensor is plugged into the port - E_DEVICE_DISTANCE = 7, ///< A distance sensor is plugged into the port - E_DEVICE_RADIO = 8, ///< A radio is plugged into the port - E_DEVICE_VISION = 11, ///< A vision sensor is plugged into the port - E_DEVICE_ADI = 12, ///< This port is an ADI expander - E_DEVICE_OPTICAL = 16, ///< An optical sensor is plugged into the port - E_DEVICE_GPS = 20, ///< A GPS sensor is plugged into the port - E_DEVICE_SERIAL = 129, ///< A serial device is plugged into the port - E_DEVICE_GENERIC __attribute__((deprecated("use E_DEVICE_SERIAL instead"))) = E_DEVICE_SERIAL, - E_DEVICE_UNDEFINED = 255 ///< The device type is not defined, or is not a valid device -} v5_device_e_t; - -/** - * Gets the type of device on given port. - * - * \return The device type as an enum. - * - * \b Example - * \code - * #define DEVICE_PORT 1 - * - * void opcontrol() { - * while (true) { - * v5_device_e_t pt = get_plugged_type(DEVICE_PORT); - * printf("device plugged type: {plugged type: %d}\n", pt); - * delay(20); - * } - * } - * \endcode -*/ -v5_device_e_t get_plugged_type(uint8_t port); - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -#endif - -#endif // _PROS_DEVICE_H_ +/** + * \file pros/device.h + * + * Contains functions for interacting with VEX devices. + * + * + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2021, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-device VEX Generic Device C API (For Advanced Users) + */ + +#ifndef _PROS_DEVICE_H_ +#define _PROS_DEVICE_H_ + +#include + +#ifdef __cplusplus +namespace pros::c { +extern "C" { +#endif + +/** + * \ingroup c-device + * \note These functions can be used for dynamic device instantiation. + */ + +/** + * \addtogroup c-device + * @{ + */ + +/** + * \enum v5_device_e + * \brief + * List of possible v5 devices + * + * This list contains all current V5 Devices, and mirrors V5_DeviceType from the + * api. + */ +typedef enum v5_device_e { + E_DEVICE_NONE = 0, ///< No device is plugged into the port + E_DEVICE_MOTOR = 2, ///< A motor is plugged into the port + E_DEVICE_ROTATION = 4, ///< A rotation sensor is plugged into the port + E_DEVICE_IMU = 6, ///< An inertial sensor is plugged into the port + E_DEVICE_DISTANCE = 7, ///< A distance sensor is plugged into the port + E_DEVICE_RADIO = 8, ///< A radio is plugged into the port + E_DEVICE_VISION = 11, ///< A vision sensor is plugged into the port + E_DEVICE_ADI = 12, ///< This port is an ADI expander + E_DEVICE_OPTICAL = 16, ///< An optical sensor is plugged into the port + E_DEVICE_GPS = 20, ///< A GPS sensor is plugged into the port + E_DEVICE_SERIAL = 129, ///< A serial device is plugged into the port + E_DEVICE_GENERIC __attribute__((deprecated("use E_DEVICE_SERIAL instead"))) = E_DEVICE_SERIAL, + E_DEVICE_UNDEFINED = 255 ///< The device type is not defined, or is not a valid device +} v5_device_e_t; + +/** + * Gets the type of device on given port. + * + * \return The device type as an enum. + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * while (true) { + * v5_device_e_t pt = get_plugged_type(DEVICE_PORT); + * printf("device plugged type: {plugged type: %d}\n", pt); + * delay(20); + * } + * } + * \endcode +*/ +v5_device_e_t get_plugged_type(uint8_t port); + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +#endif + +#endif // _PROS_DEVICE_H_ diff --git a/include/pros/device.hpp b/include/pros/device.hpp index c7529d2..7fcee80 100644 --- a/include/pros/device.hpp +++ b/include/pros/device.hpp @@ -1,162 +1,162 @@ -/** - * \file pros/device.hpp - * - * Base class for all smart devices. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2021, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup cpp-device VEX Generic Device C++ API (For Advanced Users) - */ - -#ifndef _PROS_DEVICE_HPP_ -#define _PROS_DEVICE_HPP_ - -#include "pros/misc.hpp" -#include "pros/rtos.hpp" - -namespace pros { -inline namespace v5 { -/** - * \ingroup cpp-device - * \note These functions can be used for dynamic device instantiation. - */ - -/** - * \addtogroup cpp-device - * @{ - */ - -/** - * \enum DeviceType - * \brief - * Enum of possible v5 devices. - * - * Contains all current V5 Devices. - */ -enum class DeviceType { - none = 0, ///< No device is plugged into the port - motor = 2, ///< A motor is plugged into the port - rotation = 4, ///< A rotation sensor is plugged into the port - imu = 6, ///< An inertial sensor is plugged into the port - distance = 7, ///< A distance sensor is plugged into the port - radio = 8, ///< A radio is plugged into the port - vision = 11, ///< A vision sensor is plugged into the port - adi = 12, ///< This port is an ADI expander - optical = 16, ///< An optical sensor is plugged into the port - gps = 20, ///< A GPS sensor is plugged into the port - serial = 129, ///< A serial device is plugged into the port - undefined = 255 ///< The device type is not defined, or is not a valid device -}; - -class Device { - public: - /** - * Creates a Device object. - * - * \param port The V5 port number from 1-21 - * - * \b Example - * \code - * #define DEVICE_PORT 1 - * - * void opcontrol() { - * Device device(DEVICE_PORT); - * } - * \endcode - */ - explicit Device(const std::uint8_t port); - - /** - * Gets the port number of the Smart Device. - * - * \return The smart device's port number. - * - * \b Example - * \code - * void opcontrol() { - * #define DEVICE_PORT 1 - * while (true) { - * Device device(DEVICE_PORT); - * printf("device plugged type: {port: %d}\n", device.get_port()); - * delay(20); - * } - * } - * \endcode - */ - std::uint8_t get_port(void); - - /** - * Checks if the device is installed. - * - * \return true if the corresponding device is installed, false otherwise. - * \b Example - * - * \code - * #define DEVICE_PORT 1 - * - * void opcontrol() { - * Device device(DEVICE_PORT); - * while (true) { - * printf("device plugged type: {is_installed: %d}\n", device.is_installed()); - * delay(20); - * } - * } - * \endcode - */ - virtual bool is_installed(); - - /** - * Gets the type of device. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Mutex of port cannot be taken (access denied). - * - * \return The device type as an enum. - * - * \b Example - * \code - * #define DEVICE_PORT 1 - * - * void opcontrol() { - Device device(DEVICE_PORT); - * while (true) { - * DeviceType dt = device.get_plugged_type(); - * printf("device plugged type: {plugged type: %d}\n", dt); - * delay(20); - * } - * } - * \endcode - */ - pros::DeviceType get_plugged_type() const; - - - protected: - /** - * Creates a Device object. - * - * \param port The V5 port number from 1-21 - * - * \param deviceType The type of the constructed device - */ - Device(const std::uint8_t port, const enum DeviceType deviceType) : - _port(port), - _deviceType(deviceType) {} - - protected: - const std::uint8_t _port; - const enum DeviceType _deviceType = pros::DeviceType::none; - - ///@} -}; -} // namespace v5 -} // namespace pros - -#endif +/** + * \file pros/device.hpp + * + * Base class for all smart devices. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2021, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-device VEX Generic Device C++ API (For Advanced Users) + */ + +#ifndef _PROS_DEVICE_HPP_ +#define _PROS_DEVICE_HPP_ + +#include "pros/misc.hpp" +#include "pros/rtos.hpp" + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-device + * \note These functions can be used for dynamic device instantiation. + */ + +/** + * \addtogroup cpp-device + * @{ + */ + +/** + * \enum DeviceType + * \brief + * Enum of possible v5 devices. + * + * Contains all current V5 Devices. + */ +enum class DeviceType { + none = 0, ///< No device is plugged into the port + motor = 2, ///< A motor is plugged into the port + rotation = 4, ///< A rotation sensor is plugged into the port + imu = 6, ///< An inertial sensor is plugged into the port + distance = 7, ///< A distance sensor is plugged into the port + radio = 8, ///< A radio is plugged into the port + vision = 11, ///< A vision sensor is plugged into the port + adi = 12, ///< This port is an ADI expander + optical = 16, ///< An optical sensor is plugged into the port + gps = 20, ///< A GPS sensor is plugged into the port + serial = 129, ///< A serial device is plugged into the port + undefined = 255 ///< The device type is not defined, or is not a valid device +}; + +class Device { + public: + /** + * Creates a Device object. + * + * \param port The V5 port number from 1-21 + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * Device device(DEVICE_PORT); + * } + * \endcode + */ + explicit Device(const std::uint8_t port); + + /** + * Gets the port number of the Smart Device. + * + * \return The smart device's port number. + * + * \b Example + * \code + * void opcontrol() { + * #define DEVICE_PORT 1 + * while (true) { + * Device device(DEVICE_PORT); + * printf("device plugged type: {port: %d}\n", device.get_port()); + * delay(20); + * } + * } + * \endcode + */ + std::uint8_t get_port(void); + + /** + * Checks if the device is installed. + * + * \return true if the corresponding device is installed, false otherwise. + * \b Example + * + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + * Device device(DEVICE_PORT); + * while (true) { + * printf("device plugged type: {is_installed: %d}\n", device.is_installed()); + * delay(20); + * } + * } + * \endcode + */ + virtual bool is_installed(); + + /** + * Gets the type of device. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Mutex of port cannot be taken (access denied). + * + * \return The device type as an enum. + * + * \b Example + * \code + * #define DEVICE_PORT 1 + * + * void opcontrol() { + Device device(DEVICE_PORT); + * while (true) { + * DeviceType dt = device.get_plugged_type(); + * printf("device plugged type: {plugged type: %d}\n", dt); + * delay(20); + * } + * } + * \endcode + */ + pros::DeviceType get_plugged_type() const; + + + protected: + /** + * Creates a Device object. + * + * \param port The V5 port number from 1-21 + * + * \param deviceType The type of the constructed device + */ + Device(const std::uint8_t port, const enum DeviceType deviceType) : + _port(port), + _deviceType(deviceType) {} + + protected: + const std::uint8_t _port; + const enum DeviceType _deviceType = pros::DeviceType::none; + + ///@} +}; +} // namespace v5 +} // namespace pros + +#endif diff --git a/include/pros/distance.h b/include/pros/distance.h index 327f74e..63bcd41 100644 --- a/include/pros/distance.h +++ b/include/pros/distance.h @@ -1,160 +1,160 @@ -/** - * \file pros/distance.h - * \ingroup c-distance - * - * Contains prototypes for functions related to the VEX Distance sensor. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-distance VEX Distance Sensor C API - */ - -#ifndef _PROS_DISTANCE_H_ -#define _PROS_DISTANCE_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif - -/** - * \ingroup c-distance - */ - -/** - * \addtogroup c-distance - * @{ - */ - -/** - * Get the currently measured distance from the sensor in mm - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Distance Sensor - * - * \param port The V5 Distance Sensor port number from 1-21 - * \return The distance value or PROS_ERR if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define DISTANCE_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Distance Value: %d mm\n", distance_get(DISTANCE_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t distance_get(uint8_t port); - -/** - * Get the confidence in the distance reading - * - * This is a value that has a range of 0 to 63. 63 means high confidence, - * lower values imply less confidence. Confidence is only available - * when distance is > 200mm (the value 10 is returned in this scenario). - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Distance Sensor - * - * \param port The V5 Distance Sensor port number from 1-21 - * \return The confidence value or PROS_ERR if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define DISTANCE_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Distance Confidence Value: %d\n", distance_get_confidence(DISTANCE_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t distance_get_confidence(uint8_t port); - -/** - * Get the current guess at relative object size - * - * This is a value that has a range of 0 to 400. - * A 18" x 30" grey card will return a value of approximately 75 - * in typical room lighting. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Distance Sensor - * - * \param port The V5 Distance Sensor port number from 1-21 - * \return The size value or PROS_ERR if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define DISTANCE_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Distance Object Size: %d\n", distance_get_object_size(DISTANCE_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t distance_get_object_size(uint8_t port); - -/** - * Get the object velocity in m/s - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Distance Sensor - * - * \param port The V5 Distance Sensor port number from 1-21 - * \return The velocity value or PROS_ERR if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define DISTANCE_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Distance Object Velocity: %f\n", distance_get_object_velocity(DISTANCE_PORT)); - * delay(20); - * } - * } - * \endcode - */ -double distance_get_object_velocity(uint8_t port); - -///@} - -#ifdef __cplusplus -} -} -} -#endif - -#endif +/** + * \file pros/distance.h + * \ingroup c-distance + * + * Contains prototypes for functions related to the VEX Distance sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-distance VEX Distance Sensor C API + */ + +#ifndef _PROS_DISTANCE_H_ +#define _PROS_DISTANCE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-distance + */ + +/** + * \addtogroup c-distance + * @{ + */ + +/** + * Get the currently measured distance from the sensor in mm + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The distance value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Value: %d mm\n", distance_get(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t distance_get(uint8_t port); + +/** + * Get the confidence in the distance reading + * + * This is a value that has a range of 0 to 63. 63 means high confidence, + * lower values imply less confidence. Confidence is only available + * when distance is > 200mm (the value 10 is returned in this scenario). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The confidence value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Confidence Value: %d\n", distance_get_confidence(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t distance_get_confidence(uint8_t port); + +/** + * Get the current guess at relative object size + * + * This is a value that has a range of 0 to 400. + * A 18" x 30" grey card will return a value of approximately 75 + * in typical room lighting. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The size value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Object Size: %d\n", distance_get_object_size(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t distance_get_object_size(uint8_t port); + +/** + * Get the object velocity in m/s + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Distance Sensor + * + * \param port The V5 Distance Sensor port number from 1-21 + * \return The velocity value or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define DISTANCE_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Distance Object Velocity: %f\n", distance_get_object_velocity(DISTANCE_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double distance_get_object_velocity(uint8_t port); + +///@} + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/include/pros/error.h b/include/pros/error.h index 72a354f..17dd6d3 100644 --- a/include/pros/error.h +++ b/include/pros/error.h @@ -1,42 +1,42 @@ -/** - * \file pros/error.h - * - * Contains macro definitions for return types, mostly errors - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#ifndef _PROS_ERROR_H_ -#define _PROS_ERROR_H_ - -#include "limits.h" - -// Different Byte Size Errors - -/// @brief -/// Return This on Byte Sized Return Error -#define PROS_ERR_BYTE (INT8_MAX) - -/// @brief -/// Return This on 2 Byte Sized Return Error -#define PROS_ERR_2_BYTE (INT16_MAX) - -/// @brief -/// Return This on 4 Byte Sized Return Error -#define PROS_ERR (INT32_MAX) - -/// @brief -/// Return This on 8 Byte Sized Return Error -#define PROS_ERR_F (INFINITY) - -/// @brief -/// Return This on Success (1) -#define PROS_SUCCESS (1) - -#endif +/** + * \file pros/error.h + * + * Contains macro definitions for return types, mostly errors + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef _PROS_ERROR_H_ +#define _PROS_ERROR_H_ + +#include "limits.h" + +// Different Byte Size Errors + +/// @brief +/// Return This on Byte Sized Return Error +#define PROS_ERR_BYTE (INT8_MAX) + +/// @brief +/// Return This on 2 Byte Sized Return Error +#define PROS_ERR_2_BYTE (INT16_MAX) + +/// @brief +/// Return This on 4 Byte Sized Return Error +#define PROS_ERR (INT32_MAX) + +/// @brief +/// Return This on 8 Byte Sized Return Error +#define PROS_ERR_F (INFINITY) + +/// @brief +/// Return This on Success (1) +#define PROS_SUCCESS (1) + +#endif diff --git a/include/pros/ext_adi.h b/include/pros/ext_adi.h index 29d083a..421b193 100644 --- a/include/pros/ext_adi.h +++ b/include/pros/ext_adi.h @@ -1,1330 +1,1330 @@ -/** - * \file pros/ext_adi.h - * \ingroup ext-adi - * - * Contains prototypes for interfacing with the 3-Wire Expander. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup ext-adi ADI Expander C API - * \note The internal ADI API can be found [here.](@ref c-adi) - */ - -#ifndef _PROS_EXT_ADI_H_ -#define _PROS_EXT_ADI_H_ - -#include -#include - -#include "adi.h" -#include "pros/adi.h" -#ifndef PROS_ERR -#define PROS_ERR (INT32_MAX) -#endif - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -#ifdef __cplusplus -namespace c { -#endif - -/** - * \ingroup ext-adi - */ - -/** - * \addtogroup ext-adi - * @{ - */ - -/******************************************************************************/ -/** General ADI Use Functions **/ -/** **/ -/** These functions allow for interaction with any ADI port type **/ -/******************************************************************************/ - -/** - * Gets the configuration for the given ADI port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return - * the configuration - * - * \return The ADI configuration for the given port - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); - * // Displays the value of E_ADI_ANALOG_IN - * printf("Port Type: %d\n", ext_adi_port_get_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); - * } - * \endcode - */ -adi_port_config_e_t ext_adi_port_get_config(uint8_t smart_port, uint8_t adi_port); - -/** - * Gets the value for the given ADI port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return - * the configuration - * - * \return The value stored for the given port - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); - * printf("Port Value: %d\n", ext_adi_get_value(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); - * } - * \endcode - */ -int32_t ext_adi_port_get_value(uint8_t smart_port, uint8_t adi_port); - -/** - * Configures an ADI port to act as a given sensor type. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure - * \param type - * The configuration type for the port - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); - * } - * \endcode - */ -int32_t ext_adi_port_set_config(uint8_t smart_port, uint8_t adi_port, adi_port_config_e_t type); - -/** - * Sets the value for the given ADI port. - * - * This only works on ports configured as outputs, and the behavior will change - * depending on the configuration of the port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value - * will be set - * \param value - * The value to set the ADI port to - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define DIGITAL_SENSOR_PORT 1 - * - * void initialize() { - * ext_adi_port_set_config(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); - * ext_adi_set_value(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, HIGH); - * } - * \endcode - */ -int32_t ext_adi_port_set_value(uint8_t smart_port, uint8_t adi_port, int32_t value); - -/** - * Calibrates the analog sensor on the specified port and returns the new - * calibration value. - * - * This method assumes that the true sensor value is not actively changing at - * this time and computes an average from approximately 500 samples, 1 ms apart, - * for a 0.5 s period of calibration. The average value thus calculated is - * returned and stored for later calls to the adi_analog_read_calibrated() and - * adi_analog_read_calibrated_HR() functions. These functions will return - * the difference between this value and the current sensor value when called. - * - * Do not use this function when the sensor value might be unstable - * (gyro rotation, accelerometer movement). - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port to calibrate (from 1-8, 'a'-'h', 'A'-'H') - * - * \return The average sensor value computed by this function - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void initialize() { - * ext_adi_analog_calibrate(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT); - * printf("Calibrated Reading: %d\n", - * ext_adi_analog_read_calibrated(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); - * // All readings from then on will be calibrated - * } - * \endcode - */ -int32_t ext_adi_analog_calibrate(uint8_t smart_port, uint8_t adi_port); - -/** - * Gets the 12-bit value of the specified port. - * - * The value returned is undefined if the analog pin has been switched to a - * different mode. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an analog input - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be - * returned - * - * \return The analog sensor value, where a value of 0 reflects an input voltage - * of nearly 0 V and a value of 4095 reflects an input voltage of nearly 5 V - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Sensor Reading: %d\n", ext_adi_analog_read(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_analog_read(uint8_t smart_port, uint8_t adi_port); - -/** - * Gets the 12 bit calibrated value of an analog input port. - * - * The adi_analog_calibrate() function must be run first. This function is - * inappropriate for sensor values intended for integration, as round-off error - * can accumulate causing drift over time. Use adi_analog_read_calibrated_HR() - * instead. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an analog input - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be - * returned - * - * \return The difference of the sensor value from its calibrated default from - * -4095 to 4095 - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Sensor Reading: %d\n", ext_adi_analog_read_calibrated(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_analog_read_calibrated(uint8_t smart_port, uint8_t adi_port); - -/** - * Gets the 16 bit calibrated value of an analog input port. - * - * The adi_analog_calibrate() function must be run first. This is intended for - * integrated sensor values such as gyros and accelerometers to reduce drift due - * to round-off, and should not be used on a sensor such as a line tracker - * or potentiometer. - * - * The value returned actually has 16 bits of "precision", even though the ADC - * only reads 12 bits, so that error induced by the average value being between - * two values when integrated over time is trivial. Think of the value as the - * true value times 16. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an analog input - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be - * returned - * - * \return The difference of the sensor value from its calibrated default from - * -16384 to 16384 - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * ext_adi_analog_calibrate(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT); - * - * printf("Sensor Reading: %d\n", ext_adi_analog_read_calibrated_HR(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_analog_read_calibrated_HR(uint8_t smart_port, uint8_t adi_port); - -/** - * Gets the digital value (1 or 0) of a port configured as a digital input. - * - * If the port is configured as some other mode, the digital value which - * reflects the current state of the port is returned, which may or may not - * differ from the currently set value. The return value is undefined for ports - * configured as any mode other than a Digital Input. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a digital input - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') - * - * \return True if the pin is HIGH, or false if it is LOW - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define DIGITAL_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf(“Sensor Value: %dn”, - * ext_adi_digital_read(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT)); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_digital_read(uint8_t smart_port, uint8_t adi_port); - -/** - * Gets a rising-edge case for a digital button press. - * - * This function is not thread-safe. - * Multiple tasks polling a single button may return different results under the - * same circumstances, so only one task should call this function for any given - * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call - * this function for button 3, but should not for buttons 1 or 2. A typical - * use-case for this function is to call inside opcontrol to detect new button - * presses, and not in any other tasks. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a digital input - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') - * - * \return 1 if the button is pressed and had not been pressed - * the last time this function was called, 0 otherwise. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define DIGITAL_SENSOR_PORT 1 - * - * void opcontrol() { - * while (true) { - * if (ext_adi_digital_get_new_press(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT)) { - * // Toggle pneumatics or other state operations - * } - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_digital_get_new_press(uint8_t smart_port, uint8_t adi_port); - -/** - * Sets the digital value (1 or 0) of a port configured as a digital output. - * - * If the port is configured as some other mode, behavior is undefined. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a digital output - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure - * \param value - * An expression evaluating to "true" or "false" to set the output to - * HIGH or LOW respectively, or the constants HIGH or LOW themselves - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define DIGITAL_SENSOR_PORT 1 - * - * void opcontrol() { - * bool state = LOW; - * while (true) { - * state != state; - * ext_adi_digital_write(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, state); - * - * delay(5); // toggle the sensor value every 50ms - * } - * } - * \endcode - */ -int32_t ext_adi_digital_write(uint8_t smart_port, uint8_t adi_port, bool value); - -/** - * Configures the port as an input or output with a variety of settings. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure - * \param mode - * One of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define ANALOG_SENSOR_PORT 1 - * - * void initialize() { - * ext_adi_pin_mode(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, INPUT_ANALOG); - * } - * \endcode - */ -int32_t ext_adi_pin_mode(uint8_t smart_port, uint8_t adi_port, uint8_t mode); - -/** - * Sets the speed of the motor on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an motor - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure - * \param speed - * The new signed speed; -127 is full reverse and 127 is full forward, - * with 0 being off - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define MOTOR_PORT 1 - * - * void opcontrol() { - * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 127); // Go full speed forward - * delay(1000); - * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor - * } - * \endcode - */ -int32_t ext_adi_motor_set(uint8_t smart_port, uint8_t adi_port, int8_t speed); - -/** - * Gets the last set speed of the motor on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an motor - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port to get (from 1-8, 'a'-'h', 'A'-'H') - * - * \return The last set speed of the motor on the given port - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 # - * define MOTOR_PORT 1 - * - * void opcontrol() { - * ext_adi_motor_set(ADI_EXPANDER_PORT, - * MOTOR_PORT, 127); // Go full speed forward - * printf(“Commanded Motor Power: %dn”, - * ext_adi_motor_get(ADI_EXPANDER_PORT, MOTOR_PORT)); // Will display 127 - * delay(1000); - * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor - * } - * \endcode - */ -int32_t ext_adi_motor_get(uint8_t smart_port, uint8_t adi_port); - -/** - * Stops the motor on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an motor - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define MOTOR_PORT 1 - * - * void opcontrol() { - * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 127); // Go full speed forward - * delay(1000); - * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor - * ext_adi_motor_stop(ADI_EXPANDER_PORT, MOTOR_PORT); // use this instead - * } - * \endcode - */ -int32_t ext_adi_motor_stop(uint8_t smart_port, uint8_t adi_port); - -/** - * Reference type for an initialized encoder. - * - * This merely contains the port number for the encoder. - */ -typedef int32_t ext_adi_encoder_t; - -/** - * Gets the number of ticks recorded by the encoder. - * - * There are 360 ticks in one revolution. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an encoder - * - * \param enc - * The adi_encoder_t object from adi_encoder_init() to read - * - * \return The signed and cumulative number of counts since the last start or - * reset - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define PORT_TOP 1 #define PORT_BOTTOM 2 - * - * void opcontrol() { - * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, - * PORT_TOP, PORT_BOTTOM, false); - * while (true) { - * printf(“Encoder Value: %dn”, - * ext_adi_encoder_get(enc)); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_encoder_get(ext_adi_encoder_t enc); - -/** - * Creates an encoder object and configures the specified ports accordingly. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an encoder - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port_top - * The "top" wire from the encoder sensor with the removable cover side - * up. This should be in port 1, 3, 5, or 7 ('A', 'C', 'E', or 'G'). - * \param adi_port_bottom - * The "bottom" wire from the encoder sensor - * \param reverse - * If "true", the sensor will count in the opposite direction - * - * \return An adi_encoder_t object to be stored and used for later calls to - * encoder functions - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); - * while (true) { - * printf("Encoder Value: %d\n", ext_adi_encoder_get(enc)); - * delay(5); - * } - * } - * \endcode - */ -ext_adi_encoder_t ext_adi_encoder_init(uint8_t smart_port, uint8_t adi_port_top, uint8_t adi_port_bottom, bool reverse); - -/** - * Sets the encoder value to zero. - * - * It is safe to use this method while an encoder is enabled. It is not - * necessary to call this method before stopping or starting an encoder. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an encoder - * - * \param enc - * The adi_encoder_t object from adi_encoder_init() to reset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); - * delay(1000); // Move the encoder around in this time - * ext_adi_encoder_reset(enc); // The encoder is now zero again - * } - * \endcode - */ -int32_t ext_adi_encoder_reset(ext_adi_encoder_t enc); - -/** - * Disables the encoder and voids the configuration on its ports. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an encoder - * - * \param enc - * The adi_encoder_t object from adi_encoder_init() to stop - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define ADI_EXPANDER_PORT 20 - * #define PORT_TOP 1 - * #define PORT_BOTTOM 2 - * - * void opcontrol() { - * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); - * // Use the encoder - * ext_adi_encoder_shutdown(enc); - * } - * \endcode - */ -int32_t ext_adi_encoder_shutdown(ext_adi_encoder_t enc); - -/** - * Reference type for an initialized ultrasonic. - * - * This merely contains the port number for the ultrasonic. - */ -typedef int32_t ext_adi_ultrasonic_t; - -/** - * Gets the current ultrasonic sensor value in centimeters. - * - * If no object was found, zero is returned. If the ultrasonic sensor was never - * started, the return value is undefined. Round and fluffy objects can cause - * inaccurate values to be returned. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an ultrasonic - * - * \param ult - * The adi_ultrasonic_t object from adi_ultrasonic_init() to read - * - * \return The distance to the nearest object in m^-4 (10000 indicates 1 meter), - * measured from the sensor's mounting points. - * - * \b Example - * \code - * - * #define PORT_PING 1 - * #define PORT_ECHO 2 - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); - * while (true) { - * // Print the distance read by the ultrasonic - * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_ultrasonic_get(ext_adi_ultrasonic_t ult); - -/** - * Creates an ultrasonic object and configures the specified ports accordingly. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an ultrasonic - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port_ping - * The port connected to the orange OUTPUT cable. This should be in port - * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). - * \param adi_port_echo - * The port connected to the yellow INPUT cable. This should be in the - * next highest port following port_ping. - * - * \return An adi_ultrasonic_t object to be stored and used for later calls to - * ultrasonic functions - * - * \b Example - * \code - * - * #define PORT_PING 1 - * #define PORT_ECHO 2 - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); - * while (true) { - * // Print the distance read by the ultrasonic - * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); - * delay(5); - * } - * } - * \endcode - */ -ext_adi_ultrasonic_t ext_adi_ultrasonic_init(uint8_t smart_port, uint8_t adi_port_ping, uint8_t adi_port_echo); - -/** - * Disables the ultrasonic sensor and voids the configuration on its ports. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as an ultrasonic - * - * \param ult - * The adi_ultrasonic_t object from adi_ultrasonic_init() to stop - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define PORT_PING 1 - * #define PORT_ECHO 2 - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); - * while (true) { - * // Print the distance read by the ultrasonic - * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); - * delay(5); - * } - * ext_adi_ultrasonic_shutdown(ult); - * } - * \endcode - */ -int32_t ext_adi_ultrasonic_shutdown(ext_adi_ultrasonic_t ult); - -/** - * Reference type for an initialized gyroscope. - * - * This merely contains the port number for the gyroscope. - * - * (Might Be useless with the wire expander.) - */ -typedef int32_t ext_adi_gyro_t; - -/** - * Gets the current gyro angle in tenths of a degree. Unless a multiplier is - * applied to the gyro, the return value will be a whole number representing - * the number of degrees of rotation times 10. - * - * There are 360 degrees in a circle, thus the gyro will return 3600 for one - * whole rotation. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a gyro - * - * \param gyro - * The adi_gyro_t object for which the angle will be returned - * - * \return The gyro angle in degrees. - * - * \b Example - * \code - * - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); - * delay(5); - * } - * } - * \endcode - */ -double ext_adi_gyro_get(ext_adi_gyro_t gyro); - -/** - * Initializes a gyroscope on the given port. If the given port has not - * previously been configured as a gyro, then this function starts a 1300 ms - * calibration period. - * - * It is highly recommended that this function be called from initialize() when - * the robot is stationary to ensure proper calibration. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a gyro - * - * \param smart_port - * The smart port number that the ADI Expander is in - * \param adi_port - * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') - * \param multiplier - * A scalar value that will be multiplied by the gyro heading value - * supplied by the ADI - * - * \return An adi_gyro_t object containing the given port, or PROS_ERR if the - * initialization failed. - * - * \b Example - * \code - * - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); - * delay(5); - * } - * } - * \endcode - */ -ext_adi_gyro_t ext_adi_gyro_init(uint8_t smart_port, uint8_t adi_port, double multiplier); - -/** - * Resets the gyroscope value to zero. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a gyro - * - * \param gyro - * The adi_gyro_t object for which the angle will be returned - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); - * uint32_t now = millis(); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); - * - * if (millis() - now > 2000) { - * // Reset the gyro every 2 seconds - * ext_adi_gyro_reset(gyro); - * now = millis(); - * } - * - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_gyro_reset(ext_adi_gyro_t gyro); - -/** - * Disables the gyro and voids the configuration on its port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - Either the ADI port value or the smart port value is not within its - * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). - * EADDRINUSE - The port is not configured as a gyro - * - * \param gyro - * The adi_gyro_t object to be shut down - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * #define GYRO_PORT 1 - * #define GYRO_MULTIPLIER 1 // Standard behavior - * #define ADI_EXPANDER_PORT 20 - * - * void opcontrol() { - * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); - * uint32_t now = millis(); - * while (true) { - * // Print the gyro's heading - * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); - * - * if (millis() - now > 2000) { - * ext_adi_gyro_shutdown(gyro); - * // Shut down the gyro after two seconds - * break; - * } - * - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_gyro_shutdown(ext_adi_gyro_t gyro); - -/** - * Reference type for an initialized potentiometer. - * - * This merely contains the port number for the potentiometer. - */ -typedef int32_t ext_adi_potentiometer_t; - -/** - * Initializes a potentiometer on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a potentiometer - * - * \param port - * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') - * \param potentiometer_type - * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type - * - * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the - * initialization failed. - */ -ext_adi_potentiometer_t ext_adi_potentiometer_init(uint8_t smart_port, uint8_t adi_port, adi_potentiometer_type_e_t potentiometer_type); - -/** - * Gets the current potentiometer angle in tenths of a degree. - * - * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. - * Potentiometer V2 rotates 333 degrees thus returning an angle between 0-333 degrees. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EADDRINUSE - The port is not configured as a potentiometer - * - * \param potentiometer - * The adi_potentiometer_t object for which the angle will be returned - * - * \return The potentiometer angle in degrees. - */ -double ext_adi_potentiometer_get_angle(ext_adi_potentiometer_t potentiometer); - -/** - * Reference type for an initialized addressable led. - * - * This merely contains the port number for the led, unlike its use as an - * object to store led data in the C++ API. - */ -typedef int32_t ext_adi_led_t; - -/** - * Initializes a led on the given port. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * \param smart_port - * The smart port with the adi expander (1-21) - * \param adi_port - * The ADI port to initialize as a led (from 1-8, 'a'-'h', 'A'-'H') - * - * \return An ext_adi_led_t object containing the given port, or PROS_ERR if the - * initialization failed. - * - * \b Example: - * \code - * #define SMART_PORT 1 - * #define ADI_PORT 'A' - * - * void opcontrol() { - * // Initialize a led on smart port 1 and adi port A - * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); - * // Initialize a buffer with a single color of red - * uint32_t buffer[1] = {0xFF0000}; - * - * while (true) { - * // Set the led to colors in the buffer - * ext_adi_led_set(led, buffer, 1); - * delay(5); - * } - * } - * \endcode - */ -ext_adi_led_t ext_adi_led_init(uint8_t smart_port, uint8_t adi_port); - -/** - * @brief Clear the entire led strip of color - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of buffer to clear - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example: - * \code - * #define SMART_PORT 1 - * #define ADI_PORT 'A' - * - * void opcontrol() { - * // Initialize a led on smart port 1 and adi port A - * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); - * // Initialize a buffer with a single color of red - * uint32_t buffer[1] = {0xFF0000}; - * - * while (true) { - * // Set the led to colors in the buffer - * ext_adi_led_set(led, buffer, 1); - * delay(5); - * - * // Clear the led - * ext_adi_led_clear_all(led, buffer, 1); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_led_clear_all(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length); - -/** - * @brief Set the entire led strip using the colors contained in the buffer - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of buffer to clear - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example: - * \code - * #define SMART_PORT 1 - * #define ADI_PORT 'A' - * - * void opcontrol() { - * // Initialize a led on smart port 1 and adi port A - * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); - * // Initialize a buffer with a single color of red - * uint32_t buffer[1] = {0xFF0000}; - * - * while (true) { - * // Set the led to colors in the buffer - * ext_adi_led_set(led, buffer, 1); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_led_set(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length); - -/** - * @brief Set the entire led strip to one color - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of buffer to clear - * @param color color to set all the led strip value to - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example: - * \code - * #define SMART_PORT 1 - * #define ADI_PORT 'A' - * - * void opcontrol() { - * // Initialize a led on smart port 1 and adi port A - * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); - * // Initialize a buffer with a single color of red - * uint32_t buffer[1] = {0xFF0000}; - * - * while (true) { - * // Set the entire led strip to red - * ext_adi_led_set_all(led, buffer, 1, 0xFF0000); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_led_set_all(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color); - -/** - * @brief Set one pixel on the led strip - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of the input buffer - * @param color color to clear all the led strip to - * @param pixel_position position of the pixel to clear (0 indexed) - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example: - * \code - * #define SMART_PORT 1 - * #define ADI_PORT 'A' - * - * void opcontrol() { - * // Initialize a led on smart port 1 and adi port A - * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); - * // Initialize a buffer with multiple colors - * uint32_t buffer[3] = {0xFF0000, 0x00FF00, 0x0000FF}; - * - * while (true) { - * // Set the first pixel to red - * ext_adi_led_set_pixel(led, buffer, 3, 0xFF0000, 0); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_led_set_pixel(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color, uint32_t pixel_position); - -/** - * @brief Clear one pixel on the led strip - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of ADI Ports - * EINVAL - A given value is not correct, or the buffer is null - * EADDRINUSE - The port is not configured for ADI output - * - * @param led port of type adi_led_t - * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw - * @param buffer_length length of the input buffer - * @param pixel_position position of the pixel to clear (0 indexed) - * @return PROS_SUCCESS if successful, PROS_ERR if not - * - * \b Example: - * \code - * #define SMART_PORT 1 - * #define ADI_PORT 'A' - * - * void opcontrol() { - * // Initialize a led on smart port 1 and adi port A - * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); - * // Initialize a buffer with multiple colors - * uint32_t buffer[3] = {0xFF0000, 0x00FF00, 0x0000FF}; - * - * while (true) { - * // Set the first pixel to red - * ext_adi_led_set_pixel(led, buffer, 3, 0xFF0000, 0); - * delay(5); - * - * // Clear the first pixel - * ext_adi_led_clear_pixel(led, buffer, 3, 0); - * delay(5); - * } - * } - * \endcode - */ -int32_t ext_adi_led_clear_pixel(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t pixel_position); - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - -#endif // _PROS_ADI_H_ +/** + * \file pros/ext_adi.h + * \ingroup ext-adi + * + * Contains prototypes for interfacing with the 3-Wire Expander. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup ext-adi ADI Expander C API + * \note The internal ADI API can be found [here.](@ref c-adi) + */ + +#ifndef _PROS_EXT_ADI_H_ +#define _PROS_EXT_ADI_H_ + +#include +#include + +#include "adi.h" +#include "pros/adi.h" +#ifndef PROS_ERR +#define PROS_ERR (INT32_MAX) +#endif + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/** + * \ingroup ext-adi + */ + +/** + * \addtogroup ext-adi + * @{ + */ + +/******************************************************************************/ +/** General ADI Use Functions **/ +/** **/ +/** These functions allow for interaction with any ADI port type **/ +/******************************************************************************/ + +/** + * Gets the configuration for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return + * the configuration + * + * \return The ADI configuration for the given port + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * // Displays the value of E_ADI_ANALOG_IN + * printf("Port Type: %d\n", ext_adi_port_get_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +adi_port_config_e_t ext_adi_port_get_config(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the value for the given ADI port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which to return + * the configuration + * + * \return The value stored for the given port + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * printf("Port Value: %d\n", ext_adi_get_value(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * } + * \endcode + */ +int32_t ext_adi_port_get_value(uint8_t smart_port, uint8_t adi_port); + +/** + * Configures an ADI port to act as a given sensor type. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param type + * The configuration type for the port + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, E_ADI_ANALOG_IN); + * } + * \endcode + */ +int32_t ext_adi_port_set_config(uint8_t smart_port, uint8_t adi_port, adi_port_config_e_t type); + +/** + * Sets the value for the given ADI port. + * + * This only works on ports configured as outputs, and the behavior will change + * depending on the configuration of the port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') for which the value + * will be set + * \param value + * The value to set the ADI port to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void initialize() { + * ext_adi_port_set_config(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, E_ADI_DIGITAL_OUT); + * ext_adi_set_value(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, HIGH); + * } + * \endcode + */ +int32_t ext_adi_port_set_value(uint8_t smart_port, uint8_t adi_port, int32_t value); + +/** + * Calibrates the analog sensor on the specified port and returns the new + * calibration value. + * + * This method assumes that the true sensor value is not actively changing at + * this time and computes an average from approximately 500 samples, 1 ms apart, + * for a 0.5 s period of calibration. The average value thus calculated is + * returned and stored for later calls to the adi_analog_read_calibrated() and + * adi_analog_read_calibrated_HR() functions. These functions will return + * the difference between this value and the current sensor value when called. + * + * Do not use this function when the sensor value might be unstable + * (gyro rotation, accelerometer movement). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to calibrate (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The average sensor value computed by this function + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * ext_adi_analog_calibrate(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT); + * printf("Calibrated Reading: %d\n", + * ext_adi_analog_read_calibrated(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * // All readings from then on will be calibrated + * } + * \endcode + */ +int32_t ext_adi_analog_calibrate(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the 12-bit value of the specified port. + * + * The value returned is undefined if the analog pin has been switched to a + * different mode. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an analog input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The analog sensor value, where a value of 0 reflects an input voltage + * of nearly 0 V and a value of 4095 reflects an input voltage of nearly 5 V + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", ext_adi_analog_read(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_analog_read(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the 12 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This function is + * inappropriate for sensor values intended for integration, as round-off error + * can accumulate causing drift over time. Use adi_analog_read_calibrated_HR() + * instead. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an analog input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -4095 to 4095 + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Sensor Reading: %d\n", ext_adi_analog_read_calibrated(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_analog_read_calibrated(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the 16 bit calibrated value of an analog input port. + * + * The adi_analog_calibrate() function must be run first. This is intended for + * integrated sensor values such as gyros and accelerometers to reduce drift due + * to round-off, and should not be used on a sensor such as a line tracker + * or potentiometer. + * + * The value returned actually has 16 bits of "precision", even though the ADC + * only reads 12 bits, so that error induced by the average value being between + * two values when integrated over time is trivial. Think of the value as the + * true value times 16. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an analog input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port (from 1-8, 'a'-'h', 'A'-'H') for which the value will be + * returned + * + * \return The difference of the sensor value from its calibrated default from + * -16384 to 16384 + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * ext_adi_analog_calibrate(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT); + * + * printf("Sensor Reading: %d\n", ext_adi_analog_read_calibrated_HR(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_analog_read_calibrated_HR(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets the digital value (1 or 0) of a port configured as a digital input. + * + * If the port is configured as some other mode, the digital value which + * reflects the current state of the port is returned, which may or may not + * differ from the currently set value. The return value is undefined for ports + * configured as any mode other than a Digital Input. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a digital input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return True if the pin is HIGH, or false if it is LOW + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf(“Sensor Value: %dn”, + * ext_adi_digital_read(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_digital_read(uint8_t smart_port, uint8_t adi_port); + +/** + * Gets a rising-edge case for a digital button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under the + * same circumstances, so only one task should call this function for any given + * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call + * this function for button 3, but should not for buttons 1 or 2. A typical + * use-case for this function is to call inside opcontrol to detect new button + * presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a digital input + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to read (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the button is pressed and had not been pressed + * the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * while (true) { + * if (ext_adi_digital_get_new_press(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT)) { + * // Toggle pneumatics or other state operations + * } + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_digital_get_new_press(uint8_t smart_port, uint8_t adi_port); + +/** + * Sets the digital value (1 or 0) of a port configured as a digital output. + * + * If the port is configured as some other mode, behavior is undefined. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a digital output + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param value + * An expression evaluating to "true" or "false" to set the output to + * HIGH or LOW respectively, or the constants HIGH or LOW themselves + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define DIGITAL_SENSOR_PORT 1 + * + * void opcontrol() { + * bool state = LOW; + * while (true) { + * state != state; + * ext_adi_digital_write(ADI_EXPANDER_PORT, DIGITAL_SENSOR_PORT, state); + * + * delay(5); // toggle the sensor value every 50ms + * } + * } + * \endcode + */ +int32_t ext_adi_digital_write(uint8_t smart_port, uint8_t adi_port, bool value); + +/** + * Configures the port as an input or output with a variety of settings. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param mode + * One of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define ANALOG_SENSOR_PORT 1 + * + * void initialize() { + * ext_adi_pin_mode(ADI_EXPANDER_PORT, ANALOG_SENSOR_PORT, INPUT_ANALOG); + * } + * \endcode + */ +int32_t ext_adi_pin_mode(uint8_t smart_port, uint8_t adi_port, uint8_t mode); + +/** + * Sets the speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an motor + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port number (from 1-8, 'a'-'h', 'A'-'H') to configure + * \param speed + * The new signed speed; -127 is full reverse and 127 is full forward, + * with 0 being off + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t ext_adi_motor_set(uint8_t smart_port, uint8_t adi_port, int8_t speed); + +/** + * Gets the last set speed of the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an motor + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to get (from 1-8, 'a'-'h', 'A'-'H') + * + * \return The last set speed of the motor on the given port + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 # + * define MOTOR_PORT 1 + * + * void opcontrol() { + * ext_adi_motor_set(ADI_EXPANDER_PORT, + * MOTOR_PORT, 127); // Go full speed forward + * printf(“Commanded Motor Power: %dn”, + * ext_adi_motor_get(ADI_EXPANDER_PORT, MOTOR_PORT)); // Will display 127 + * delay(1000); + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor + * } + * \endcode + */ +int32_t ext_adi_motor_get(uint8_t smart_port, uint8_t adi_port); + +/** + * Stops the motor on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an motor + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to set (from 1-8, 'a'-'h', 'A'-'H') + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define MOTOR_PORT 1 + * + * void opcontrol() { + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 127); // Go full speed forward + * delay(1000); + * ext_adi_motor_set(ADI_EXPANDER_PORT, MOTOR_PORT, 0); // Stop the motor + * ext_adi_motor_stop(ADI_EXPANDER_PORT, MOTOR_PORT); // use this instead + * } + * \endcode + */ +int32_t ext_adi_motor_stop(uint8_t smart_port, uint8_t adi_port); + +/** + * Reference type for an initialized encoder. + * + * This merely contains the port number for the encoder. + */ +typedef int32_t ext_adi_encoder_t; + +/** + * Gets the number of ticks recorded by the encoder. + * + * There are 360 ticks in one revolution. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to read + * + * \return The signed and cumulative number of counts since the last start or + * reset + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, + * PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf(“Encoder Value: %dn”, + * ext_adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_encoder_get(ext_adi_encoder_t enc); + +/** + * Creates an encoder object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port_top + * The "top" wire from the encoder sensor with the removable cover side + * up. This should be in port 1, 3, 5, or 7 ('A', 'C', 'E', or 'G'). + * \param adi_port_bottom + * The "bottom" wire from the encoder sensor + * \param reverse + * If "true", the sensor will count in the opposite direction + * + * \return An adi_encoder_t object to be stored and used for later calls to + * encoder functions + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); + * while (true) { + * printf("Encoder Value: %d\n", ext_adi_encoder_get(enc)); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_encoder_t ext_adi_encoder_init(uint8_t smart_port, uint8_t adi_port_top, uint8_t adi_port_bottom, bool reverse); + +/** + * Sets the encoder value to zero. + * + * It is safe to use this method while an encoder is enabled. It is not + * necessary to call this method before stopping or starting an encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to reset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); + * delay(1000); // Move the encoder around in this time + * ext_adi_encoder_reset(enc); // The encoder is now zero again + * } + * \endcode + */ +int32_t ext_adi_encoder_reset(ext_adi_encoder_t enc); + +/** + * Disables the encoder and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an encoder + * + * \param enc + * The adi_encoder_t object from adi_encoder_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define ADI_EXPANDER_PORT 20 + * #define PORT_TOP 1 + * #define PORT_BOTTOM 2 + * + * void opcontrol() { + * ext_adi_encoder_t enc = ext_adi_encoder_init(ADI_EXPANDER_PORT, PORT_TOP, PORT_BOTTOM, false); + * // Use the encoder + * ext_adi_encoder_shutdown(enc); + * } + * \endcode + */ +int32_t ext_adi_encoder_shutdown(ext_adi_encoder_t enc); + +/** + * Reference type for an initialized ultrasonic. + * + * This merely contains the port number for the ultrasonic. + */ +typedef int32_t ext_adi_ultrasonic_t; + +/** + * Gets the current ultrasonic sensor value in centimeters. + * + * If no object was found, zero is returned. If the ultrasonic sensor was never + * started, the return value is undefined. Round and fluffy objects can cause + * inaccurate values to be returned. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to read + * + * \return The distance to the nearest object in m^-4 (10000 indicates 1 meter), + * measured from the sensor's mounting points. + * + * \b Example + * \code + * + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_ultrasonic_get(ext_adi_ultrasonic_t ult); + +/** + * Creates an ultrasonic object and configures the specified ports accordingly. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port_ping + * The port connected to the orange OUTPUT cable. This should be in port + * 1, 3, 5, or 7 ('A', 'C', 'E', 'G'). + * \param adi_port_echo + * The port connected to the yellow INPUT cable. This should be in the + * next highest port following port_ping. + * + * \return An adi_ultrasonic_t object to be stored and used for later calls to + * ultrasonic functions + * + * \b Example + * \code + * + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_ultrasonic_t ext_adi_ultrasonic_init(uint8_t smart_port, uint8_t adi_port_ping, uint8_t adi_port_echo); + +/** + * Disables the ultrasonic sensor and voids the configuration on its ports. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as an ultrasonic + * + * \param ult + * The adi_ultrasonic_t object from adi_ultrasonic_init() to stop + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define PORT_PING 1 + * #define PORT_ECHO 2 + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_ultrasonic_t ult = ext_adi_ultrasonic_init(ADI_EXPANDER_PORT, PORT_PING, PORT_ECHO); + * while (true) { + * // Print the distance read by the ultrasonic + * printf("Distance: %d\n", ext_adi_ultrasonic_get(ult)); + * delay(5); + * } + * ext_adi_ultrasonic_shutdown(ult); + * } + * \endcode + */ +int32_t ext_adi_ultrasonic_shutdown(ext_adi_ultrasonic_t ult); + +/** + * Reference type for an initialized gyroscope. + * + * This merely contains the port number for the gyroscope. + * + * (Might Be useless with the wire expander.) + */ +typedef int32_t ext_adi_gyro_t; + +/** + * Gets the current gyro angle in tenths of a degree. Unless a multiplier is + * applied to the gyro, the return value will be a whole number representing + * the number of degrees of rotation times 10. + * + * There are 360 degrees in a circle, thus the gyro will return 3600 for one + * whole rotation. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return The gyro angle in degrees. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +double ext_adi_gyro_get(ext_adi_gyro_t gyro); + +/** + * Initializes a gyroscope on the given port. If the given port has not + * previously been configured as a gyro, then this function starts a 1300 ms + * calibration period. + * + * It is highly recommended that this function be called from initialize() when + * the robot is stationary to ensure proper calibration. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param smart_port + * The smart port number that the ADI Expander is in + * \param adi_port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param multiplier + * A scalar value that will be multiplied by the gyro heading value + * supplied by the ADI + * + * \return An adi_gyro_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_gyro_t ext_adi_gyro_init(uint8_t smart_port, uint8_t adi_port, double multiplier); + +/** + * Resets the gyroscope value to zero. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object for which the angle will be returned + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * // Reset the gyro every 2 seconds + * ext_adi_gyro_reset(gyro); + * now = millis(); + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_gyro_reset(ext_adi_gyro_t gyro); + +/** + * Disables the gyro and voids the configuration on its port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - Either the ADI port value or the smart port value is not within its + * valid range (ADI port: 1-8, 'a'-'h', or 'A'-'H'; smart port: 1-21). + * EADDRINUSE - The port is not configured as a gyro + * + * \param gyro + * The adi_gyro_t object to be shut down + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * #define GYRO_PORT 1 + * #define GYRO_MULTIPLIER 1 // Standard behavior + * #define ADI_EXPANDER_PORT 20 + * + * void opcontrol() { + * ext_adi_gyro_t gyro = ext_adi_gyro_init(ADI_EXPANDER_PORT, GYRO_PORT, GYRO_MULTIPLIER); + * uint32_t now = millis(); + * while (true) { + * // Print the gyro's heading + * printf("Heading: %lf\n", ext_adi_gyro_get(gyro)); + * + * if (millis() - now > 2000) { + * ext_adi_gyro_shutdown(gyro); + * // Shut down the gyro after two seconds + * break; + * } + * + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_gyro_shutdown(ext_adi_gyro_t gyro); + +/** + * Reference type for an initialized potentiometer. + * + * This merely contains the port number for the potentiometer. + */ +typedef int32_t ext_adi_potentiometer_t; + +/** + * Initializes a potentiometer on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param port + * The ADI port to initialize as a gyro (from 1-8, 'a'-'h', 'A'-'H') + * \param potentiometer_type + * An adi_potentiometer_type_e_t enum value specifying the potentiometer version type + * + * \return An adi_potentiometer_t object containing the given port, or PROS_ERR if the + * initialization failed. + */ +ext_adi_potentiometer_t ext_adi_potentiometer_init(uint8_t smart_port, uint8_t adi_port, adi_potentiometer_type_e_t potentiometer_type); + +/** + * Gets the current potentiometer angle in tenths of a degree. + * + * The original potentiometer rotates 250 degrees thus returning an angle between 0-250 degrees. + * Potentiometer V2 rotates 333 degrees thus returning an angle between 0-333 degrees. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EADDRINUSE - The port is not configured as a potentiometer + * + * \param potentiometer + * The adi_potentiometer_t object for which the angle will be returned + * + * \return The potentiometer angle in degrees. + */ +double ext_adi_potentiometer_get_angle(ext_adi_potentiometer_t potentiometer); + +/** + * Reference type for an initialized addressable led. + * + * This merely contains the port number for the led, unlike its use as an + * object to store led data in the C++ API. + */ +typedef int32_t ext_adi_led_t; + +/** + * Initializes a led on the given port. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * \param smart_port + * The smart port with the adi expander (1-21) + * \param adi_port + * The ADI port to initialize as a led (from 1-8, 'a'-'h', 'A'-'H') + * + * \return An ext_adi_led_t object containing the given port, or PROS_ERR if the + * initialization failed. + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the led to colors in the buffer + * ext_adi_led_set(led, buffer, 1); + * delay(5); + * } + * } + * \endcode + */ +ext_adi_led_t ext_adi_led_init(uint8_t smart_port, uint8_t adi_port); + +/** + * @brief Clear the entire led strip of color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the led to colors in the buffer + * ext_adi_led_set(led, buffer, 1); + * delay(5); + * + * // Clear the led + * ext_adi_led_clear_all(led, buffer, 1); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_clear_all(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip using the colors contained in the buffer + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the led to colors in the buffer + * ext_adi_led_set(led, buffer, 1); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_set(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length); + +/** + * @brief Set the entire led strip to one color + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of buffer to clear + * @param color color to set all the led strip value to + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with a single color of red + * uint32_t buffer[1] = {0xFF0000}; + * + * while (true) { + * // Set the entire led strip to red + * ext_adi_led_set_all(led, buffer, 1, 0xFF0000); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_set_all(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color); + +/** + * @brief Set one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param color color to clear all the led strip to + * @param pixel_position position of the pixel to clear (0 indexed) + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with multiple colors + * uint32_t buffer[3] = {0xFF0000, 0x00FF00, 0x0000FF}; + * + * while (true) { + * // Set the first pixel to red + * ext_adi_led_set_pixel(led, buffer, 3, 0xFF0000, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_set_pixel(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t color, uint32_t pixel_position); + +/** + * @brief Clear one pixel on the led strip + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of ADI Ports + * EINVAL - A given value is not correct, or the buffer is null + * EADDRINUSE - The port is not configured for ADI output + * + * @param led port of type adi_led_t + * @param buffer array of colors in format 0xRRGGBB, recommended that individual RGB value not to exceed 0x80 due to current draw + * @param buffer_length length of the input buffer + * @param pixel_position position of the pixel to clear (0 indexed) + * @return PROS_SUCCESS if successful, PROS_ERR if not + * + * \b Example: + * \code + * #define SMART_PORT 1 + * #define ADI_PORT 'A' + * + * void opcontrol() { + * // Initialize a led on smart port 1 and adi port A + * ext_adi_led_t led = ext_adi_led_init(SMART_PORT, ADI_PORT); + * // Initialize a buffer with multiple colors + * uint32_t buffer[3] = {0xFF0000, 0x00FF00, 0x0000FF}; + * + * while (true) { + * // Set the first pixel to red + * ext_adi_led_set_pixel(led, buffer, 3, 0xFF0000, 0); + * delay(5); + * + * // Clear the first pixel + * ext_adi_led_clear_pixel(led, buffer, 3, 0); + * delay(5); + * } + * } + * \endcode + */ +int32_t ext_adi_led_clear_pixel(ext_adi_led_t led, uint32_t* buffer, uint32_t buffer_length, uint32_t pixel_position); + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_ADI_H_ diff --git a/include/pros/gps.h b/include/pros/gps.h index cc2d509..9304e0f 100644 --- a/include/pros/gps.h +++ b/include/pros/gps.h @@ -1,668 +1,668 @@ -/** - * \file pros/gps.h - * \ingroup c-gps - * - * Contains prototypes for functions related to the VEX GPS. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-gps VEX GPS Sensor C API - * \note For a pros-specific usage guide on the GPS, please check out our article [here.](@ref gps) - */ - -#ifndef _PROS_GPS_H_ -#define _PROS_GPS_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/** - * \ingroup c-gps - */ - -/** - * \addtogroup c-gps - * @{ - */ - -/** - * \struct gps_position_s_t - */ -typedef struct __attribute__((__packed__)) gps_position_s { - /// X Position (meters) - double x; - /// Y Position (meters) - double y; -} gps_position_s_t; - -/** - * \struct gps_status_s_t - */ -typedef struct __attribute__((__packed__)) gps_status_s { - /// X Position (meters) - double x; - /// Y Position (meters) - double y; - /// Percieved Pitch based on GPS + IMU - double pitch; - /// Percieved Roll based on GPS + IMU - double roll; - /// Percieved Yaw based on GPS + IMU - double yaw; -} gps_status_s_t; - -/** - * \struct gps_raw_s - */ -struct gps_raw_s { - /// Percieved Pitch based on GPS + IMU - double x; - /// Percieved Roll based on GPS + IMU - double y; - /// Percieved Yaw based on GPS + IMU - double z; -}; - -/** - * \struct gps_accel_s_t - * - */ -typedef struct gps_raw_s gps_accel_s_t; - -/** - * \struct gps_gyro_s_t - * - */ -typedef struct gps_raw_s gps_gyro_s_t; - -#ifdef __cplusplus -namespace c { -#endif - - -/** - * Set the GPS's offset relative to the center of turning in meters, - * as well as its initial position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \param xOffset - * Cartesian 4-Quadrant X offset from center of turning (meters) - * \param yOffset - * Cartesian 4-Quadrant Y offset from center of turning (meters) - * \param xInitial - * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) - * \param yInitial - * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) - * \param headingInitial - * Heading with 0 being north on the field, in degrees [0,360) going clockwise - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * #define X_OFFSET .225 - * #define Y_OFFSET .223 - * #define X_INITIAL 1.54 - * #define Y_INITIAL 1.14 - * #define HEADING_INITIAL 90 - * - * void initialize() { - * gps_initialize_full(GPS_PORT, X_OFFSET, Y_OFFSET, X_INITIAL, Y_INITIAL, HEADING_INITIAL); - * } - * \endcode - */ -int32_t gps_initialize_full(uint8_t port, double xInitial, double yInitial, double headingInitial, double xOffset, - double yOffset); - -/** - * Set the GPS's offset relative to the center of turning in meters. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \param xOffset - * Cartesian 4-Quadrant X offset from center of turning (meters) - * \param yOffset - * Cartesian 4-Quadrant Y offset from center of turning (meters) - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * #define X_OFFSET -.225 - * #define Y_OFFSET .225 - * - * void initialize() { - * gps_set_offset(GPS_PORT, X_OFFSET, Y_OFFSET); - * } - * \endcode - */ -int32_t gps_set_offset(uint8_t port, double xOffset, double yOffset); - -/** - * Gets the position and roll, yaw, and pitch of the GPS. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * - * \return A struct (gps_status_s_t) containing values mentioned above. - * If the operation failed, all the structure's members are filled with - * PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * gps_status_s_t status; - * - * while (true) { - * status = gps_get_status(GPS_PORT); - * printf("X: %f, Y: %f, Pitch: %f, Roll: %f, Yaw: %f\n", status.x, status.y, status.pitch, status.roll, status.yaw); - * delay(20); - * } - * } - * \endcode - */ -gps_status_s_t gps_get_status(uint8_t port); - -/** - * Gets the x and y position on the field of the GPS in meters. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * - * \return A struct (gps_position_s_t) containing values mentioned above. - * If the operation failed, all the structure's members are filled with - * PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * gps_position_s_t position; - * - * while (true) { - * position = gps_get_position(GPS_PORT); - * printf("X: %f, Y: %f\n", position.x, position.y); - * delay(20); - * } - * } - * \endcode - */ -gps_position_s_t gps_get_position(uint8_t port); - -/** - * Get the GPS's raw gyroscope values - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \return The raw gyroscope values. If the operation failed, all the - * structure's members are filled with PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * gps_gyro_s_t gyro; - * - * while (true) { - * gyro = gps_get_gyro(GPS_PORT); - * printf("Gyro: %f %f %f\n", gyro.x, gyro.y, gyro.z); - * delay(20); - * } - * } - * \endcode - */ -gps_gyro_s_t gps_get_gyro_rate(uint8_t port); - -/** - * Get the GPS's raw accelerometer values - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS's port number from 1-21 - * \return The raw accelerometer values. If the operation failed, all the - * structure's members are filled with PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * gps_accel_s_t accel; - * - * while (true) { - * accel = gps_get_accel(GPS_PORT); - * printf("X: %f, Y: %f, Z: %f\n", accel.x, accel.y, accel.z); - * delay(20); - * } - * } - * \endcode - */ -gps_accel_s_t gps_get_accel(uint8_t port); - -/** - * Get the GPS's cartesian location relative to the center of turning/origin in meters. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \return A struct (gps_position_s_t) containing the X and Y values if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * gps_position_s_t pos; - * - * while (true) { - * pos = gps_get_offset(GPS_PORT, x, y); - * screen_print(TEXT_MEDIUM, 1, "X Offset: %4d, Y Offset: %4d", pos.x, pos.y); - * delay(20); - * } - * } - * \endcode - */ -gps_position_s_t gps_get_offset(uint8_t port); - -/** - * Sets the robot's location relative to the center of the field in meters. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \param xInitial - * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) - * \param yInitial - * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) - * \param headingInitial - * Heading with 0 being north on the field, in degrees [0,360) going clockwise - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * #define X_INITIAL -1.15 - * #define Y_INITIAL 1.45 - * #define HEADING_INITIAL 90 - * - * void initialize() { - * gps_set_position(GPS_PORT, X_INITIAL, Y_INITIAL, HEADING_INITIAL); - * } - * \endcode - */ -int32_t gps_set_position(uint8_t port, double xInitial, double yInitial, double headingInitial); - -/** - * Set the GPS sensor's data rate in milliseconds, only applies to IMU on GPS. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \param rate - * Data rate in milliseconds (Minimum: 5 ms) - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * #define GPS_DATA_RATE 5 - * - * void initialize() { - * gps_set_data_rate(GPS_PORT, GPS_DATA_RATE); - * while (true) { - * // Do something - * } - * } - * \endcode - */ -int32_t gps_set_data_rate(uint8_t port, uint32_t rate); - -/** - * Get the possible RMS (Root Mean Squared) error in meters for GPS position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * - * \return Possible RMS (Root Mean Squared) error in meters for GPS position. - * If the operation failed, returns PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * double error; - * error = gps_get_error(GPS_PORT); - * screen_print(TEXT_MEDIUM, 1, "Error: %4d", error); - * } - * \endcode - */ -double gps_get_error(uint8_t port); - -/** - * Gets the position and roll, yaw, and pitch of the GPS. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * - * \return A struct (gps_status_s_t) containing values mentioned above. - * If the operation failed, all the structure's members are filled with - * PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * struct gps_status_s_t status; - * - * while (true) { - * status = gps_get_status(GPS_PORT); - * screen_print(TEXT_MEDIUM, 1, "x: %3f, y: %3f, pitch: %3f", status.x, status.y); - * screen_print(TEXT_MEDIUM, 2, "yaw: %3f, roll: %3f", status.pitch, status.yaw); - * screen_print(TEXT_MEDIUM, 3, "roll: %3f", status.roll); - * delay(20); - * } - * } - * \endcode - */ -gps_status_s_t gps_get_status(uint8_t port); - -/** - * Get the heading in [0,360) degree values. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * - * \return The heading in [0,360) degree values. If the operation failed, - * returns PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * double heading; - * - * while (true) { - * heading = gps_get_heading(GPS_PORT); - * delay(20); - * } - * } - * \endcode - */ -double gps_get_heading(uint8_t port); - -/** - * Get the heading in the max double value and min double value scale. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * - * \return The heading in [DOUBLE_MIN, DOUBLE_MAX] values. If the operation - * fails, returns PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * double heading; - * - * while (true) { - * heading = gps_get_heading_raw(GPS_PORT); - * delay(20); - * } - * } - * \endcode - */ -double gps_get_heading_raw(uint8_t port); - -/** - * Gets the GPS sensor's elapsed rotation value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \return The elased heading in degrees. If the operation fails, returns - * PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * double elapsed_rotation; - * - * elapsed_rotation = gps_get_rotation(GPS_PORT); - * printf("Elapsed rotation: %3f", elapsed_rotation); - * } - * \endcode - */ -double gps_get_rotation(uint8_t port); - -/** - * Set the GPS sensor's rotation value to target value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \param target - * Target rotation value to set rotation value to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * gps_set_rotation(GPS_PORT, 60); - * printf("Elapsed rotation: %3f", gps_get_rotation(GPS_PORT)); - * } - * \endcode - */ -int32_t gps_set_rotation(uint8_t port, double target); - -/** - * Tare the GPS sensor's rotation value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void initialize() { - * gps_tare_rotation(GPS_PORT); - * printf("Elapsed rotation: %3f", gps_get_rotation(GPS_PORT)); // should be 0 - * } - * \endcode - */ -int32_t gps_tare_rotation(uint8_t port); - -/** - * Get the GPS's raw gyroscope values - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS port number from 1-21 - * \return The raw gyroscope values. If the operation failed, all the - * structure's members are filled with PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * struct gps_gyro_s_t gyro; - * - * while (true) { - * gyro = gps_get_gyro_rate(GPS_PORT); - * screen_print(TEXT_MEDIUM, 1, "gyroscope- x: %3f, y: %3f, z: %3f", gyro.x, gyro.y, gyro.z); - * delay(20); - * } - * } - * \endcode - */ -gps_gyro_s_t gps_get_gyro_rate(uint8_t port); - -/** - * Get the GPS's raw accelerometer values - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an GPS - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 GPS's port number from 1-21 - * \return The raw accelerometer values. If the operation failed, all the - * structure's members are filled with PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define GPS_PORT 1 - * - * void opcontrol() { - * struct gps_accel_s_t accel; - * - * while (true) { - * accel = gps_get_accel(GPS_PORT); - * screen_print(TEXT_MEDIUM, 1, "accleration- x: %3f, y: %3f, z: %3f", accel.x, accel.y, accel.z); - * } - * } - * \endcode - */ -gps_accel_s_t gps_get_accel(uint8_t port); - -///@} - -#ifdef __cplusplus -} -} -} -#endif - -#endif +/** + * \file pros/gps.h + * \ingroup c-gps + * + * Contains prototypes for functions related to the VEX GPS. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-gps VEX GPS Sensor C API + * \note For a pros-specific usage guide on the GPS, please check out our article [here.](@ref gps) + */ + +#ifndef _PROS_GPS_H_ +#define _PROS_GPS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-gps + */ + +/** + * \addtogroup c-gps + * @{ + */ + +/** + * \struct gps_position_s_t + */ +typedef struct __attribute__((__packed__)) gps_position_s { + /// X Position (meters) + double x; + /// Y Position (meters) + double y; +} gps_position_s_t; + +/** + * \struct gps_status_s_t + */ +typedef struct __attribute__((__packed__)) gps_status_s { + /// X Position (meters) + double x; + /// Y Position (meters) + double y; + /// Percieved Pitch based on GPS + IMU + double pitch; + /// Percieved Roll based on GPS + IMU + double roll; + /// Percieved Yaw based on GPS + IMU + double yaw; +} gps_status_s_t; + +/** + * \struct gps_raw_s + */ +struct gps_raw_s { + /// Percieved Pitch based on GPS + IMU + double x; + /// Percieved Roll based on GPS + IMU + double y; + /// Percieved Yaw based on GPS + IMU + double z; +}; + +/** + * \struct gps_accel_s_t + * + */ +typedef struct gps_raw_s gps_accel_s_t; + +/** + * \struct gps_gyro_s_t + * + */ +typedef struct gps_raw_s gps_gyro_s_t; + +#ifdef __cplusplus +namespace c { +#endif + + +/** + * Set the GPS's offset relative to the center of turning in meters, + * as well as its initial position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Heading with 0 being north on the field, in degrees [0,360) going clockwise + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define X_OFFSET .225 + * #define Y_OFFSET .223 + * #define X_INITIAL 1.54 + * #define Y_INITIAL 1.14 + * #define HEADING_INITIAL 90 + * + * void initialize() { + * gps_initialize_full(GPS_PORT, X_OFFSET, Y_OFFSET, X_INITIAL, Y_INITIAL, HEADING_INITIAL); + * } + * \endcode + */ +int32_t gps_initialize_full(uint8_t port, double xInitial, double yInitial, double headingInitial, double xOffset, + double yOffset); + +/** + * Set the GPS's offset relative to the center of turning in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param xOffset + * Cartesian 4-Quadrant X offset from center of turning (meters) + * \param yOffset + * Cartesian 4-Quadrant Y offset from center of turning (meters) + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define X_OFFSET -.225 + * #define Y_OFFSET .225 + * + * void initialize() { + * gps_set_offset(GPS_PORT, X_OFFSET, Y_OFFSET); + * } + * \endcode + */ +int32_t gps_set_offset(uint8_t port, double xOffset, double yOffset); + +/** + * Gets the position and roll, yaw, and pitch of the GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return A struct (gps_status_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_status_s_t status; + * + * while (true) { + * status = gps_get_status(GPS_PORT); + * printf("X: %f, Y: %f, Pitch: %f, Roll: %f, Yaw: %f\n", status.x, status.y, status.pitch, status.roll, status.yaw); + * delay(20); + * } + * } + * \endcode + */ +gps_status_s_t gps_get_status(uint8_t port); + +/** + * Gets the x and y position on the field of the GPS in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return A struct (gps_position_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_position_s_t position; + * + * while (true) { + * position = gps_get_position(GPS_PORT); + * printf("X: %f, Y: %f\n", position.x, position.y); + * delay(20); + * } + * } + * \endcode + */ +gps_position_s_t gps_get_position(uint8_t port); + +/** + * Get the GPS's raw gyroscope values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return The raw gyroscope values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_gyro_s_t gyro; + * + * while (true) { + * gyro = gps_get_gyro(GPS_PORT); + * printf("Gyro: %f %f %f\n", gyro.x, gyro.y, gyro.z); + * delay(20); + * } + * } + * \endcode + */ +gps_gyro_s_t gps_get_gyro_rate(uint8_t port); + +/** + * Get the GPS's raw accelerometer values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS's port number from 1-21 + * \return The raw accelerometer values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_accel_s_t accel; + * + * while (true) { + * accel = gps_get_accel(GPS_PORT); + * printf("X: %f, Y: %f, Z: %f\n", accel.x, accel.y, accel.z); + * delay(20); + * } + * } + * \endcode + */ +gps_accel_s_t gps_get_accel(uint8_t port); + +/** + * Get the GPS's cartesian location relative to the center of turning/origin in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return A struct (gps_position_s_t) containing the X and Y values if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_position_s_t pos; + * + * while (true) { + * pos = gps_get_offset(GPS_PORT, x, y); + * screen_print(TEXT_MEDIUM, 1, "X Offset: %4d, Y Offset: %4d", pos.x, pos.y); + * delay(20); + * } + * } + * \endcode + */ +gps_position_s_t gps_get_offset(uint8_t port); + +/** + * Sets the robot's location relative to the center of the field in meters. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param xInitial + * Initial 4-Quadrant X Position, with (0,0) being at the center of the field (meters) + * \param yInitial + * Initial 4-Quadrant Y Position, with (0,0) being at the center of the field (meters) + * \param headingInitial + * Heading with 0 being north on the field, in degrees [0,360) going clockwise + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define X_INITIAL -1.15 + * #define Y_INITIAL 1.45 + * #define HEADING_INITIAL 90 + * + * void initialize() { + * gps_set_position(GPS_PORT, X_INITIAL, Y_INITIAL, HEADING_INITIAL); + * } + * \endcode + */ +int32_t gps_set_position(uint8_t port, double xInitial, double yInitial, double headingInitial); + +/** + * Set the GPS sensor's data rate in milliseconds, only applies to IMU on GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param rate + * Data rate in milliseconds (Minimum: 5 ms) + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * #define GPS_DATA_RATE 5 + * + * void initialize() { + * gps_set_data_rate(GPS_PORT, GPS_DATA_RATE); + * while (true) { + * // Do something + * } + * } + * \endcode + */ +int32_t gps_set_data_rate(uint8_t port, uint32_t rate); + +/** + * Get the possible RMS (Root Mean Squared) error in meters for GPS position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return Possible RMS (Root Mean Squared) error in meters for GPS position. + * If the operation failed, returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double error; + * error = gps_get_error(GPS_PORT); + * screen_print(TEXT_MEDIUM, 1, "Error: %4d", error); + * } + * \endcode + */ +double gps_get_error(uint8_t port); + +/** + * Gets the position and roll, yaw, and pitch of the GPS. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return A struct (gps_status_s_t) containing values mentioned above. + * If the operation failed, all the structure's members are filled with + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * struct gps_status_s_t status; + * + * while (true) { + * status = gps_get_status(GPS_PORT); + * screen_print(TEXT_MEDIUM, 1, "x: %3f, y: %3f, pitch: %3f", status.x, status.y); + * screen_print(TEXT_MEDIUM, 2, "yaw: %3f, roll: %3f", status.pitch, status.yaw); + * screen_print(TEXT_MEDIUM, 3, "roll: %3f", status.roll); + * delay(20); + * } + * } + * \endcode + */ +gps_status_s_t gps_get_status(uint8_t port); + +/** + * Get the heading in [0,360) degree values. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The heading in [0,360) degree values. If the operation failed, + * returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double heading; + * + * while (true) { + * heading = gps_get_heading(GPS_PORT); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_heading(uint8_t port); + +/** + * Get the heading in the max double value and min double value scale. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * + * \return The heading in [DOUBLE_MIN, DOUBLE_MAX] values. If the operation + * fails, returns PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double heading; + * + * while (true) { + * heading = gps_get_heading_raw(GPS_PORT); + * delay(20); + * } + * } + * \endcode + */ +double gps_get_heading_raw(uint8_t port); + +/** + * Gets the GPS sensor's elapsed rotation value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return The elased heading in degrees. If the operation fails, returns + * PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * double elapsed_rotation; + * + * elapsed_rotation = gps_get_rotation(GPS_PORT); + * printf("Elapsed rotation: %3f", elapsed_rotation); + * } + * \endcode + */ +double gps_get_rotation(uint8_t port); + +/** + * Set the GPS sensor's rotation value to target value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \param target + * Target rotation value to set rotation value to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * gps_set_rotation(GPS_PORT, 60); + * printf("Elapsed rotation: %3f", gps_get_rotation(GPS_PORT)); + * } + * \endcode + */ +int32_t gps_set_rotation(uint8_t port, double target); + +/** + * Tare the GPS sensor's rotation value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void initialize() { + * gps_tare_rotation(GPS_PORT); + * printf("Elapsed rotation: %3f", gps_get_rotation(GPS_PORT)); // should be 0 + * } + * \endcode + */ +int32_t gps_tare_rotation(uint8_t port); + +/** + * Get the GPS's raw gyroscope values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS port number from 1-21 + * \return The raw gyroscope values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * struct gps_gyro_s_t gyro; + * + * while (true) { + * gyro = gps_get_gyro_rate(GPS_PORT); + * screen_print(TEXT_MEDIUM, 1, "gyroscope- x: %3f, y: %3f, z: %3f", gyro.x, gyro.y, gyro.z); + * delay(20); + * } + * } + * \endcode + */ +gps_gyro_s_t gps_get_gyro_rate(uint8_t port); + +/** + * Get the GPS's raw accelerometer values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an GPS + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 GPS's port number from 1-21 + * \return The raw accelerometer values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define GPS_PORT 1 + * + * void opcontrol() { + * struct gps_accel_s_t accel; + * + * while (true) { + * accel = gps_get_accel(GPS_PORT); + * screen_print(TEXT_MEDIUM, 1, "accleration- x: %3f, y: %3f, z: %3f", accel.x, accel.y, accel.z); + * } + * } + * \endcode + */ +gps_accel_s_t gps_get_accel(uint8_t port); + +///@} + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/include/pros/imu.h b/include/pros/imu.h index 15177f0..bf724ab 100644 --- a/include/pros/imu.h +++ b/include/pros/imu.h @@ -1,947 +1,947 @@ -/** - * \file pros/imu.h - * \ingroup c-imu - * - * Contains prototypes for functions related to the VEX Inertial sensor. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-imu VEX Inertial Sensor C API - */ - -#ifndef _PROS_IMU_H_ -#define _PROS_IMU_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/** - * \ingroup c-imu - * */ - -/** - * \addtogroup c-imu - * @{ - */ - -/** - * \enum imu_status_e_t - * @brief Indicates IMU status. - */ -typedef enum imu_status_e { - /** The IMU is calibrating */ - E_IMU_STATUS_CALIBRATING = 0x01, - /** Used to indicate that an error state was reached in the imu_get_status function,\ - not that the IMU is necessarily in an error state */ - E_IMU_STATUS_ERROR = 0xFF, -} imu_status_e_t; - -/** - * \struct quaternion_s_t - */ -typedef struct __attribute__((__packed__)) quaternion_s { - double x; - double y; - double z; - double w; -} quaternion_s_t; - -/** - * \struct imu_raw_s - * - */ -struct imu_raw_s { - double x; - double y; - double z; -}; - -/** - * \struct imu_gyro_s_t - * - */ -typedef struct imu_raw_s imu_gyro_s_t; - -/** - * \struct imu_accel_s_t - * - */ -typedef struct imu_raw_s imu_accel_s_t; - -/** - * \struct euler_s_t - * - */ -typedef struct __attribute__((__packed__)) euler_s { - double pitch; - double roll; - double yaw; -} euler_s_t; - -#ifdef __cplusplus -namespace c { -#endif -/** - * \def IMU_MINIMUM_DATA_RATE - */ -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define IMU_STATUS_CALIBRATING pros::E_IMU_STATUS_CALIBRATING -#define IMU_STATUS_ERROR pros::E_IMU_STATUS_ERROR -#else -#define IMU_STATUS_CALIBRATING E_IMU_STATUS_CALIBRATING -#define IMU_STATUS_ERROR E_IMU_STATUS_ERROR -#endif -#endif - -#define IMU_MINIMUM_DATA_RATE 5 - -/** - * Calibrate IMU - * - * Calibration takes approximately 2 seconds, but this function only blocks - * until the IMU status flag is set properly to E_IMU_STATUS_CALIBRATING, - * with a minimum blocking time of 5ms. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is already calibrating, or time out setting the status flag. - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void initialize() { - * imu_reset(IMU_PORT); - * int time = millis(); - * int iter = 0; - * while (imu_get_status(IMU_PORT) & E_IMU_STATUS_CALIBRATING) { - * printf("IMU calibrating... %d\n", iter); - * iter += 10; - * delay(10); - * } - * // should print about 2000 ms - * printf("IMU is done calibrating (took %d ms)\n", iter - time); - * } - * \endcode - */ -int32_t imu_reset(uint8_t port); - -/** - * Calibrate IMU and Blocks while Calibrating - * - * Calibration takes approximately 2 seconds and blocks during this period, - * with a timeout for this operation being set a 3 seconds as a safety margin. - * Like the other reset function, this function also blocks until the IMU - * status flag is set properly to E_IMU_STATUS_CALIBRATING, with a minimum - * blocking time of 5ms and a timeout of 1 second if it's never set. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is already calibrating, or time out setting the status flag. - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed (timing out or port claim failure), setting errno. - */ -int32_t imu_reset_blocking(uint8_t port); -/** - * Set the Inertial Sensor's refresh interval in milliseconds. - * - * The rate may be specified in increments of 5ms, and will be rounded down to - * the nearest increment. The minimum allowable refresh rate is 5ms. The default - * rate is 10ms. - * - * As values are copied into the shared memory buffer only at 10ms intervals, - * setting this value to less than 10ms does not mean that you can poll the - * sensor's values any faster. However, it will guarantee that the data is as - * recent as possible. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param rate The data refresh interval in milliseconds - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * - * \endcode - */ -int32_t imu_set_data_rate(uint8_t port, uint32_t rate); - -/** - * Get the total number of degrees the Inertial Sensor has spun about the z-axis - * - * This value is theoretically unbounded. Clockwise rotations are represented - * with positive degree values, while counterclockwise rotations are represented - * with negative ones. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The degree value or PROS_ERR_F if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("IMU get rotation: %f degrees\n", imu_get_rotation(IMU_PORT)); - * delay(20); - * } - * } - * \endcode - */ -double imu_get_rotation(uint8_t port); - -/** - * Get the Inertial Sensor's heading relative to the initial direction of its - * x-axis - * - * This value is bounded by [0,360). Clockwise rotations are represented with - * positive degree values, while counterclockwise rotations are represented with - * negative ones. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The degree value or PROS_ERR_F if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("IMU get heading: %f degrees\n", imu_get_heading(IMU_PORT)); - * delay(20); - * } - * } - * \endcode - */ -double imu_get_heading(uint8_t port); - -/** - * Get a quaternion representing the Inertial Sensor's orientation - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The quaternion representing the sensor's orientation. If the - * operation failed, all the quaternion's members are filled with PROS_ERR_F and - * errno is set. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * quaternion_s_t qt = imu_get_quaternion(IMU_PORT); - * printf("IMU quaternion: {x: %f, y: %f, z: %f, w: %f}\n", qt.x, qt.y, qt.z, qt.w); - * delay(20); - * } - * } - * \endcode - */ -quaternion_s_t imu_get_quaternion(uint8_t port); - -/** - * Get the Euler angles representing the Inertial Sensor's orientation - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The Euler angles representing the sensor's orientation. If the - * operation failed, all the structure's members are filled with PROS_ERR_F and - * errno is set. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * euler_s_t eu = imu_get_euler(IMU_PORT); - * printf("IMU euler angles: {pitch: %f, roll: %f, yaw: %f}\n", eu.pitch, eu.roll, eu.yaw); - * delay(20); - * } - * } - * \endcode - */ -euler_s_t imu_get_euler(uint8_t port); - -/** - * Get the Inertial Sensor's raw gyroscope values - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The pitch angle, or PROS_ERR_F if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("IMU pitch: %f\n", imu_get_pitch(IMU_PORT)); - * delay(20); - * } - * } - * \endcode - */ -imu_gyro_s_t imu_get_gyro_rate(uint8_t port); - -/** - * Get the Inertial Sensor's raw acceleroneter values - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The roll angle, or PROS_ERR_F if the operation failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("IMU roll: %f\n", imu_get_roll(IMU_PORT)); - * delay(20); - * } - * } - * \endcode - */ -imu_accel_s_t imu_get_accel(uint8_t port); - -/** - * Get the Inertial Sensor's status - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("IMU yaw: %f\n", imu_get_yaw(IMU_PORT)); - * delay(20); - * } - * } - * \endcode - */ -imu_status_e_t imu_get_status(uint8_t port); - -// Value set functions: -/** - * Sets the current reading of the Inertial Sensor's euler values to - * target euler values. Will default to +/- 180 if target exceeds +/- 180. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The raw gyroscope values. If the operation failed, all the - * structure's members are filled with PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * int32_t val = imu_set_euler(IMU_PORT, {45, 60, 90}); - * printf("IMU : {gyro vals: %d}\n", val); - * delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_euler(uint8_t port, euler_s_t target); - -/** - * Get the Inertial Sensor's pitch angle bounded by (-180,180) - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The raw accelerometer values. If the operation failed, all the - * structure's members are filled with PROS_ERR_F and errno is set. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * imu_accel_s_t accel = imu_get_accel(IMU_PORT); - * printf("IMU accel values: {x: %f, y: %f, z: %f}\n", accel.x, accel.y, accel.z); - * delay(20); - * } - * } - * \endcode - */ -double imu_get_pitch(uint8_t port); - -/** - * Get the Inertial Sensor's roll angle bounded by (-180,180) - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The Inertial Sensor's status code, or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void initialize() { - * imu_reset(IMU_PORT); - * int time = millis(); - * int iter = 0; - * while (imu_get_status(IMU_PORT) & E_IMU_STATUS_CALIBRATING) { - * printf("IMU calibrating... %d\n", iter); - * iter += 10; - * delay(10); - * } - * // should print about 2000 ms - * printf("IMU is done calibrating (took %d ms)\n", iter - time); - * } - * \endcode - */ -double imu_get_roll(uint8_t port); - -/** - * Get the Inertial Sensor's yaw angle bounded by (-180,180) - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. - */ -double imu_get_yaw(uint8_t port); - -// NOTE: not used -// void imu_set_mode(uint8_t port, uint32_t mode); -// uint32_t imu_get_mode(uint8_t port); - -/** - * \name Value Reset Functions - * @{ - */ - -/** - * Resets the current reading of the Inertial Sensor's heading to zero - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare_heading(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare_heading(uint8_t port); - -/** - * Resets the current reading of the Inertial Sensor's rotation to zero - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare_rotation(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare_rotation(uint8_t port); - -/** - * Resets the current reading of the Inertial Sensor's pitch to zero - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare_pitch(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare_pitch(uint8_t port); - -/** - * Resets the current reading of the Inertial Sensor's roll to zero - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare_roll(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare_roll(uint8_t port); - -/** - * Resets the current reading of the Inertial Sensor's yaw to zero - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare_yaw(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare_yaw(uint8_t port); - -/** - * Reset all 3 euler values of the Inertial Sensor to 0. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare_euler(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare_euler(uint8_t port); - -/** - * Resets all 5 values of the Inertial Sensor to 0. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_tare(IMU_PORT); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_tare(uint8_t port); - -/** @} */ - -/** - * \name Value Set Functions - * @{ - */ - -/** - * Sets the current reading of the Inertial Sensor's euler values to - * target euler values. Will default to +/- 180 if target exceeds +/- 180. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param target - * Target euler values for the euler values to be set to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_set_euler(IMU_PORT, {45,45,45}); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_euler(uint8_t port, euler_s_t target); - -/** - * Sets the current reading of the Inertial Sensor's rotation to target value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param target - * Target value for the rotation value to be set to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_set_rotation(IMU_PORT, 45); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_rotation(uint8_t port, double target); - -/** - * Sets the current reading of the Inertial Sensor's heading to target value - * Target will default to 360 if above 360 and default to 0 if below 0. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param target - * Target value for the heading value to be set to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_set_heading(IMU_PORT, 45); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_heading(uint8_t port, double target); - -/** - * Sets the current reading of the Inertial Sensor's pitch to target value - * Will default to +/- 180 if target exceeds +/- 180. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param target - * Target value for the pitch value to be set to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_set_pitch(IMU_PORT, 45); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_pitch(uint8_t port, double target); - -/** - * Sets the current reading of the Inertial Sensor's roll to target value - * Will default to +/- 180 if target exceeds +/- 180. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param target - * Target value for the roll value to be set to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1 - * - * void opcontrol() { - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_set_roll(IMU_PORT, 45); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_roll(uint8_t port, double target); - -/** - * Sets the current reading of the Inertial Sensor's yaw to target value - * Will default to +/- 180 if target exceeds +/- 180. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Inertial Sensor - * EAGAIN - The sensor is still calibrating - * - * \param port - * The V5 Inertial Sensor port number from 1-21 - * \param target - * Target value for the yaw value to be set to - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define IMU_PORT 1void opcontrol() { - * - * while (true) { - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * imu_set_yaw(IMU_PORT, 45); - * } - * pros::delay(20); - * } - * } - * \endcode - */ -int32_t imu_set_yaw(uint8_t port, double target); - -/** @} */ - -/** @} */ - -#ifdef __cplusplus -} -} -} -#endif - -#endif +/** + * \file pros/imu.h + * \ingroup c-imu + * + * Contains prototypes for functions related to the VEX Inertial sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-imu VEX Inertial Sensor C API + */ + +#ifndef _PROS_IMU_H_ +#define _PROS_IMU_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-imu + * */ + +/** + * \addtogroup c-imu + * @{ + */ + +/** + * \enum imu_status_e_t + * @brief Indicates IMU status. + */ +typedef enum imu_status_e { + /** The IMU is calibrating */ + E_IMU_STATUS_CALIBRATING = 0x01, + /** Used to indicate that an error state was reached in the imu_get_status function,\ + not that the IMU is necessarily in an error state */ + E_IMU_STATUS_ERROR = 0xFF, +} imu_status_e_t; + +/** + * \struct quaternion_s_t + */ +typedef struct __attribute__((__packed__)) quaternion_s { + double x; + double y; + double z; + double w; +} quaternion_s_t; + +/** + * \struct imu_raw_s + * + */ +struct imu_raw_s { + double x; + double y; + double z; +}; + +/** + * \struct imu_gyro_s_t + * + */ +typedef struct imu_raw_s imu_gyro_s_t; + +/** + * \struct imu_accel_s_t + * + */ +typedef struct imu_raw_s imu_accel_s_t; + +/** + * \struct euler_s_t + * + */ +typedef struct __attribute__((__packed__)) euler_s { + double pitch; + double roll; + double yaw; +} euler_s_t; + +#ifdef __cplusplus +namespace c { +#endif +/** + * \def IMU_MINIMUM_DATA_RATE + */ +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define IMU_STATUS_CALIBRATING pros::E_IMU_STATUS_CALIBRATING +#define IMU_STATUS_ERROR pros::E_IMU_STATUS_ERROR +#else +#define IMU_STATUS_CALIBRATING E_IMU_STATUS_CALIBRATING +#define IMU_STATUS_ERROR E_IMU_STATUS_ERROR +#endif +#endif + +#define IMU_MINIMUM_DATA_RATE 5 + +/** + * Calibrate IMU + * + * Calibration takes approximately 2 seconds, but this function only blocks + * until the IMU status flag is set properly to E_IMU_STATUS_CALIBRATING, + * with a minimum blocking time of 5ms. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is already calibrating, or time out setting the status flag. + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void initialize() { + * imu_reset(IMU_PORT); + * int time = millis(); + * int iter = 0; + * while (imu_get_status(IMU_PORT) & E_IMU_STATUS_CALIBRATING) { + * printf("IMU calibrating... %d\n", iter); + * iter += 10; + * delay(10); + * } + * // should print about 2000 ms + * printf("IMU is done calibrating (took %d ms)\n", iter - time); + * } + * \endcode + */ +int32_t imu_reset(uint8_t port); + +/** + * Calibrate IMU and Blocks while Calibrating + * + * Calibration takes approximately 2 seconds and blocks during this period, + * with a timeout for this operation being set a 3 seconds as a safety margin. + * Like the other reset function, this function also blocks until the IMU + * status flag is set properly to E_IMU_STATUS_CALIBRATING, with a minimum + * blocking time of 5ms and a timeout of 1 second if it's never set. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is already calibrating, or time out setting the status flag. + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed (timing out or port claim failure), setting errno. + */ +int32_t imu_reset_blocking(uint8_t port); +/** + * Set the Inertial Sensor's refresh interval in milliseconds. + * + * The rate may be specified in increments of 5ms, and will be rounded down to + * the nearest increment. The minimum allowable refresh rate is 5ms. The default + * rate is 10ms. + * + * As values are copied into the shared memory buffer only at 10ms intervals, + * setting this value to less than 10ms does not mean that you can poll the + * sensor's values any faster. However, it will guarantee that the data is as + * recent as possible. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param rate The data refresh interval in milliseconds + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * + * \endcode + */ +int32_t imu_set_data_rate(uint8_t port, uint32_t rate); + +/** + * Get the total number of degrees the Inertial Sensor has spun about the z-axis + * + * This value is theoretically unbounded. Clockwise rotations are represented + * with positive degree values, while counterclockwise rotations are represented + * with negative ones. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The degree value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU get rotation: %f degrees\n", imu_get_rotation(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double imu_get_rotation(uint8_t port); + +/** + * Get the Inertial Sensor's heading relative to the initial direction of its + * x-axis + * + * This value is bounded by [0,360). Clockwise rotations are represented with + * positive degree values, while counterclockwise rotations are represented with + * negative ones. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The degree value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU get heading: %f degrees\n", imu_get_heading(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double imu_get_heading(uint8_t port); + +/** + * Get a quaternion representing the Inertial Sensor's orientation + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The quaternion representing the sensor's orientation. If the + * operation failed, all the quaternion's members are filled with PROS_ERR_F and + * errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * quaternion_s_t qt = imu_get_quaternion(IMU_PORT); + * printf("IMU quaternion: {x: %f, y: %f, z: %f, w: %f}\n", qt.x, qt.y, qt.z, qt.w); + * delay(20); + * } + * } + * \endcode + */ +quaternion_s_t imu_get_quaternion(uint8_t port); + +/** + * Get the Euler angles representing the Inertial Sensor's orientation + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The Euler angles representing the sensor's orientation. If the + * operation failed, all the structure's members are filled with PROS_ERR_F and + * errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * euler_s_t eu = imu_get_euler(IMU_PORT); + * printf("IMU euler angles: {pitch: %f, roll: %f, yaw: %f}\n", eu.pitch, eu.roll, eu.yaw); + * delay(20); + * } + * } + * \endcode + */ +euler_s_t imu_get_euler(uint8_t port); + +/** + * Get the Inertial Sensor's raw gyroscope values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The pitch angle, or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU pitch: %f\n", imu_get_pitch(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +imu_gyro_s_t imu_get_gyro_rate(uint8_t port); + +/** + * Get the Inertial Sensor's raw acceleroneter values + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The roll angle, or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU roll: %f\n", imu_get_roll(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +imu_accel_s_t imu_get_accel(uint8_t port); + +/** + * Get the Inertial Sensor's status + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("IMU yaw: %f\n", imu_get_yaw(IMU_PORT)); + * delay(20); + * } + * } + * \endcode + */ +imu_status_e_t imu_get_status(uint8_t port); + +// Value set functions: +/** + * Sets the current reading of the Inertial Sensor's euler values to + * target euler values. Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The raw gyroscope values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * int32_t val = imu_set_euler(IMU_PORT, {45, 60, 90}); + * printf("IMU : {gyro vals: %d}\n", val); + * delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_euler(uint8_t port, euler_s_t target); + +/** + * Get the Inertial Sensor's pitch angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The raw accelerometer values. If the operation failed, all the + * structure's members are filled with PROS_ERR_F and errno is set. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * imu_accel_s_t accel = imu_get_accel(IMU_PORT); + * printf("IMU accel values: {x: %f, y: %f, z: %f}\n", accel.x, accel.y, accel.z); + * delay(20); + * } + * } + * \endcode + */ +double imu_get_pitch(uint8_t port); + +/** + * Get the Inertial Sensor's roll angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The Inertial Sensor's status code, or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void initialize() { + * imu_reset(IMU_PORT); + * int time = millis(); + * int iter = 0; + * while (imu_get_status(IMU_PORT) & E_IMU_STATUS_CALIBRATING) { + * printf("IMU calibrating... %d\n", iter); + * iter += 10; + * delay(10); + * } + * // should print about 2000 ms + * printf("IMU is done calibrating (took %d ms)\n", iter - time); + * } + * \endcode + */ +double imu_get_roll(uint8_t port); + +/** + * Get the Inertial Sensor's yaw angle bounded by (-180,180) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return The yaw angle, or PROS_ERR_F if the operation failed, setting errno. + */ +double imu_get_yaw(uint8_t port); + +// NOTE: not used +// void imu_set_mode(uint8_t port, uint32_t mode); +// uint32_t imu_get_mode(uint8_t port); + +/** + * \name Value Reset Functions + * @{ + */ + +/** + * Resets the current reading of the Inertial Sensor's heading to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_heading(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_heading(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's rotation to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_rotation(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_rotation(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's pitch to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_pitch(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_pitch(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's roll to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_roll(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_roll(uint8_t port); + +/** + * Resets the current reading of the Inertial Sensor's yaw to zero + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_yaw(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_yaw(uint8_t port); + +/** + * Reset all 3 euler values of the Inertial Sensor to 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare_euler(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare_euler(uint8_t port); + +/** + * Resets all 5 values of the Inertial Sensor to 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_tare(IMU_PORT); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_tare(uint8_t port); + +/** @} */ + +/** + * \name Value Set Functions + * @{ + */ + +/** + * Sets the current reading of the Inertial Sensor's euler values to + * target euler values. Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target euler values for the euler values to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_euler(IMU_PORT, {45,45,45}); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_euler(uint8_t port, euler_s_t target); + +/** + * Sets the current reading of the Inertial Sensor's rotation to target value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the rotation value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_rotation(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_rotation(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's heading to target value + * Target will default to 360 if above 360 and default to 0 if below 0. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the heading value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_heading(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_heading(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's pitch to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the pitch value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_pitch(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_pitch(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's roll to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the roll value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1 + * + * void opcontrol() { + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_roll(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_roll(uint8_t port, double target); + +/** + * Sets the current reading of the Inertial Sensor's yaw to target value + * Will default to +/- 180 if target exceeds +/- 180. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Inertial Sensor + * EAGAIN - The sensor is still calibrating + * + * \param port + * The V5 Inertial Sensor port number from 1-21 + * \param target + * Target value for the yaw value to be set to + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define IMU_PORT 1void opcontrol() { + * + * while (true) { + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * imu_set_yaw(IMU_PORT, 45); + * } + * pros::delay(20); + * } + * } + * \endcode + */ +int32_t imu_set_yaw(uint8_t port, double target); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/include/pros/llemu.h b/include/pros/llemu.h index 6978ebc..868cd73 100644 --- a/include/pros/llemu.h +++ b/include/pros/llemu.h @@ -1,52 +1,54 @@ -#ifndef _PROS_LLEMU_H_ -#define _PROS_LLEMU_H_ - -// TODO:? Should there be weak symbols for the C api in here as well? - -#include "stdint.h" - -/******************************************************************************/ -/** LLEMU Conditional Include **/ -/** **/ -/** When the libvgl versions of llemu.h is present, common.mk will **/ -/** define a macro which lets this file know that liblvgl's llemu.h is **/ -/** present. If it is, we conditionally include it so that it gets **/ -/** included into api.h. **/ -/******************************************************************************/ -#ifdef _PROS_INCLUDE_LIBLVGL_LLEMU_H -#include "liblvgl/llemu.h" -#endif - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif //__cplusplus - -/** - * Displays a formatted string on the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line on which to display the text [0-7] - * \param fmt - * Format string - * \param ... - * Optional list of arguments for the format string - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - */ -bool __attribute__((weak)) lcd_print(int16_t line, const char *fmt, ...) { return false; } - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} // extern "C" -#endif //__cplusplus - -#endif // _PROS_LLEMU_H_ +#ifndef _PROS_LLEMU_H_ +#define _PROS_LLEMU_H_ + +// TODO:? Should there be weak symbols for the C api in here as well? + +#include "stdint.h" + +/******************************************************************************/ +/** LLEMU Conditional Include **/ +/** **/ +/** When the libvgl versions of llemu.h is present, common.mk will **/ +/** define a macro which lets this file know that liblvgl's llemu.h is **/ +/** present. If it is, we conditionally include it so that it gets **/ +/** included into api.h. **/ +/******************************************************************************/ +#ifdef _PROS_INCLUDE_LIBLVGL_LLEMU_H +#include "liblvgl/llemu.h" +#endif + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif//__cplusplus + +/** + * Displays a formatted string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param fmt + * Format string + * \param ... + * Optional list of arguments for the format string + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + */ +bool __attribute__((weak)) lcd_print(int16_t line, const char* fmt, ...) { + return false; +} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} // extern "C" +#endif//__cplusplus + +#endif // _PROS_LLEMU_H_ diff --git a/include/pros/llemu.hpp b/include/pros/llemu.hpp index 667edbc..4f75d6c 100644 --- a/include/pros/llemu.hpp +++ b/include/pros/llemu.hpp @@ -1,138 +1,138 @@ -/** - * \file pros/llemu.hpp - * \ingroup cpp-llemu - * - * Legacy LCD Emulator - * - * \details This file defines a high-level API for emulating the three-button, UART-based - * VEX LCD, containing a set of functions that facilitate the use of a software- - * emulated version of the classic VEX LCD module. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef _PROS_LLEMU_HPP_ -#define _PROS_LLEMU_HPP_ - -#include -#include - -/******************************************************************************/ -/** LLEMU Conditional Include **/ -/** **/ -/** When the libvgl versions of llemu.hpp is present, common.mk will **/ -/** define a macro which lets this file know that liblvgl's llemu.hpp is **/ -/** present. If it is, we conditionally include it so that it gets **/ -/** included into api.h. **/ -/******************************************************************************/ -#ifdef _PROS_INCLUDE_LIBLVGL_LLEMU_HPP -#include "liblvgl/llemu.hpp" -#endif - -/******************************************************************************/ -/** LLEMU Weak Stubs **/ -/** **/ -/** These functions allow main.cpp to be compiled without LVGL present **/ -/******************************************************************************/ - -namespace pros { - -/** - * \ingroup cpp-llemu - */ -namespace lcd { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-function" - namespace { - template - T convert_args(T arg) { - return arg; - } - const char* convert_args(const std::string& arg) { - return arg.c_str(); - } - } // namespace - #pragma GCC diagnostic pop - - using lcd_btn_cb_fn_t = void (*)(void); - - /* - * These weak symbols allow the example main.cpp in to compile even when - * the liblvgl template is missing from the project. - * - * For documentation on these functions, please see the doxygen comments for - * these functions in the libvgl llemu headers. - */ - - extern __attribute__((weak)) bool set_text(std::int16_t line, std::string text); - extern __attribute__((weak)) bool clear_line(std::int16_t line); - extern __attribute__((weak)) bool initialize(void); - extern __attribute__((weak)) std::uint8_t read_buttons(void); - extern __attribute__((weak)) void register_btn1_cb(lcd_btn_cb_fn_t cb); - extern __attribute__((weak)) bool is_initialized(void); - - /** - * \addtogroup cpp-llemu - * @{ - */ - - /* - * Note: This template resides in this file since the - */ - - /** - * Displays a formatted string on the emulated three-button LCD screen. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. - * EINVAL - The line number specified is not in the range [0-7] - * - * \param line - * The line on which to display the text [0-7] - * \param fmt - * Format string - * \param ...args - * Optional list of arguments for the format string - * - * \return True if the operation was successful, or false otherwise, setting - * errno values as specified above. - * - * \b Example - * \code - * #include "pros/llemu.hpp" - * - * void initialize() { - * pros::lcd::initialize(); - * pros::lcd::print(0, "My formatted text: %d!", 2); - * } - * \endcode - */ - template - bool print(std::int16_t line, const char* fmt, Params... args) { - return pros::c::lcd_print(line, fmt, convert_args(args)...); - } - - #ifndef LCD_BTN_LEFT - #define LCD_BTN_LEFT 4 - #endif - - #ifndef LCD_BTN_CENTER - #define LCD_BTN_CENTER 2 - #endif - - #ifndef LCD_BTN_RIGHT - #define LCD_BTN_RIGHT 1 - #endif - /// @} -} // namespace lcd -} // namespace pros - -#endif // _PROS_LLEMU_HPP_ +/** + * \file pros/llemu.hpp + * \ingroup cpp-llemu + * + * Legacy LCD Emulator + * + * \details This file defines a high-level API for emulating the three-button, UART-based + * VEX LCD, containing a set of functions that facilitate the use of a software- + * emulated version of the classic VEX LCD module. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PROS_LLEMU_HPP_ +#define _PROS_LLEMU_HPP_ + +#include +#include + +/******************************************************************************/ +/** LLEMU Conditional Include **/ +/** **/ +/** When the libvgl versions of llemu.hpp is present, common.mk will **/ +/** define a macro which lets this file know that liblvgl's llemu.hpp is **/ +/** present. If it is, we conditionally include it so that it gets **/ +/** included into api.h. **/ +/******************************************************************************/ +#ifdef _PROS_INCLUDE_LIBLVGL_LLEMU_HPP +#include "liblvgl/llemu.hpp" +#endif + +/******************************************************************************/ +/** LLEMU Weak Stubs **/ +/** **/ +/** These functions allow main.cpp to be compiled without LVGL present **/ +/******************************************************************************/ + +namespace pros { + +/** + * \ingroup cpp-llemu + */ +namespace lcd { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + namespace { + template + T convert_args(T arg) { + return arg; + } + const char* convert_args(const std::string& arg) { + return arg.c_str(); + } + } // namespace + #pragma GCC diagnostic pop + + using lcd_btn_cb_fn_t = void (*)(void); + + /* + * These weak symbols allow the example main.cpp in to compile even when + * the liblvgl template is missing from the project. + * + * For documentation on these functions, please see the doxygen comments for + * these functions in the libvgl llemu headers. + */ + + extern __attribute__((weak)) bool set_text(std::int16_t line, std::string text); + extern __attribute__((weak)) bool clear_line(std::int16_t line); + extern __attribute__((weak)) bool initialize(void); + extern __attribute__((weak)) std::uint8_t read_buttons(void); + extern __attribute__((weak)) void register_btn1_cb(lcd_btn_cb_fn_t cb); + extern __attribute__((weak)) bool is_initialized(void); + + /** + * \addtogroup cpp-llemu + * @{ + */ + + /* + * Note: This template resides in this file since the + */ + + /** + * Displays a formatted string on the emulated three-button LCD screen. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The LCD has not been initialized. Call lcd_initialize() first. + * EINVAL - The line number specified is not in the range [0-7] + * + * \param line + * The line on which to display the text [0-7] + * \param fmt + * Format string + * \param ...args + * Optional list of arguments for the format string + * + * \return True if the operation was successful, or false otherwise, setting + * errno values as specified above. + * + * \b Example + * \code + * #include "pros/llemu.hpp" + * + * void initialize() { + * pros::lcd::initialize(); + * pros::lcd::print(0, "My formatted text: %d!", 2); + * } + * \endcode + */ + template + bool print(std::int16_t line, const char* fmt, Params... args) { + return pros::c::lcd_print(line, fmt, convert_args(args)...); + } + + #ifndef LCD_BTN_LEFT + #define LCD_BTN_LEFT 4 + #endif + + #ifndef LCD_BTN_CENTER + #define LCD_BTN_CENTER 2 + #endif + + #ifndef LCD_BTN_RIGHT + #define LCD_BTN_RIGHT 1 + #endif + /// @} +} // namespace lcd +} // namespace pros + +#endif // _PROS_LLEMU_HPP_ diff --git a/include/pros/misc.h b/include/pros/misc.h index 3c878ac..d0ad676 100644 --- a/include/pros/misc.h +++ b/include/pros/misc.h @@ -1,756 +1,756 @@ -/** - * \file pros/misc.h - * \ingroup c-misc - * - * Contains prototypes for miscellaneous functions pertaining to the controller, - * battery, and competition control. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reservered. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-misc Miscellaneous C API - * \note Additional example code for this module can be found in its [Tutorial.](@ref controller) - */ - -#ifndef _PROS_MISC_H_ -#define _PROS_MISC_H_ - -#include - -#define NUM_V5_PORTS (22) - -/** - * \ingroup c-misc - */ - -/** - * \addtogroup c-misc - * @{ - */ - -/// \name V5 Competition -//@{ - -#define COMPETITION_DISABLED (1 << 0) -#define COMPETITION_AUTONOMOUS (1 << 1) -#define COMPETITION_CONNECTED (1 << 2) - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif - -/** - * \fn competition_get_status(void) - * Get the current status of the competition control. - * - * \return The competition control status as a mask of bits with - * COMPETITION_{ENABLED,AUTONOMOUS,CONNECTED}. - * - * \b Example - * \code - * void initialize() { - * if (competition_get_status() & COMPETITION_CONNECTED == true) { - * // Field Control is Connected - * // Run LCD Selector code or similar - * } - * } - * \endcode - */ -uint8_t competition_get_status(void); - -#ifdef __cplusplus -} -} -} -#endif - -/** - * \fn competition_is_disabled() - * - * \return True if the V5 Brain is disabled, false otherwise. - * - * \b Example - * \code - * void my_task_fn(void* ignore) { - * while (!competition_is_disabled()) { - * // Run competition tasks (like Lift Control or similar) - * } - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIO_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); - * } - * \endcode - */ -#define competition_is_disabled() ((competition_get_status() & COMPETITION_DISABLED) != 0) - -/** - * \return True if the V5 Brain is connected to competition control, false otherwise. - * - * \b Example - * \code - * void initialize() { - * if (competition_is_connected()) { - * // Field Control is Connected - * // Run LCD Selector code or similar - * } - * } - * \endcode - */ -#define competition_is_connected() ((competition_get_status() & COMPETITION_CONNECTED) != 0) - -/** - * \return True if the V5 Brain is in autonomous mode, false otherwise. - * - * \b Example - * \code - * void my_task_fn(void* ignore) { - * while (!competition_is_autonomous()) { - * // Wait to do anything until autonomous starts - * delay(2); - * } - * while (competition_is_autonomous()) { - * // Run whatever code is desired to just execute in autonomous - * } - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIO_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); - * } - * \endcode - */ -#define competition_is_autonomous() ((competition_get_status() & COMPETITION_AUTONOMOUS) != 0) - -///@} - -/// \name V5 Controller -///@{ -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/** - * \enum - */ -typedef enum { - ///The master controller. - E_CONTROLLER_MASTER = 0, - ///The partner controller. - E_CONTROLLER_PARTNER } controller_id_e_t; - -/** - * \enum - */ -typedef enum { - ///The horizontal axis of the controller’s left analog stick. - E_CONTROLLER_ANALOG_LEFT_X = 0, - ///The vertical axis of the controller’s left analog stick. - E_CONTROLLER_ANALOG_LEFT_Y, - ///The horizontal axis of the controller’s right analog stick. - E_CONTROLLER_ANALOG_RIGHT_X, - ///The vertical axis of the controller’s right analog stick. - E_CONTROLLER_ANALOG_RIGHT_Y -} controller_analog_e_t; - -/** - * \enum - */ -typedef enum { - ///The first trigger on the left side of the controller. - E_CONTROLLER_DIGITAL_L1 = 6, - ///The second trigger on the left side of the controller. - E_CONTROLLER_DIGITAL_L2, - ///The first trigger on the right side of the controller. - E_CONTROLLER_DIGITAL_R1, - ///The second trigger on the right side of the controller. - E_CONTROLLER_DIGITAL_R2, - ///The up arrow on the left arrow pad of the controller. - E_CONTROLLER_DIGITAL_UP, - ///The down arrow on the left arrow pad of the controller. - E_CONTROLLER_DIGITAL_DOWN, - ///The left arrow on the left arrow pad of the controller. - E_CONTROLLER_DIGITAL_LEFT, - ///The right arrow on the left arrow pad of the controller. - E_CONTROLLER_DIGITAL_RIGHT, - ///The ‘X’ button on the right button pad of the controller. - E_CONTROLLER_DIGITAL_X, - ///The ‘B’ button on the right button pad of the controller. - E_CONTROLLER_DIGITAL_B, - ///The ‘Y’ button on the right button pad of the controller. - E_CONTROLLER_DIGITAL_Y, - ///The ‘A’ button on the right button pad of the controller. - E_CONTROLLER_DIGITAL_A -} controller_digital_e_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define CONTROLLER_MASTER pros::E_CONTROLLER_MASTER -#define CONTROLLER_PARTNER pros::E_CONTROLLER_PARTNER -#define ANALOG_LEFT_X pros::E_CONTROLLER_ANALOG_LEFT_X -#define ANALOG_LEFT_Y pros::E_CONTROLLER_ANALOG_LEFT_Y -#define ANALOG_RIGHT_X pros::E_CONTROLLER_ANALOG_RIGHT_X -#define ANALOG_RIGHT_Y pros::E_CONTROLLER_ANALOG_RIGHT_Y -#define DIGITAL_L1 pros::E_CONTROLLER_DIGITAL_L1 -#define DIGITAL_L2 pros::E_CONTROLLER_DIGITAL_L2 -#define DIGITAL_R1 pros::E_CONTROLLER_DIGITAL_R1 -#define DIGITAL_R2 pros::E_CONTROLLER_DIGITAL_R2 -#define DIGITAL_UP pros::E_CONTROLLER_DIGITAL_UP -#define DIGITAL_DOWN pros::E_CONTROLLER_DIGITAL_DOWN -#define DIGITAL_LEFT pros::E_CONTROLLER_DIGITAL_LEFT -#define DIGITAL_RIGHT pros::E_CONTROLLER_DIGITAL_RIGHT -#define DIGITAL_X pros::E_CONTROLLER_DIGITAL_X -#define DIGITAL_B pros::E_CONTROLLER_DIGITAL_B -#define DIGITAL_Y pros::E_CONTROLLER_DIGITAL_Y -#define DIGITAL_A pros::E_CONTROLLER_DIGITAL_A -#else -#define CONTROLLER_MASTER E_CONTROLLER_MASTER -#define CONTROLLER_PARTNER E_CONTROLLER_PARTNER -#define ANALOG_LEFT_X E_CONTROLLER_ANALOG_LEFT_X -#define ANALOG_LEFT_Y E_CONTROLLER_ANALOG_LEFT_Y -#define ANALOG_RIGHT_X E_CONTROLLER_ANALOG_RIGHT_X -#define ANALOG_RIGHT_Y E_CONTROLLER_ANALOG_RIGHT_Y -#define DIGITAL_L1 E_CONTROLLER_DIGITAL_L1 -#define DIGITAL_L2 E_CONTROLLER_DIGITAL_L2 -#define DIGITAL_R1 E_CONTROLLER_DIGITAL_R1 -#define DIGITAL_R2 E_CONTROLLER_DIGITAL_R2 -#define DIGITAL_UP E_CONTROLLER_DIGITAL_UP -#define DIGITAL_DOWN E_CONTROLLER_DIGITAL_DOWN -#define DIGITAL_LEFT E_CONTROLLER_DIGITAL_LEFT -#define DIGITAL_RIGHT E_CONTROLLER_DIGITAL_RIGHT -#define DIGITAL_X E_CONTROLLER_DIGITAL_X -#define DIGITAL_B E_CONTROLLER_DIGITAL_B -#define DIGITAL_Y E_CONTROLLER_DIGITAL_Y -#define DIGITAL_A E_CONTROLLER_DIGITAL_A -#endif -#endif - -/** - * \def Given an id and a port, this macro sets the port variable based on the id and allows the mutex to take that port. - * - * \returns error (in the function/scope it's in) if the controller failed to connect or an invalid id is given. -*/ -#define CONTROLLER_PORT_MUTEX_TAKE(id, port) \ - switch (id) { \ - case E_CONTROLLER_MASTER: \ - port = V5_PORT_CONTROLLER_1; \ - break; \ - case E_CONTROLLER_PARTNER: \ - port = V5_PORT_CONTROLLER_2; \ - break; \ - default: \ - errno = EINVAL; \ - return PROS_ERR; \ - } \ - if (!internal_port_mutex_take(port)) { \ - errno = EACCES; \ - return PROS_ERR; \ - } \ - -#ifdef __cplusplus -namespace c { -#endif - -/** - * Checks if the controller is connected. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * - * \return 1 if the controller is connected, 0 otherwise - * - * \b Example - * \code - * void initialize() { - * if (competition_is_connected()) { - * // Field Control is Connected - * // Run LCD Selector code or similar - * } - * } - * \endcode - */ -int32_t controller_is_connected(controller_id_e_t id); - -/** - * Gets the value of an analog channel (joystick) on a controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param channel - * The analog channel to get. - * Must be one of ANALOG_LEFT_X, ANALOG_LEFT_Y, ANALOG_RIGHT_X, - * ANALOG_RIGHT_Y - * - * \return The current reading of the analog channel: [-127, 127]. - * If the controller was not connected, then 0 is returned - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * delay(2); - * } - * } - * \endcode - */ -int32_t controller_get_analog(controller_id_e_t id, controller_analog_e_t channel); - -/** - * Gets the battery capacity of the given controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER - * - * \return The controller's battery capacity - * - * \b Example - * \code - * void initialize() { - * printf("Battery Capacity: %d\n", controller_get_battery_capacity(E_CONTROLLER_MASTER)); - * } - * \endcode - */ -int32_t controller_get_battery_capacity(controller_id_e_t id); - -/** - * Gets the battery level of the given controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER - * - * \return The controller's battery level - * - * \b Example - * \code - * void initialize() { - * printf("Battery Level: %d\n", controller_get_battery_level(E_CONTROLLER_MASTER)); - * } - * \endcode - */ -int32_t controller_get_battery_level(controller_id_e_t id); - -/** - * Checks if a digital channel (button) on the controller is currently pressed. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param button - * The button to read. - * Must be one of DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} - * - * \return 1 if the button on the controller is pressed. - * If the controller was not connected, then 0 is returned - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * if (controller_get_digital(E_CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_A)) { - * motor_set(1, 100); - * } - * else { - * motor_set(1, 0); - * } - * delay(2); - * } - * } - - * \endcode - */ -int32_t controller_get_digital(controller_id_e_t id, controller_digital_e_t button); - -/** - * Returns a rising-edge case for a controller button press. - * - * This function is not thread-safe. - * Multiple tasks polling a single button may return different results under the - * same circumstances, so only one task should call this function for any given - * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call - * this function for button 3, but should not for buttons 1 or 2. A typical - * use-case for this function is to call inside opcontrol to detect new button - * presses, and not in any other tasks. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param button - * The button to read. Must be one of - * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} - * - * \return 1 if the button on the controller is pressed and had not been pressed - * the last time this function was called, 0 otherwise. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * if (controller_get_digital_new_press(E_CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_A)) { - * // Toggle pneumatics or other similar actions - * } - * - * delay(2); - * } - * } - * \endcode - */ -int32_t controller_get_digital_new_press(controller_id_e_t id, controller_digital_e_t button); - -/** - * Sets text to the controller LCD screen. - * - * \note Controller text setting is a slow process, so updates faster than 10ms - * when on a wired connection or 50ms over Vexnet will not be applied to the controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * EAGAIN - Could not send the text to the controller. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param line - * The line number at which the text will be displayed [0-2] - * \param col - * The column number at which the text will be displayed [0-14] - * \param fmt - * The format string to print to the controller - * \param ... - * The argument list for the format string - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * int count = 0; - * while (true) { - * if (!(count % 25)) { - * // Only print every 50ms, the controller text update rate is slow - * controller_print(E_CONTROLLER_MASTER, 0, 0, "Counter: %d", count); - * } - * count++; - * delay(2); - * } - * } - * \endcode - */ -int32_t controller_print(controller_id_e_t id, uint8_t line, uint8_t col, const char* fmt, ...); - -/** - * Sets text to the controller LCD screen. - * - * \note Controller text setting is a slow process, so updates faster than 10ms - * when on a wired connection or 50ms over Vexnet will not be applied to the controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * EAGAIN - Could not send the text to the controller. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param line - * The line number at which the text will be displayed [0-2] - * \param col - * The column number at which the text will be displayed [0-14] - * \param str - * The pre-formatted string to print to the controller - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * int count = 0; - * while (true) { - * if (!(count % 25)) { - * // Only print every 50ms, the controller text update rate is slow - * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example text"); - * } - * count++; - * delay(2); - * } - * } - * \endcode - */ -int32_t controller_set_text(controller_id_e_t id, uint8_t line, uint8_t col, const char* str); - -/** - * Clears an individual line of the controller screen. - * - * \note Controller text setting is currently in beta, so continuous, fast - * updates will not work well. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param line - * The line number to clear [0-2] - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example"); - * delay(100); - * controller_clear_line(E_CONTROLLER_MASTER, 0); - * } - * \endcode - */ -int32_t controller_clear_line(controller_id_e_t id, uint8_t line); - -/** - * Clears all of the lines on the controller screen. - * - * \note Controller text setting is a slow process, so updates faster than 10ms - * when on a wired connection or 50ms over Vexnet will not be applied to the controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * EAGAIN - Could not send the text to the controller. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example"); - * delay(100); - * controller_clear(E_CONTROLLER_MASTER); - * } - * \endcode - */ -int32_t controller_clear(controller_id_e_t id); - -/** - * Rumble the controller. - * - * \note Controller rumble activation is a slow process, so updates faster than 10ms - * when on a wired connection or 50ms over Vexnet will not be applied to the controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is - * given. - * EACCES - Another resource is currently trying to access the controller port. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - * \param rumble_pattern - * A string consisting of the characters '.', '-', and ' ', where dots - * are short rumbles, dashes are long rumbles, and spaces are pauses. - * Maximum supported length is 8 characters. - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * int count = 0; - * while (true) { - * if (!(count % 25)) { - * // Only send every 50ms, the controller update rate is slow - * controller_rumble(E_CONTROLLER_MASTER, ". - . -"); - * } - * count++; - * delay(2); - * } - * } - * \endcode - */ -int32_t controller_rumble(controller_id_e_t id, const char* rumble_pattern); - -/** - * Gets the current voltage of the battery, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current voltage of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery's Voltage: %d\n", battery_get_voltage()); - * } - * \endcode - */ -int32_t battery_get_voltage(void); - -/** - * Gets the current current of the battery, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current current of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery Current: %d\n", battery_get_current()); - * } - * \endcode - */ -int32_t battery_get_current(void); - -/** - * Gets the current temperature of the battery, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current temperature of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery's Temperature: %d\n", battery_get_temperature()); - * } - * \endcode - */ -double battery_get_temperature(void); - -/** - * Gets the current capacity of the battery, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current capacity of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery Level: %d\n", battery_get_capacity()); - * } - * \endcode - */ -double battery_get_capacity(void); - -/** - * Checks if the SD card is installed. - * - * \return 1 if the SD card is installed, 0 otherwise - * - * \b Example - * \code - * void opcontrol() { - * printf("%i", usd_is_installed()); - * } - * \endcode - */ -int32_t usd_is_installed(void); - -/******************************************************************************/ -/** Date and Time **/ -/******************************************************************************/ - -extern const char* baked_date; -extern const char* baked_time; - -typedef struct { - uint16_t year; // Year - 1980 - uint8_t day; - uint8_t month; // 1 = January -} date_s_t; - -typedef struct { - uint8_t hour; - uint8_t min; - uint8_t sec; - uint8_t sec_hund; // hundredths of a second -} time_s_t; - -///@} - -///@} - -#ifdef __cplusplus -} -} // namespace pros -} -#endif - -#endif // _PROS_MISC_H_ +/** + * \file pros/misc.h + * \ingroup c-misc + * + * Contains prototypes for miscellaneous functions pertaining to the controller, + * battery, and competition control. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reservered. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-misc Miscellaneous C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref controller) + */ + +#ifndef _PROS_MISC_H_ +#define _PROS_MISC_H_ + +#include + +#define NUM_V5_PORTS (22) + +/** + * \ingroup c-misc + */ + +/** + * \addtogroup c-misc + * @{ + */ + +/// \name V5 Competition +//@{ + +#define COMPETITION_DISABLED (1 << 0) +#define COMPETITION_AUTONOMOUS (1 << 1) +#define COMPETITION_CONNECTED (1 << 2) + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \fn competition_get_status(void) + * Get the current status of the competition control. + * + * \return The competition control status as a mask of bits with + * COMPETITION_{ENABLED,AUTONOMOUS,CONNECTED}. + * + * \b Example + * \code + * void initialize() { + * if (competition_get_status() & COMPETITION_CONNECTED == true) { + * // Field Control is Connected + * // Run LCD Selector code or similar + * } + * } + * \endcode + */ +uint8_t competition_get_status(void); + +#ifdef __cplusplus +} +} +} +#endif + +/** + * \fn competition_is_disabled() + * + * \return True if the V5 Brain is disabled, false otherwise. + * + * \b Example + * \code + * void my_task_fn(void* ignore) { + * while (!competition_is_disabled()) { + * // Run competition tasks (like Lift Control or similar) + * } + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIO_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +#define competition_is_disabled() ((competition_get_status() & COMPETITION_DISABLED) != 0) + +/** + * \return True if the V5 Brain is connected to competition control, false otherwise. + * + * \b Example + * \code + * void initialize() { + * if (competition_is_connected()) { + * // Field Control is Connected + * // Run LCD Selector code or similar + * } + * } + * \endcode + */ +#define competition_is_connected() ((competition_get_status() & COMPETITION_CONNECTED) != 0) + +/** + * \return True if the V5 Brain is in autonomous mode, false otherwise. + * + * \b Example + * \code + * void my_task_fn(void* ignore) { + * while (!competition_is_autonomous()) { + * // Wait to do anything until autonomous starts + * delay(2); + * } + * while (competition_is_autonomous()) { + * // Run whatever code is desired to just execute in autonomous + * } + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIO_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +#define competition_is_autonomous() ((competition_get_status() & COMPETITION_AUTONOMOUS) != 0) + +///@} + +/// \name V5 Controller +///@{ +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \enum + */ +typedef enum { + ///The master controller. + E_CONTROLLER_MASTER = 0, + ///The partner controller. + E_CONTROLLER_PARTNER } controller_id_e_t; + +/** + * \enum + */ +typedef enum { + ///The horizontal axis of the controller’s left analog stick. + E_CONTROLLER_ANALOG_LEFT_X = 0, + ///The vertical axis of the controller’s left analog stick. + E_CONTROLLER_ANALOG_LEFT_Y, + ///The horizontal axis of the controller’s right analog stick. + E_CONTROLLER_ANALOG_RIGHT_X, + ///The vertical axis of the controller’s right analog stick. + E_CONTROLLER_ANALOG_RIGHT_Y +} controller_analog_e_t; + +/** + * \enum + */ +typedef enum { + ///The first trigger on the left side of the controller. + E_CONTROLLER_DIGITAL_L1 = 6, + ///The second trigger on the left side of the controller. + E_CONTROLLER_DIGITAL_L2, + ///The first trigger on the right side of the controller. + E_CONTROLLER_DIGITAL_R1, + ///The second trigger on the right side of the controller. + E_CONTROLLER_DIGITAL_R2, + ///The up arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_UP, + ///The down arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_DOWN, + ///The left arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_LEFT, + ///The right arrow on the left arrow pad of the controller. + E_CONTROLLER_DIGITAL_RIGHT, + ///The ‘X’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_X, + ///The ‘B’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_B, + ///The ‘Y’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_Y, + ///The ‘A’ button on the right button pad of the controller. + E_CONTROLLER_DIGITAL_A +} controller_digital_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define CONTROLLER_MASTER pros::E_CONTROLLER_MASTER +#define CONTROLLER_PARTNER pros::E_CONTROLLER_PARTNER +#define ANALOG_LEFT_X pros::E_CONTROLLER_ANALOG_LEFT_X +#define ANALOG_LEFT_Y pros::E_CONTROLLER_ANALOG_LEFT_Y +#define ANALOG_RIGHT_X pros::E_CONTROLLER_ANALOG_RIGHT_X +#define ANALOG_RIGHT_Y pros::E_CONTROLLER_ANALOG_RIGHT_Y +#define DIGITAL_L1 pros::E_CONTROLLER_DIGITAL_L1 +#define DIGITAL_L2 pros::E_CONTROLLER_DIGITAL_L2 +#define DIGITAL_R1 pros::E_CONTROLLER_DIGITAL_R1 +#define DIGITAL_R2 pros::E_CONTROLLER_DIGITAL_R2 +#define DIGITAL_UP pros::E_CONTROLLER_DIGITAL_UP +#define DIGITAL_DOWN pros::E_CONTROLLER_DIGITAL_DOWN +#define DIGITAL_LEFT pros::E_CONTROLLER_DIGITAL_LEFT +#define DIGITAL_RIGHT pros::E_CONTROLLER_DIGITAL_RIGHT +#define DIGITAL_X pros::E_CONTROLLER_DIGITAL_X +#define DIGITAL_B pros::E_CONTROLLER_DIGITAL_B +#define DIGITAL_Y pros::E_CONTROLLER_DIGITAL_Y +#define DIGITAL_A pros::E_CONTROLLER_DIGITAL_A +#else +#define CONTROLLER_MASTER E_CONTROLLER_MASTER +#define CONTROLLER_PARTNER E_CONTROLLER_PARTNER +#define ANALOG_LEFT_X E_CONTROLLER_ANALOG_LEFT_X +#define ANALOG_LEFT_Y E_CONTROLLER_ANALOG_LEFT_Y +#define ANALOG_RIGHT_X E_CONTROLLER_ANALOG_RIGHT_X +#define ANALOG_RIGHT_Y E_CONTROLLER_ANALOG_RIGHT_Y +#define DIGITAL_L1 E_CONTROLLER_DIGITAL_L1 +#define DIGITAL_L2 E_CONTROLLER_DIGITAL_L2 +#define DIGITAL_R1 E_CONTROLLER_DIGITAL_R1 +#define DIGITAL_R2 E_CONTROLLER_DIGITAL_R2 +#define DIGITAL_UP E_CONTROLLER_DIGITAL_UP +#define DIGITAL_DOWN E_CONTROLLER_DIGITAL_DOWN +#define DIGITAL_LEFT E_CONTROLLER_DIGITAL_LEFT +#define DIGITAL_RIGHT E_CONTROLLER_DIGITAL_RIGHT +#define DIGITAL_X E_CONTROLLER_DIGITAL_X +#define DIGITAL_B E_CONTROLLER_DIGITAL_B +#define DIGITAL_Y E_CONTROLLER_DIGITAL_Y +#define DIGITAL_A E_CONTROLLER_DIGITAL_A +#endif +#endif + +/** + * \def Given an id and a port, this macro sets the port variable based on the id and allows the mutex to take that port. + * + * \returns error (in the function/scope it's in) if the controller failed to connect or an invalid id is given. +*/ +#define CONTROLLER_PORT_MUTEX_TAKE(id, port) \ + switch (id) { \ + case E_CONTROLLER_MASTER: \ + port = V5_PORT_CONTROLLER_1; \ + break; \ + case E_CONTROLLER_PARTNER: \ + port = V5_PORT_CONTROLLER_2; \ + break; \ + default: \ + errno = EINVAL; \ + return PROS_ERR; \ + } \ + if (!internal_port_mutex_take(port)) { \ + errno = EACCES; \ + return PROS_ERR; \ + } \ + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Checks if the controller is connected. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * + * \return 1 if the controller is connected, 0 otherwise + * + * \b Example + * \code + * void initialize() { + * if (competition_is_connected()) { + * // Field Control is Connected + * // Run LCD Selector code or similar + * } + * } + * \endcode + */ +int32_t controller_is_connected(controller_id_e_t id); + +/** + * Gets the value of an analog channel (joystick) on a controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param channel + * The analog channel to get. + * Must be one of ANALOG_LEFT_X, ANALOG_LEFT_Y, ANALOG_RIGHT_X, + * ANALOG_RIGHT_Y + * + * \return The current reading of the analog channel: [-127, 127]. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_get_analog(controller_id_e_t id, controller_analog_e_t channel); + +/** + * Gets the battery capacity of the given controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER + * + * \return The controller's battery capacity + * + * \b Example + * \code + * void initialize() { + * printf("Battery Capacity: %d\n", controller_get_battery_capacity(E_CONTROLLER_MASTER)); + * } + * \endcode + */ +int32_t controller_get_battery_capacity(controller_id_e_t id); + +/** + * Gets the battery level of the given controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER + * + * \return The controller's battery level + * + * \b Example + * \code + * void initialize() { + * printf("Battery Level: %d\n", controller_get_battery_level(E_CONTROLLER_MASTER)); + * } + * \endcode + */ +int32_t controller_get_battery_level(controller_id_e_t id); + +/** + * Checks if a digital channel (button) on the controller is currently pressed. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param button + * The button to read. + * Must be one of DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * if (controller_get_digital(E_CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_A)) { + * motor_set(1, 100); + * } + * else { + * motor_set(1, 0); + * } + * delay(2); + * } + * } + + * \endcode + */ +int32_t controller_get_digital(controller_id_e_t id, controller_digital_e_t button); + +/** + * Returns a rising-edge case for a controller button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under the + * same circumstances, so only one task should call this function for any given + * button. E.g., Task A calls this function for buttons 1 and 2. Task B may call + * this function for button 3, but should not for buttons 1 or 2. A typical + * use-case for this function is to call inside opcontrol to detect new button + * presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed and had not been pressed + * the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * if (controller_get_digital_new_press(E_CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_A)) { + * // Toggle pneumatics or other similar actions + * } + * + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_get_digital_new_press(controller_id_e_t id, controller_digital_e_t button); + +/** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * EAGAIN - Could not send the text to the controller. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param fmt + * The format string to print to the controller + * \param ... + * The argument list for the format string + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * controller_print(E_CONTROLLER_MASTER, 0, 0, "Counter: %d", count); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_print(controller_id_e_t id, uint8_t line, uint8_t col, const char* fmt, ...); + +/** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * EAGAIN - Could not send the text to the controller. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param str + * The pre-formatted string to print to the controller + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example text"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_set_text(controller_id_e_t id, uint8_t line, uint8_t col, const char* str); + +/** + * Clears an individual line of the controller screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param line + * The line number to clear [0-2] + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example"); + * delay(100); + * controller_clear_line(E_CONTROLLER_MASTER, 0); + * } + * \endcode + */ +int32_t controller_clear_line(controller_id_e_t id, uint8_t line); + +/** + * Clears all of the lines on the controller screen. + * + * \note Controller text setting is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * EAGAIN - Could not send the text to the controller. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * controller_set_text(E_CONTROLLER_MASTER, 0, 0, "Example"); + * delay(100); + * controller_clear(E_CONTROLLER_MASTER); + * } + * \endcode + */ +int32_t controller_clear(controller_id_e_t id); + +/** + * Rumble the controller. + * + * \note Controller rumble activation is a slow process, so updates faster than 10ms + * when on a wired connection or 50ms over Vexnet will not be applied to the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - A value other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER is + * given. + * EACCES - Another resource is currently trying to access the controller port. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + * \param rumble_pattern + * A string consisting of the characters '.', '-', and ' ', where dots + * are short rumbles, dashes are long rumbles, and spaces are pauses. + * Maximum supported length is 8 characters. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * while (true) { + * if (!(count % 25)) { + * // Only send every 50ms, the controller update rate is slow + * controller_rumble(E_CONTROLLER_MASTER, ". - . -"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ +int32_t controller_rumble(controller_id_e_t id, const char* rumble_pattern); + +/** + * Gets the current voltage of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current voltage of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Voltage: %d\n", battery_get_voltage()); + * } + * \endcode + */ +int32_t battery_get_voltage(void); + +/** + * Gets the current current of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current current of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Current: %d\n", battery_get_current()); + * } + * \endcode + */ +int32_t battery_get_current(void); + +/** + * Gets the current temperature of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current temperature of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Temperature: %d\n", battery_get_temperature()); + * } + * \endcode + */ +double battery_get_temperature(void); + +/** + * Gets the current capacity of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current capacity of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Level: %d\n", battery_get_capacity()); + * } + * \endcode + */ +double battery_get_capacity(void); + +/** + * Checks if the SD card is installed. + * + * \return 1 if the SD card is installed, 0 otherwise + * + * \b Example + * \code + * void opcontrol() { + * printf("%i", usd_is_installed()); + * } + * \endcode + */ +int32_t usd_is_installed(void); + +/******************************************************************************/ +/** Date and Time **/ +/******************************************************************************/ + +extern const char* baked_date; +extern const char* baked_time; + +typedef struct { + uint16_t year; // Year - 1980 + uint8_t day; + uint8_t month; // 1 = January +} date_s_t; + +typedef struct { + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t sec_hund; // hundredths of a second +} time_s_t; + +///@} + +///@} + +#ifdef __cplusplus +} +} // namespace pros +} +#endif + +#endif // _PROS_MISC_H_ diff --git a/include/pros/misc.hpp b/include/pros/misc.hpp index b8f300f..8ade055 100644 --- a/include/pros/misc.hpp +++ b/include/pros/misc.hpp @@ -1,532 +1,532 @@ -/** - * \file pros/misc.hpp - * \ingroup cpp-pros - * - * Contains prototypes for miscellaneous functions pertaining to the controller, - * battery, and competition control. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reservered. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup cpp-misc Miscellaneous C++ API - * \note Additional example code for this module can be found in its [Tutorial.](@ref controller) - */ - -#ifndef _PROS_MISC_HPP_ -#define _PROS_MISC_HPP_ - -#include "pros/misc.h" - -#include -#include - -namespace pros { -inline namespace v5 { -/** - * \ingroup cpp-misc - */ -class Controller { - /** - * \addtogroup cpp-misc - * ///@{ - */ - public: - /** - * Creates a controller object for the given controller id. - * - * \param id - * The ID of the controller (e.g. the master or partner controller). - * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER - */ - explicit Controller(controller_id_e_t id); - - /** - * Checks if the controller is connected. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \return 1 if the controller is connected, 0 otherwise - * - * \b Example - * \code - * void status_display_controller(){ - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * if(!master.is_connected()) { - * pros::lcd::print(0, "Main controller is not connected!"); - * } - * } - * \endcode - */ - std::int32_t is_connected(void); - - /** - * Gets the value of an analog channel (joystick) on a controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param channel - * The analog channel to get. - * Must be one of ANALOG_LEFT_X, ANALOG_LEFT_Y, ANALOG_RIGHT_X, - * ANALOG_RIGHT_Y - * - * \return The current reading of the analog channel: [-127, 127]. - * If the controller was not connected, then 0 is returned - * - * \b Example - * \code - * void opcontrol() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * while (true) { - * motor_move(1, master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); - * delay(2); - * } - * } - * \endcode - */ - std::int32_t get_analog(controller_analog_e_t channel); - - /** - * Gets the battery capacity of the controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \return The controller's battery capacity - * - * \b Example - * \code - * void initialize() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * printf("Battery Capacity: %d\n", master.get_battery_capacity()); - * } - * \endcode - */ - std::int32_t get_battery_capacity(void); - - /** - * Gets the battery level of the controller. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \return The controller's battery level - * - * \b Example - * \code - * void initialize() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * printf("Battery Level: %d\n", master.get_battery_level()); - * } - * \endcode - */ - std::int32_t get_battery_level(void); - - /** - * Checks if a digital channel (button) on the controller is currently - * pressed. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param button - * The button to read. Must be one of - * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} - * - * \return 1 if the button on the controller is pressed. - * If the controller was not connected, then 0 is returned - * - * \b Example - * \code - * void opcontrol() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * while (true) { - * if (master.get_digital(pros::E_CONTROLLER_DIGITAL_A)) { - * motor_set(1, 100); - * } - * else { - * motor_set(1, 0); - * } - * delay(2); - * } - * } - * \endcode - */ - std::int32_t get_digital(controller_digital_e_t button); - - /** - * Returns a rising-edge case for a controller button press. - * - * This function is not thread-safe. - * Multiple tasks polling a single button may return different results under - * the same circumstances, so only one task should call this function for any - * given button. E.g., Task A calls this function for buttons 1 and 2. - * Task B may call this function for button 3, but should not for buttons - * 1 or 2. A typical use-case for this function is to call inside opcontrol - * to detect new button presses, and not in any other tasks. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param button - * The button to read. Must be one of - * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} - * - * \return 1 if the button on the controller is pressed and had not been - * pressed the last time this function was called, 0 otherwise. - * - * \b Example - * \code - * void opcontrol() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * while (true) { - * if (master.get_digital_new_press(pros::E_CONTROLLER_DIGITAL_A)) { - * // Toggle pneumatics or other similar actions - * } - * - * delay(2); - * } - * } - * \endcode - */ - std::int32_t get_digital_new_press(controller_digital_e_t button); - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" - template - T convert_args(T arg) { - return arg; - } - const char* convert_args(const std::string& arg) { - return arg.c_str(); - } -#pragma GCC diagnostic pop - - /** - * Sets text to the controller LCD screen. - * - * \note Controller text setting is currently in beta, so continuous, fast - * updates will not work well. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param line - * The line number at which the text will be displayed [0-2] - * \param col - * The column number at which the text will be displayed [0-14] - * \param fmt - * The format string to print to the controller - * \param ... - * The argument list for the format string - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * int count = 0; - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * while (true) { - * if (!(count % 25)) { - * // Only print every 50ms, the controller text update rate is slow - * master.print(0, 0, "Counter: %d", count); - * } - * count++; - * delay(2); - * } - * } - * \endcode - */ - template - std::int32_t print(std::uint8_t line, std::uint8_t col, const char* fmt, Params... args) { - return pros::c::controller_print(_id, line, col, fmt, convert_args(args)...); - } - - /** - * Sets text to the controller LCD screen. - * - * \note Controller text setting is currently in beta, so continuous, fast - * updates will not work well. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param line - * The line number at which the text will be displayed [0-2] - * \param col - * The column number at which the text will be displayed [0-14] - * \param str - * The pre-formatted string to print to the controller - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * int count = 0; - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * while (true) { - * if (!(count % 25)) { - * // Only print every 50ms, the controller text update rate is slow - * master.set_text(0, 0, "Example text"); - * } - * count++; - * delay(2); - * } - * } - * \endcode - */ - std::int32_t set_text(std::uint8_t line, std::uint8_t col, const char* str); - std::int32_t set_text(std::uint8_t line, std::uint8_t col, const std::string& str); - - /** - * Clears an individual line of the controller screen. - * - * \note Controller text setting is currently in beta, so continuous, fast - * updates will not work well. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param line - * The line number to clear [0-2] - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * master.set_text(0, 0, "Example"); - * delay(100); - * master.clear_line(0); - * } - * \endcode - */ - std::int32_t clear_line(std::uint8_t line); - - /** - * Rumble the controller. - * - * \note Controller rumble activation is currently in beta, so continuous, fast - * updates will not work well. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \param rumble_pattern - * A string consisting of the characters '.', '-', and ' ', where dots - * are short rumbles, dashes are long rumbles, and spaces are pauses. - * Maximum supported length is 8 characters. - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * int count = 0; - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * while (true) { - * if (!(count % 25)) { - * // Only send every 50ms, the controller update rate is slow - * master.rumble(". - . -"); - * } - * count++; - * delay(2); - * } - * } - * \endcode - */ - std::int32_t rumble(const char* rumble_pattern); - - /** - * Clears all of the lines on the controller screen. - * - * \note Controller text setting is currently in beta, so continuous, fast - * updates will not work well. On vexOS version 1.0.0 this function will - * block for 110ms. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the controller - * port. - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * pros::Controller master(pros::E_CONTROLLER_MASTER); - * master.set_text(0, 0, "Example"); - * delay(100); - * master.clear(); - * } - * \endcode - */ - std::int32_t clear(void); - - private: - controller_id_e_t _id; - ///@} -}; -} // namespace v5 - -namespace battery { -/** - * \addtogroup cpp-misc - * ///@{ - */ -/** - * Gets the current voltage of the battery, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current voltage of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery Level: %.2f\n", get_capacity()); - * } - * \endcode - */ -double get_capacity(void); - -/** - * Gets the current current of the battery in milliamps, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current current of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery Current: %d\n", get_current()); - * } - * \endcode - */ -int32_t get_current(void); - -/** - * Gets the current temperature of the battery, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current temperature of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery's Temperature: %.2f\n", get_temperature()); - * } - * \endcode - */ -double get_temperature(void); - -/** - * Gets the current capacity of the battery in millivolts, as reported by VEXos. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCES - Another resource is currently trying to access the battery port. - * - * \return The current capacity of the battery - * - * \b Example - * \code - * void initialize() { - * printf("Battery's Voltage: %d\n", get_voltage()); - * } - * \endcode - */ -int32_t get_voltage(void); -///@} -} // namespace battery - -namespace competition { -/** - * Get the current status of the competition control. - * - * \return The competition control status as a mask of bits with - * COMPETITION_{ENABLED,AUTONOMOUS,CONNECTED}. - * - * \b Example - * \code - * void status_display_task(){ - * if(!is_connected()) { - * pros::lcd::print(0, "V5 Brain is not connected!"); - * } - * if(is_autonomous()) { - * pros::lcd::print(0, "V5 Brain is in autonomous mode!"); - * } - * if(!is_disabled()) { - * pros::lcd::print(0, "V5 Brain is disabled!"); - * } - * \endcode - */ -std::uint8_t get_status(void); -std::uint8_t is_autonomous(void); -std::uint8_t is_connected(void); -std::uint8_t is_disabled(void); -} // namespace competition - -namespace usd { -/** - * Checks if the SD card is installed. - * - * \return 1 if the SD card is installed, 0 otherwise - * - * \b Example - * \code - * void opcontrol() { - * printf("%i", is_installed()); - * } - * \endcode - */ -std::int32_t is_installed(void); -} // namespace usd - -} // namespace pros - -#endif // _PROS_MISC_HPP_ +/** + * \file pros/misc.hpp + * \ingroup cpp-pros + * + * Contains prototypes for miscellaneous functions pertaining to the controller, + * battery, and competition control. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reservered. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-misc Miscellaneous C++ API + * \note Additional example code for this module can be found in its [Tutorial.](@ref controller) + */ + +#ifndef _PROS_MISC_HPP_ +#define _PROS_MISC_HPP_ + +#include "pros/misc.h" + +#include +#include + +namespace pros { +inline namespace v5 { +/** + * \ingroup cpp-misc + */ +class Controller { + /** + * \addtogroup cpp-misc + * ///@{ + */ + public: + /** + * Creates a controller object for the given controller id. + * + * \param id + * The ID of the controller (e.g. the master or partner controller). + * Must be one of CONTROLLER_MASTER or CONTROLLER_PARTNER + */ + explicit Controller(controller_id_e_t id); + + /** + * Checks if the controller is connected. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return 1 if the controller is connected, 0 otherwise + * + * \b Example + * \code + * void status_display_controller(){ + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * if(!master.is_connected()) { + * pros::lcd::print(0, "Main controller is not connected!"); + * } + * } + * \endcode + */ + std::int32_t is_connected(void); + + /** + * Gets the value of an analog channel (joystick) on a controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param channel + * The analog channel to get. + * Must be one of ANALOG_LEFT_X, ANALOG_LEFT_Y, ANALOG_RIGHT_X, + * ANALOG_RIGHT_Y + * + * \return The current reading of the analog channel: [-127, 127]. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * motor_move(1, master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_analog(controller_analog_e_t channel); + + /** + * Gets the battery capacity of the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return The controller's battery capacity + * + * \b Example + * \code + * void initialize() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * printf("Battery Capacity: %d\n", master.get_battery_capacity()); + * } + * \endcode + */ + std::int32_t get_battery_capacity(void); + + /** + * Gets the battery level of the controller. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return The controller's battery level + * + * \b Example + * \code + * void initialize() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * printf("Battery Level: %d\n", master.get_battery_level()); + * } + * \endcode + */ + std::int32_t get_battery_level(void); + + /** + * Checks if a digital channel (button) on the controller is currently + * pressed. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed. + * If the controller was not connected, then 0 is returned + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (master.get_digital(pros::E_CONTROLLER_DIGITAL_A)) { + * motor_set(1, 100); + * } + * else { + * motor_set(1, 0); + * } + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_digital(controller_digital_e_t button); + + /** + * Returns a rising-edge case for a controller button press. + * + * This function is not thread-safe. + * Multiple tasks polling a single button may return different results under + * the same circumstances, so only one task should call this function for any + * given button. E.g., Task A calls this function for buttons 1 and 2. + * Task B may call this function for button 3, but should not for buttons + * 1 or 2. A typical use-case for this function is to call inside opcontrol + * to detect new button presses, and not in any other tasks. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param button + * The button to read. Must be one of + * DIGITAL_{RIGHT,DOWN,LEFT,UP,A,B,Y,X,R1,R2,L1,L2} + * + * \return 1 if the button on the controller is pressed and had not been + * pressed the last time this function was called, 0 otherwise. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (master.get_digital_new_press(pros::E_CONTROLLER_DIGITAL_A)) { + * // Toggle pneumatics or other similar actions + * } + * + * delay(2); + * } + * } + * \endcode + */ + std::int32_t get_digital_new_press(controller_digital_e_t button); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + template + T convert_args(T arg) { + return arg; + } + const char* convert_args(const std::string& arg) { + return arg.c_str(); + } +#pragma GCC diagnostic pop + + /** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param fmt + * The format string to print to the controller + * \param ... + * The argument list for the format string + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * master.print(0, 0, "Counter: %d", count); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ + template + std::int32_t print(std::uint8_t line, std::uint8_t col, const char* fmt, Params... args) { + return pros::c::controller_print(_id, line, col, fmt, convert_args(args)...); + } + + /** + * Sets text to the controller LCD screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param line + * The line number at which the text will be displayed [0-2] + * \param col + * The column number at which the text will be displayed [0-14] + * \param str + * The pre-formatted string to print to the controller + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (!(count % 25)) { + * // Only print every 50ms, the controller text update rate is slow + * master.set_text(0, 0, "Example text"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ + std::int32_t set_text(std::uint8_t line, std::uint8_t col, const char* str); + std::int32_t set_text(std::uint8_t line, std::uint8_t col, const std::string& str); + + /** + * Clears an individual line of the controller screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param line + * The line number to clear [0-2] + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * master.set_text(0, 0, "Example"); + * delay(100); + * master.clear_line(0); + * } + * \endcode + */ + std::int32_t clear_line(std::uint8_t line); + + /** + * Rumble the controller. + * + * \note Controller rumble activation is currently in beta, so continuous, fast + * updates will not work well. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \param rumble_pattern + * A string consisting of the characters '.', '-', and ' ', where dots + * are short rumbles, dashes are long rumbles, and spaces are pauses. + * Maximum supported length is 8 characters. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * int count = 0; + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * while (true) { + * if (!(count % 25)) { + * // Only send every 50ms, the controller update rate is slow + * master.rumble(". - . -"); + * } + * count++; + * delay(2); + * } + * } + * \endcode + */ + std::int32_t rumble(const char* rumble_pattern); + + /** + * Clears all of the lines on the controller screen. + * + * \note Controller text setting is currently in beta, so continuous, fast + * updates will not work well. On vexOS version 1.0.0 this function will + * block for 110ms. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the controller + * port. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Controller master(pros::E_CONTROLLER_MASTER); + * master.set_text(0, 0, "Example"); + * delay(100); + * master.clear(); + * } + * \endcode + */ + std::int32_t clear(void); + + private: + controller_id_e_t _id; + ///@} +}; +} // namespace v5 + +namespace battery { +/** + * \addtogroup cpp-misc + * ///@{ + */ +/** + * Gets the current voltage of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current voltage of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Level: %.2f\n", get_capacity()); + * } + * \endcode + */ +double get_capacity(void); + +/** + * Gets the current current of the battery in milliamps, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current current of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery Current: %d\n", get_current()); + * } + * \endcode + */ +int32_t get_current(void); + +/** + * Gets the current temperature of the battery, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current temperature of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Temperature: %.2f\n", get_temperature()); + * } + * \endcode + */ +double get_temperature(void); + +/** + * Gets the current capacity of the battery in millivolts, as reported by VEXos. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCES - Another resource is currently trying to access the battery port. + * + * \return The current capacity of the battery + * + * \b Example + * \code + * void initialize() { + * printf("Battery's Voltage: %d\n", get_voltage()); + * } + * \endcode + */ +int32_t get_voltage(void); +///@} +} // namespace battery + +namespace competition { +/** + * Get the current status of the competition control. + * + * \return The competition control status as a mask of bits with + * COMPETITION_{ENABLED,AUTONOMOUS,CONNECTED}. + * + * \b Example + * \code + * void status_display_task(){ + * if(!is_connected()) { + * pros::lcd::print(0, "V5 Brain is not connected!"); + * } + * if(is_autonomous()) { + * pros::lcd::print(0, "V5 Brain is in autonomous mode!"); + * } + * if(!is_disabled()) { + * pros::lcd::print(0, "V5 Brain is disabled!"); + * } + * \endcode + */ +std::uint8_t get_status(void); +std::uint8_t is_autonomous(void); +std::uint8_t is_connected(void); +std::uint8_t is_disabled(void); +} // namespace competition + +namespace usd { +/** + * Checks if the SD card is installed. + * + * \return 1 if the SD card is installed, 0 otherwise + * + * \b Example + * \code + * void opcontrol() { + * printf("%i", is_installed()); + * } + * \endcode + */ +std::int32_t is_installed(void); +} // namespace usd + +} // namespace pros + +#endif // _PROS_MISC_HPP_ diff --git a/include/pros/motor_group.hpp b/include/pros/motor_group.hpp index 33f64c6..f99576e 100644 --- a/include/pros/motor_group.hpp +++ b/include/pros/motor_group.hpp @@ -16,8 +16,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * \defgroup cpp-motor-group Motors C++ API - * \note Additional example code for this module can be found in its [Tutorial](@ref motors). + * \defgroup cpp-motor-group Motor Groups C++ API */ #ifndef _PROS_MOTOR_GROUP_HPP_ @@ -442,7 +441,7 @@ class MotorGroup : public virtual AbstractMotor { * } * \endcode */ - double get_target_position(const std::uint8_t index) const; + double get_target_position(const std::uint8_t index = 0) const; /** * Gets a vector of the the target positions set for the motor group @@ -758,7 +757,7 @@ class MotorGroup : public virtual AbstractMotor { * * EDOM - THe motor group is empty * - * \return A vecotr containing each motor's efficiency in percent or PROS_ERR_F if the operation + * \return A vector containing each motor's efficiency in percent or PROS_ERR_F if the operation * failed, setting errno. * * \b Example @@ -1107,7 +1106,7 @@ class MotorGroup : public virtual AbstractMotor { * ENODEV - The port cannot be configured as a motor * EDOM - The motor group is empty * - * \return A vecotr of each motor's temperature in degrees Celsius or PROS_ERR_F if the + * \return A vector of each motor's temperature in degrees Celsius or PROS_ERR_F if the * operation failed, setting errno. * * \b Example @@ -1320,7 +1319,7 @@ class MotorGroup : public virtual AbstractMotor { */ std::int32_t is_over_temp(const std::uint8_t index = 0) const; /** - * Gets a vecotr with the temperature limit flag for each motor in the motor group. + * Gets a vector with the temperature limit flag for each motor in the motor group. * * This function uses the following values of errno when an error state is * reached: @@ -1377,7 +1376,7 @@ class MotorGroup : public virtual AbstractMotor { */ MotorBrake get_brake_mode(const std::uint8_t index = 0) const; /** - * Gets a vecotr with the brake mode that was set for each motor in the motor group. + * Gets a vector with the brake mode that was set for each motor in the motor group. * * This function uses the following values of errno when an error state is * reached: diff --git a/include/pros/motors.h b/include/pros/motors.h index 7a9eb39..ad6ef34 100644 --- a/include/pros/motors.h +++ b/include/pros/motors.h @@ -1,1341 +1,1341 @@ -/** - * \file pros/motors.h - * \ingroup c-motors - * - * Contains prototypes for the V5 Motor-related functions. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-motors Motors C API - * \note Additional example code for this module can be found in its [Tutorial](@ref motors). - */ - -#ifndef _PROS_MOTORS_H_ -#define _PROS_MOTORS_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif - -/** - * \ingroup c-motors - */ - -/** - * \addtogroup c-motors - * @{ - */ - -/// \name Motor movement functions -/// These functions allow programmers to make motors move -///@{ - -/** - * Sets the voltage for the motor from -127 to 127. - * - * This is designed to map easily to the input from the controller's analog - * stick for simple opcontrol use. The actual behavior of the motor is analogous - * to use of motor_move_voltage(). - * - * \note This function will not respect brake modes, and simply sets the voltage to the desired value. - * - * \note A negative port will negate the input voltage - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param voltage - * The new motor voltage from -127 to 127 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_move(int8_t port, int32_t voltage); - -/** - * Stops the motor using the currently configured brake mode. - * - * This function sets motor velocity to zero, which will cause it to act - * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, - * this function may behave differently than calling motor_move_absolute(port, 0) - * or motor_move_relative(port, 0). - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move(1, 127); - * delay(1000); - * motor_break(1); - * } - * \endcode - */ -int32_t motor_brake(int8_t port); - -/** - * Sets the target absolute position for the motor to move to. - * - * This movement is relative to the position of the motor when initialized or - * the position when it was most recently reset with motor_set_zero_position(). - * - * \note This function simply sets the target for the motor, it does not block program - * execution until the movement finishes. The example code shows how to block until a movement is finished. - * - * \note A negative port number will negate the target position - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param position - * The absolute position to move to in the motor's encoder units - * \param velocity - * The maximum allowable velocity for the movement in RPM - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_absolute(1, 100, 100); // Moves 100 units forward - * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { - * // Continue running this loop as long as the motor is not within +-5 units of its goal - * delay(2); - * } - * motor_move_absolute(1, 100, 100); // This will not cause a movement - * while(!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { - * delay(2); - * } - * - * motor_tare_position(1); - * motor_move_absolute(1, 100, 100); // Moves 100 units forward - * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_move_absolute(int8_t port, double position, const int32_t velocity); - -/** - * Sets the relative target position for the motor to move to. - * - * This movement is relative to the current position of the motor as given in - * motor_get_position(). Providing 10.0 as the position parameter would result - * in the motor moving clockwise 10 units, no matter what the current position - * is. - * - * \note This function simply sets the target for the motor, it does not block - * program execution until the movement finishes. The example code shows how to - * block until a movement is finished. - * - * \note A negative port will negate the target position - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param position - * The relative position to move to in the motor's encoder units - * \param velocity - * The maximum allowable velocity for the movement in RPM - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_relative(1, 100, 100); // Moves 100 units forward - * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { - * // Continue running this loop as long as the motor is not within +-5 units of its goal - * delay(2); - * } - * - * motor_move_relative(1, 100, 100); // Also moves 100 units forward - * while (!((motor_get_position(1) < 205) && (motor_get_position(1) > 195))) { - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_move_relative(int8_t port, double position, const int32_t velocity); - -/** - * Sets the velocity for the motor. - * - * This velocity corresponds to different actual speeds depending on the gearset - * used for the motor. This results in a range of +-100 for E_MOTOR_GEARSET_36, - * +-200 for E_MOTOR_GEARSET_18, and +-600 for E_MOTOR_GEARSET_6. The velocity - * is held with PID to ensure consistent speed, as opposed to setting the - * motor's voltage. - * - * \note A negative port will negate the velocity - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param velocity - * The new motor velocity from +-100, +-200, or +-600 depending on the - * motor's gearset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_velocity(1, 100); - * delay(1000); // Move at 100 RPM for 1 second - * motor_move_velocity(1, 0); - * } - * \endcode - */ -int32_t motor_move_velocity(int8_t port, const int32_t velocity); - -/** - * Sets the output voltage for the motor from -12000 to 12000 in millivolts - * - * \note A negative port negates the voltage - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \note This function will not respect brake modes, and simply sets the - * voltage to the desired value. - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param voltage - * The new voltage value from -12000 to 12000 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_voltage(1, 12000); - * delay(1000); // Move at max voltage for 1 second - * motor_move_voltage(1, 0); - * } - * \endcode - */ -int32_t motor_move_voltage(int8_t port, const int32_t voltage); - -/** - * Changes the output velocity for a profiled movement (motor_move_absolute or - * motor_move_relative). This will have no effect if the motor is not following - * a profiled movement. - * - * \note A negative port negates the velocity - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param velocity - * The new motor velocity from +-100, +-200, or +-600 depending on the - * motor's gearset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_absolute(1, 100, 100); - * delay(100); - * motor_modify_profiled_velocity(1, 0); // Stop the motor early - * } - * \endcode - */ -int32_t motor_modify_profiled_velocity(int8_t port, const int32_t velocity); - -/** - * Gets the target position set for the motor by the user. - * - * \note A negative port negates the return value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The target position in its encoder units or PROS_ERR_F if the - * operation failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_absolute(1, 100, 100); - * printf("Motor Target: %d\n", motor_get_target_position(1)); - * // Prints 100 - * } - * \endcode - */ -double motor_get_target_position(int8_t port); - -/** - * Gets the velocity commanded to the motor by the user. - * - * \note A negative port negates the return value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The commanded motor velocity from +-100, +-200, or +-600, or PROS_ERR - * if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move_velocity(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Commanded Velocity: %d\n", motor_get_target_velocity(1)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_get_target_velocity(int8_t port); - -///@} - -/// \name Motor telemetry functions -/// These functions allow programmers to collect telemetry from motors -///@{ - -/** - * Gets the actual velocity of the motor. - * - * \note A negative port negates the return value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Actual velocity: %lf\n", motor_get_actual_velocity(1)); - * delay(2); - * } - * } - * \endcode - */ -double motor_get_actual_velocity(int8_t port); - -/** - * Gets the current drawn by the motor in mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's current in mA or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Current Draw: %d\n", motor_get_current_draw(1)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_get_current_draw(int8_t port); - -/** - * Gets the direction of movement for the motor. - * - * \note A negative port number negates the return value. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return 1 for moving in the positive direction, -1 for moving in the - * negative direction, or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Direction: %d\n", motor_get_direction(1)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_get_direction(int8_t port); - -/** - * Gets the efficiency of the motor in percent. - * - * An efficiency of 100% means that the motor is moving electrically while - * drawing no electrical power, and an efficiency of 0% means that the motor - * is drawing power but not moving. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's efficiency in percent or PROS_ERR_F if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Efficiency: %d\n", motor_get_efficiency(1)); - * delay(2); - * } - * } - * \endcode - */ -double motor_get_efficiency(int8_t port); - -/** - * Checks if the motor is drawing over its current limit. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return 1 if the motor's current limit is being exceeded and 0 if the current - * limit is not exceeded, or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Current Limit Hit?: %d\n", motor_is_over_current(1)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_is_over_current(int8_t port); - -/** - * Checks if the motor's temperature is above its limit. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return 1 if the temperature limit is exceeded and 0 if the the temperature - * is below the limit, or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Temp Limit: %d\n", motor_is_over_temp(1)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_is_over_temp(int8_t port); - - - -#ifdef __cplusplus -} // namespace c -#endif - -/** - * \enum motor_fault_e_t - */ -typedef enum motor_fault_e { - /// No faults - E_MOTOR_FAULT_NO_FAULTS = 0x00, - /// Analogous to motor_is_over_temp() - E_MOTOR_FAULT_MOTOR_OVER_TEMP = 0x01, - /// Indicates a motor h-bridge fault - E_MOTOR_FAULT_DRIVER_FAULT = 0x02, - /// Analogous to motor_is_over_current() - E_MOTOR_FAULT_OVER_CURRENT = 0x04, - /// Indicates an h-bridge over current - E_MOTOR_FAULT_DRV_OVER_CURRENT = 0x08 -} motor_fault_e_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define MOTOR_FAULT_NO_FAULTS pros::E_MOTOR_FAULT_NO_FAULTS -#define MOTOR_FAULT_MOTOR_OVER_TEMP pros::E_MOTOR_FAULT_MOTOR_OVER_TEMP -#define MOTOR_FAULT_DRIVER_FAULT pros::E_MOTOR_FAULT_DRIVER_FAULT -#define MOTOR_FAULT_OVER_CURRENT pros::E_MOTOR_FAULT_DRV_OVER_CURRENT -#define MOTOR_FAULT_DRV_OVER_CURRENT pros::E_MOTOR_FAULT_DRV_OVER_CURRENT -#else -#define MOTOR_FAULT_NO_FAULTS E_MOTOR_FAULT_NO_FAULTS -#define MOTOR_FAULT_MOTOR_OVER_TEMP E_MOTOR_FAULT_MOTOR_OVER_TEMP -#define MOTOR_FAULT_DRIVER_FAULT E_MOTOR_FAULT_DRIVER_FAULT -#define MOTOR_FAULT_OVER_CURRENT E_MOTOR_FAULT_DRV_OVER_CURRENT -#define MOTOR_FAULT_DRV_OVER_CURRENT E_MOTOR_FAULT_DRV_OVER_CURRENT -#endif -#endif - -#ifdef __cplusplus -namespace c { -#endif - -/** - * Gets the faults experienced by the motor. - * - * Compare this bitfield to the bitmasks in motor_fault_e_t. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1-21 - * - * \return A bitfield containing the motor's faults. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Faults: %d\n", motor_get_faults(1)); - * delay(2); - * } - * } - * \endcode - */ -uint32_t motor_get_faults(int8_t port); - -#ifdef __cplusplus -} // namespace c -#endif - -/** - * \enum motor_flag_e_t - * - */ -typedef enum motor_flag_e { - ///There are no flags raised - E_MOTOR_FLAGS_NONE = 0x00, - /// Cannot currently communicate to the motor - E_MOTOR_FLAGS_BUSY = 0x01, - /// Analogous to motor_is_stopped() - E_MOTOR_FLAGS_ZERO_VELOCITY = 0x02, - /// Analogous to motor_get_zero_position_flag() - E_MOTOR_FLAGS_ZERO_POSITION = 0x04 -} motor_flag_e_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define MOTOR_FLAGS_NONE pros::E_MOTOR_FLAGS_NONE -#define MOTOR_FLAGS_BUSY pros::E_MOTOR_FLAGS_BUSY -#define MOTOR_FLAGS_ZERO_VELOCITY pros::E_MOTOR_FLAGS_ZERO_VELOCITY -#define MOTOR_FLAGS_ZERO_POSITION pros::E_MOTOR_FLAGS_ZERO_POSITION -#else -#define MOTOR_FLAGS_NONE E_MOTOR_FLAGS_NONE -#define MOTOR_FLAGS_BUSY E_MOTOR_FLAGS_BUSY -#define MOTOR_FLAGS_ZERO_VELOCITY E_MOTOR_FLAGS_ZERO_VELOCITY -#define MOTOR_FLAGS_ZERO_POSITION E_MOTOR_FLAGS_ZERO_POSITION -#endif -#endif - -#ifdef __cplusplus -namespace c { -#endif - -/** - * Gets the flags set by the motor's operation. - * - * Compare this bitfield to the bitmasks in motor_flag_e_t. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return A bitfield containing the motor's flags. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Flags: %d\n", motor_get_flags(1)); - * delay(2); - * } - * } - * \endcode - */ -uint32_t motor_get_flags(int8_t port); - -/** - * Gets the raw encoder count of the motor at a given timestamp. - * - * \note A negative port value negates the return value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param[in] timestamp - * A pointer to a time in milliseconds for which the encoder count - * will be returned. If NULL, the timestamp at which the encoder - * count was read will not be supplied - * - * \return The raw encoder count at the given timestamp or PROS_ERR if the - * operation failed. - * - * \b Example - * \code - * void opcontrol() { - * uint32_t now = millis(); - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Encoder Count: %d\n", motor_get_raw_position(1, &now)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_get_raw_position(int8_t port, uint32_t* const timestamp); - -/** - * Gets the absolute position of the motor in its encoder units. - * - * \note A negative port value negates the return value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's absolute position in its encoder units or PROS_ERR_F - * if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Position: %lf\n", motor_get_position(1)); - * delay(2); - * } - * } - * \endcode - */ -double motor_get_position(int8_t port); - -/** - * Gets the power drawn by the motor in Watts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's power draw in Watts or PROS_ERR_F if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * uint32_t now = millis(); - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Power: %lf\n", motor_get_power(1)); - * delay(2); - * } - * } - * \endcode - */ -double motor_get_power(int8_t port); - -/** - * Gets the temperature of the motor in degrees Celsius. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the - * operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Temperature: %lf\n", motor_get_temperature(1)); - * delay(2); - * } - * } - * \endcode - */ -double motor_get_temperature(int8_t port); - -/** - * Gets the torque generated by the motor in Newton Meters (Nm). - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, - * setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Torque: %lf\n", motor_get_torque(1)); - * delay(2); - * } - * } - * \endcode - */ -double motor_get_torque(int8_t port); - -/** - * Gets the voltage delivered to the motor in millivolts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, - * setting errno. - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * printf("Motor Voltage: %lf\n", motor_get_voltage(1)); - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_get_voltage(int8_t port); - -///@} - -/// \name Motor configuration functions -/// These functions allow programmers to configure the behavior of motors -///@{ - -#ifdef __cplusplus -} // namespace c -#endif - -/** - * \enum motor_brake_mode_e_t - * Indicates the current 'brake mode' of a motor. - */ -typedef enum motor_brake_mode_e { - /// Motor coasts when stopped, traditional behavior - E_MOTOR_BRAKE_COAST = 0, - /// Motor brakes when stopped - E_MOTOR_BRAKE_BRAKE = 1, - /// Motor actively holds position when stopped - E_MOTOR_BRAKE_HOLD = 2, - /// Invalid brake mode - E_MOTOR_BRAKE_INVALID = INT32_MAX -} motor_brake_mode_e_t; - -/** - * \enum motor_encoder_units_e_t - * Indicates the units used by the motor encoders. - */ -typedef enum motor_encoder_units_e { - /// Position is recorded as angle in degrees as a floating point number - E_MOTOR_ENCODER_DEGREES = 0, - /// Position is recorded as angle in rotations as a floating point number - E_MOTOR_ENCODER_ROTATIONS = 1, - /// Position is recorded as raw encoder ticks as a whole number - E_MOTOR_ENCODER_COUNTS = 2, - ///Invalid motor encoder units - E_MOTOR_ENCODER_INVALID = INT32_MAX -} motor_encoder_units_e_t; - -/** - * \enum motor_gearset_e_t - * Indicates the current internal gear ratio of a motor. - */ -typedef enum motor_gearset_e { - E_MOTOR_GEARSET_36 = 0, // 36:1, 100 RPM, Red gear set - E_MOTOR_GEAR_RED = E_MOTOR_GEARSET_36, // 36:1, 100 RPM, Red gear set - E_MOTOR_GEAR_100 = E_MOTOR_GEARSET_36, // 36:1, 100 RPM, Red gear set - E_MOTOR_GEARSET_18 = 1, // 18:1, 200 RPM, Green gear set - E_MOTOR_GEAR_GREEN = E_MOTOR_GEARSET_18, // 18:1, 200 RPM, Green gear set - E_MOTOR_GEAR_200 = E_MOTOR_GEARSET_18, // 18:1, 200 RPM, Green gear set - E_MOTOR_GEARSET_06 = 2, // 6:1, 600 RPM, Blue gear set - E_MOTOR_GEAR_BLUE = E_MOTOR_GEARSET_06, // 6:1, 600 RPM, Blue gear set - E_MOTOR_GEAR_600 = E_MOTOR_GEARSET_06, // 6:1, 600 RPM, Blue gear set - E_MOTOR_GEARSET_INVALID = INT32_MAX, // Error: Invalid Gearset -} motor_gearset_e_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define MOTOR_BRAKE_COAST pros::E_MOTOR_BRAKE_COAST -#define MOTOR_BRAKE_BRAKE pros::E_MOTOR_BRAKE_BRAKE -#define MOTOR_BRAKE_HOLD pros::E_MOTOR_BRAKE_HOLD -#define MOTOR_BRAKE_INVALID pros::E_MOTOR_BRAKE_INVALID -#define MOTOR_ENCODER_DEGREES pros::E_MOTOR_ENCODER_DEGREES -#define MOTOR_ENCODER_ROTATIONS pros::E_MOTOR_ENCODER_ROTATIONS -#define MOTOR_ENCODER_COUNTS pros::E_MOTOR_ENCODER_COUNTS -#define MOTOR_ENCODER_INVALID pros::E_MOTOR_ENCODER_INVALID -#define MOTOR_GEARSET_36 pros::E_MOTOR_GEARSET_36 -#define MOTOR_GEAR_RED pros::E_MOTOR_GEAR_RED -#define MOTOR_GEAR_100 pros::E_MOTOR_GEAR_100 -#define MOTOR_GEARSET_18 pros::E_MOTOR_GEARSET_18 -#define MOTOR_GEAR_GREEN pros::E_MOTOR_GEAR_GREEN -#define MOTOR_GEAR_200 pros::E_MOTOR_GEAR_200 -#define MOTOR_GEARSET_06 pros::E_MOTOR_GEARSET_06 -#define MOTOR_GEARSET_6 pros::E_MOTOR_GEARSET_06 -#define MOTOR_GEAR_BLUE pros::E_MOTOR_GEAR_BLUE -#define MOTOR_GEAR_600 pros::E_MOTOR_GEAR_600 -#define MOTOR_GEARSET_INVALID pros::E_MOTOR_GEARSET_INVALID -#else -#define MOTOR_BRAKE_COAST E_MOTOR_BRAKE_COAST -#define MOTOR_BRAKE_BRAKE E_MOTOR_BRAKE_BRAKE -#define MOTOR_BRAKE_HOLD E_MOTOR_BRAKE_HOLD -#define MOTOR_BRAKE_INVALID E_MOTOR_BRAKE_INVALID -#define MOTOR_ENCODER_DEGREES E_MOTOR_ENCODER_DEGREES -#define MOTOR_ENCODER_ROTATIONS E_MOTOR_ENCODER_ROTATIONS -#define MOTOR_ENCODER_COUNTS E_MOTOR_ENCODER_COUNTS -#define MOTOR_ENCODER_INVALID E_MOTOR_ENCODER_INVALID -#define MOTOR_GEARSET_36 E_MOTOR_GEARSET_36 -#define MOTOR_GEAR_RED E_MOTOR_GEAR_RED -#define MOTOR_GEAR_100 E_MOTOR_GEAR_100 -#define MOTOR_GEARSET_18 E_MOTOR_GEARSET_18 -#define MOTOR_GEAR_GREEN E_MOTOR_GEAR_GREEN -#define MOTOR_GEAR_200 E_MOTOR_GEAR_200 -#define MOTOR_GEARSET_06 E_MOTOR_GEARSET_06 -#define MOTOR_GEARSET_6 E_MOTOR_GEARSET_06 -#define MOTOR_GEAR_BLUE E_MOTOR_GEAR_BLUE -#define MOTOR_GEAR_600 E_MOTOR_GEAR_600 -#define MOTOR_GEARSET_INVALID E_MOTOR_GEARSET_INVALID -#endif -#endif - -/** - * \struct motor_pid_full_s_t - * - * Holds the information about a Motor's position or velocity PID controls. - * - * These values are in 4.4 format, meaning that a value of 0x20 represents 2.0, - * 0x21 represents 2.0625, 0x22 represents 2.125, etc. - */ -typedef struct motor_pid_full_s { - /// The feedforward constant - uint8_t kf; - /// The proportional constant - uint8_t kp; - /// The integral constants - uint8_t ki; - /// The derivative constant - uint8_t kd; - /// A constant used for filtering the profile acceleration - uint8_t filter; - /// The integral limit - uint16_t limit; - /// The threshold for determining if a position movement hasreached its goa l. This has no effect for velocity PID calculations. - uint8_t threshold; - /// The rate at which the PID computation is run in ms - uint8_t loopspeed; -} motor_pid_full_s_t; - -/** - * \struct motor_pid_s_t - * - * Holds just the constants for a Motor's position or velocity PID controls. - * - * These values are in 4.4 format, meaning that a value of 0x20 represents 2.0, - * 0x21 represents 2.0625, 0x22 represents 2.125, etc. - */ -typedef struct motor_pid_s { - /// The feedforward constant - uint8_t kf; - /// The proportional constant - uint8_t kp; - /// The integral constants - uint8_t ki; - /// The derivative constant - uint8_t kd; -} motor_pid_s_t; - -#ifdef __cplusplus -namespace c { -#endif - -/** - * Sets the position for the motor in its encoder units. - * - * This will be the future reference point for the motor's "absolute" position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param position - * The new reference position in its encoder units - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * - * \code - * void autonomous() { - * motor_move_absolute(1, 100, 100); // Moves 100 units forward - * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { - * // Continue running this loop as long as the motor is not within +-5 units of its goal - * delay(2); - * } - * motor_move_absolute(1, 100, 100); // This does not cause a movement - * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { - * delay(2); - * } - * - * motor_set_zero_position(1, 80); - * motor_move_absolute(1, 100, 100); // Moves 80 units forward - * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_set_zero_position(int8_t port, const double position); - -/** - * Sets the "absolute" zero position of the motor to its current position. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_move_absolute(1, 100, 100); // Moves 100 units forward - * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { - * // Continue running this loop as long as the motor is not within +-5 units of its goal - * delay(2); - * } - * motor_move_absolute(1, 100, 100); // This does not cause a movement - * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { - * delay(2); - * } - * - * motor_tare_position(1); - * motor_move_absolute(1, 100, 100); // Moves 100 units forward - * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_tare_position(int8_t port); - -/** - * Sets one of motor_brake_mode_e_t to the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param mode - * The motor_brake_mode_e_t to set for the motor - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void initialize() { - * motor_set_brake_mode(1, E_MOTOR_BRAKE_HOLD); - * printf("Brake Mode: %d\n", motor_get_brake_mode(1)); - * } - * \endcode - */ -int32_t motor_set_brake_mode(int8_t port, const motor_brake_mode_e_t mode); - -/** - * Sets the current limit for the motor in mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param limit - * The new current limit in mA - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * motor_set_current_limit(1, 1000); - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * // The motor will reduce its output at 1000 mA instead of the default 2500 mA - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_set_current_limit(int8_t port, const int32_t limit); - -/** - * Sets one of motor_encoder_units_e_t for the motor encoder. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param units - * The new motor encoder units - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void initialize() { - * motor_set_encoder_units(1, E_MOTOR_ENCODER_DEGREES); - * printf("Encoder Units: %d\n", motor_get_encoder_units(1)); - * } - * \endcode - */ -int32_t motor_set_encoder_units(int8_t port, const motor_encoder_units_e_t units); - -/** - * Sets one of motor_gearset_e_t for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param gearset - * The new motor gearset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void initialize() { - * motor_set_gearing(1, E_MOTOR_GEARSET_06); - * printf("Brake Mode: %d\n", motor_get_gearing(1)); - * } - * \endcode - */ -int32_t motor_set_gearing(int8_t port, const motor_gearset_e_t gearset); - -/** - * Sets the voltage limit for the motor in Volts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * \param limit - * The new voltage limit in Volts - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * motor_set_voltage_limit(1, 10000); - * while (true) { - * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); - * // The motor will not output more than 10 V - * delay(2); - * } - * } - * \endcode - */ -int32_t motor_set_voltage_limit(int8_t port, const int32_t limit); - -/** - * Gets the brake mode that was set for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return One of motor_brake_mode_e_t, according to what was set for the motor, - * or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. - * - * \b Example - * \code - * void initialize() { - * motor_set_brake_mode(1, E_MOTOR_BRAKE_HOLD); - * printf("Brake Mode: %d\n", motor_get_brake_mode(1)); - * } - * \endcode - */ -motor_brake_mode_e_t motor_get_brake_mode(int8_t port); - -/** - * Gets the current limit for the motor in mA. - * - * The default value is 2500 mA. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's current limit in mA or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example - * \code - * void initialize() { - * printf("Motor Current Limit: %d\n", motor_get_current_limit(1)); - * // Prints "Motor Current Limit: 2500" - * } - * \endcode - */ -int32_t motor_get_current_limit(int8_t port); - -/** - * Gets the encoder units that were set for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return One of motor_encoder_units_e_t according to what is set for the motor - * or E_MOTOR_ENCODER_INVALID if the operation failed. - */ -motor_encoder_units_e_t motor_get_encoder_units(int8_t port); - -/** - * Gets the gearset that was set for the motor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return One of motor_gearset_e_t according to what is set for the motor, - * or E_GEARSET_INVALID if the operation failed. - * - * \b Example - * \code - * void initialize() { - * printf("Motor Encoder Units: %d\n", motor_get_encoder_units(1)); - * // Prints E_MOTOR_ENCODER_DEGREES by default - * } - * \endcode - */ -motor_gearset_e_t motor_get_gearing(int8_t port); - -/** - * Gets the voltage limit set by the user. - * - * Default value is 0V, which means that there is no software limitation imposed - * on the voltage. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors - * - * \return The motor's voltage limit in V or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example - * \code - * void initialize() { - * printf("Motor Voltage Limit: %d\n", motor_get_voltage_limit(1)); - * // Prints 0 by default, indicating no limit - * } - * \endcode - */ -int32_t motor_get_voltage_limit(int8_t port); - -///@} - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - -#endif // _PROS_MOTORS_H_ +/** + * \file pros/motors.h + * \ingroup c-motors + * + * Contains prototypes for the V5 Motor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-motors Motors C API + * \note Additional example code for this module can be found in its [Tutorial](@ref motors). + */ + +#ifndef _PROS_MOTORS_H_ +#define _PROS_MOTORS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-motors + */ + +/** + * \addtogroup c-motors + * @{ + */ + +/// \name Motor movement functions +/// These functions allow programmers to make motors move +///@{ + +/** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is analogous + * to use of motor_move_voltage(). + * + * \note This function will not respect brake modes, and simply sets the voltage to the desired value. + * + * \note A negative port will negate the input voltage + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_move(int8_t port, int32_t voltage); + +/** + * Stops the motor using the currently configured brake mode. + * + * This function sets motor velocity to zero, which will cause it to act + * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, + * this function may behave differently than calling motor_move_absolute(port, 0) + * or motor_move_relative(port, 0). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move(1, 127); + * delay(1000); + * motor_break(1); + * } + * \endcode + */ +int32_t motor_brake(int8_t port); + +/** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with motor_set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block program + * execution until the movement finishes. The example code shows how to block until a movement is finished. + * + * \note A negative port number will negate the target position + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * motor_move_absolute(1, 100, 100); // This will not cause a movement + * while(!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * delay(2); + * } + * + * motor_tare_position(1); + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_move_absolute(int8_t port, double position, const int32_t velocity); + +/** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * motor_get_position(). Providing 10.0 as the position parameter would result + * in the motor moving clockwise 10 units, no matter what the current position + * is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. The example code shows how to + * block until a movement is finished. + * + * \note A negative port will negate the target position + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_relative(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) < 105) && (motor_get_position(1) > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * + * motor_move_relative(1, 100, 100); // Also moves 100 units forward + * while (!((motor_get_position(1) < 205) && (motor_get_position(1) > 195))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_move_relative(int8_t port, double position, const int32_t velocity); + +/** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the gearset + * used for the motor. This results in a range of +-100 for E_MOTOR_GEARSET_36, + * +-200 for E_MOTOR_GEARSET_18, and +-600 for E_MOTOR_GEARSET_6. The velocity + * is held with PID to ensure consistent speed, as opposed to setting the + * motor's voltage. + * + * \note A negative port will negate the velocity + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_velocity(1, 100); + * delay(1000); // Move at 100 RPM for 1 second + * motor_move_velocity(1, 0); + * } + * \endcode + */ +int32_t motor_move_velocity(int8_t port, const int32_t velocity); + +/** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts + * + * \note A negative port negates the voltage + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \note This function will not respect brake modes, and simply sets the + * voltage to the desired value. + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_voltage(1, 12000); + * delay(1000); // Move at max voltage for 1 second + * motor_move_voltage(1, 0); + * } + * \endcode + */ +int32_t motor_move_voltage(int8_t port, const int32_t voltage); + +/** + * Changes the output velocity for a profiled movement (motor_move_absolute or + * motor_move_relative). This will have no effect if the motor is not following + * a profiled movement. + * + * \note A negative port negates the velocity + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param velocity + * The new motor velocity from +-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); + * delay(100); + * motor_modify_profiled_velocity(1, 0); // Stop the motor early + * } + * \endcode + */ +int32_t motor_modify_profiled_velocity(int8_t port, const int32_t velocity); + +/** + * Gets the target position set for the motor by the user. + * + * \note A negative port negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); + * printf("Motor Target: %d\n", motor_get_target_position(1)); + * // Prints 100 + * } + * \endcode + */ +double motor_get_target_position(int8_t port); + +/** + * Gets the velocity commanded to the motor by the user. + * + * \note A negative port negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or PROS_ERR + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move_velocity(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Commanded Velocity: %d\n", motor_get_target_velocity(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_target_velocity(int8_t port); + +///@} + +/// \name Motor telemetry functions +/// These functions allow programmers to collect telemetry from motors +///@{ + +/** + * Gets the actual velocity of the motor. + * + * \note A negative port negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Actual velocity: %lf\n", motor_get_actual_velocity(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_actual_velocity(int8_t port); + +/** + * Gets the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Current Draw: %d\n", motor_get_current_draw(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_current_draw(int8_t port); + +/** + * Gets the direction of movement for the motor. + * + * \note A negative port number negates the return value. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Direction: %d\n", motor_get_direction(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_direction(int8_t port); + +/** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Efficiency: %d\n", motor_get_efficiency(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_efficiency(int8_t port); + +/** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the motor's current limit is being exceeded and 0 if the current + * limit is not exceeded, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Current Limit Hit?: %d\n", motor_is_over_current(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_is_over_current(int8_t port); + +/** + * Checks if the motor's temperature is above its limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the temperature limit is exceeded and 0 if the the temperature + * is below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Temp Limit: %d\n", motor_is_over_temp(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_is_over_temp(int8_t port); + + + +#ifdef __cplusplus +} // namespace c +#endif + +/** + * \enum motor_fault_e_t + */ +typedef enum motor_fault_e { + /// No faults + E_MOTOR_FAULT_NO_FAULTS = 0x00, + /// Analogous to motor_is_over_temp() + E_MOTOR_FAULT_MOTOR_OVER_TEMP = 0x01, + /// Indicates a motor h-bridge fault + E_MOTOR_FAULT_DRIVER_FAULT = 0x02, + /// Analogous to motor_is_over_current() + E_MOTOR_FAULT_OVER_CURRENT = 0x04, + /// Indicates an h-bridge over current + E_MOTOR_FAULT_DRV_OVER_CURRENT = 0x08 +} motor_fault_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define MOTOR_FAULT_NO_FAULTS pros::E_MOTOR_FAULT_NO_FAULTS +#define MOTOR_FAULT_MOTOR_OVER_TEMP pros::E_MOTOR_FAULT_MOTOR_OVER_TEMP +#define MOTOR_FAULT_DRIVER_FAULT pros::E_MOTOR_FAULT_DRIVER_FAULT +#define MOTOR_FAULT_OVER_CURRENT pros::E_MOTOR_FAULT_DRV_OVER_CURRENT +#define MOTOR_FAULT_DRV_OVER_CURRENT pros::E_MOTOR_FAULT_DRV_OVER_CURRENT +#else +#define MOTOR_FAULT_NO_FAULTS E_MOTOR_FAULT_NO_FAULTS +#define MOTOR_FAULT_MOTOR_OVER_TEMP E_MOTOR_FAULT_MOTOR_OVER_TEMP +#define MOTOR_FAULT_DRIVER_FAULT E_MOTOR_FAULT_DRIVER_FAULT +#define MOTOR_FAULT_OVER_CURRENT E_MOTOR_FAULT_DRV_OVER_CURRENT +#define MOTOR_FAULT_DRV_OVER_CURRENT E_MOTOR_FAULT_DRV_OVER_CURRENT +#endif +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Faults: %d\n", motor_get_faults(1)); + * delay(2); + * } + * } + * \endcode + */ +uint32_t motor_get_faults(int8_t port); + +#ifdef __cplusplus +} // namespace c +#endif + +/** + * \enum motor_flag_e_t + * + */ +typedef enum motor_flag_e { + ///There are no flags raised + E_MOTOR_FLAGS_NONE = 0x00, + /// Cannot currently communicate to the motor + E_MOTOR_FLAGS_BUSY = 0x01, + /// Analogous to motor_is_stopped() + E_MOTOR_FLAGS_ZERO_VELOCITY = 0x02, + /// Analogous to motor_get_zero_position_flag() + E_MOTOR_FLAGS_ZERO_POSITION = 0x04 +} motor_flag_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define MOTOR_FLAGS_NONE pros::E_MOTOR_FLAGS_NONE +#define MOTOR_FLAGS_BUSY pros::E_MOTOR_FLAGS_BUSY +#define MOTOR_FLAGS_ZERO_VELOCITY pros::E_MOTOR_FLAGS_ZERO_VELOCITY +#define MOTOR_FLAGS_ZERO_POSITION pros::E_MOTOR_FLAGS_ZERO_POSITION +#else +#define MOTOR_FLAGS_NONE E_MOTOR_FLAGS_NONE +#define MOTOR_FLAGS_BUSY E_MOTOR_FLAGS_BUSY +#define MOTOR_FLAGS_ZERO_VELOCITY E_MOTOR_FLAGS_ZERO_VELOCITY +#define MOTOR_FLAGS_ZERO_POSITION E_MOTOR_FLAGS_ZERO_POSITION +#endif +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Flags: %d\n", motor_get_flags(1)); + * delay(2); + * } + * } + * \endcode + */ +uint32_t motor_get_flags(int8_t port); + +/** + * Gets the raw encoder count of the motor at a given timestamp. + * + * \note A negative port value negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param[in] timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Encoder Count: %d\n", motor_get_raw_position(1, &now)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_raw_position(int8_t port, uint32_t* const timestamp); + +/** + * Gets the absolute position of the motor in its encoder units. + * + * \note A negative port value negates the return value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Position: %lf\n", motor_get_position(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_position(int8_t port); + +/** + * Gets the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Power: %lf\n", motor_get_power(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_power(int8_t port); + +/** + * Gets the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Temperature: %lf\n", motor_get_temperature(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_temperature(int8_t port); + +/** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Torque: %lf\n", motor_get_torque(1)); + * delay(2); + * } + * } + * \endcode + */ +double motor_get_torque(int8_t port); + +/** + * Gets the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * printf("Motor Voltage: %lf\n", motor_get_voltage(1)); + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_get_voltage(int8_t port); + +///@} + +/// \name Motor configuration functions +/// These functions allow programmers to configure the behavior of motors +///@{ + +#ifdef __cplusplus +} // namespace c +#endif + +/** + * \enum motor_brake_mode_e_t + * Indicates the current 'brake mode' of a motor. + */ +typedef enum motor_brake_mode_e { + /// Motor coasts when stopped, traditional behavior + E_MOTOR_BRAKE_COAST = 0, + /// Motor brakes when stopped + E_MOTOR_BRAKE_BRAKE = 1, + /// Motor actively holds position when stopped + E_MOTOR_BRAKE_HOLD = 2, + /// Invalid brake mode + E_MOTOR_BRAKE_INVALID = INT32_MAX +} motor_brake_mode_e_t; + +/** + * \enum motor_encoder_units_e_t + * Indicates the units used by the motor encoders. + */ +typedef enum motor_encoder_units_e { + /// Position is recorded as angle in degrees as a floating point number + E_MOTOR_ENCODER_DEGREES = 0, + /// Position is recorded as angle in rotations as a floating point number + E_MOTOR_ENCODER_ROTATIONS = 1, + /// Position is recorded as raw encoder ticks as a whole number + E_MOTOR_ENCODER_COUNTS = 2, + ///Invalid motor encoder units + E_MOTOR_ENCODER_INVALID = INT32_MAX +} motor_encoder_units_e_t; + +/** + * \enum motor_gearset_e_t + * Indicates the current internal gear ratio of a motor. + */ +typedef enum motor_gearset_e { + E_MOTOR_GEARSET_36 = 0, // 36:1, 100 RPM, Red gear set + E_MOTOR_GEAR_RED = E_MOTOR_GEARSET_36, // 36:1, 100 RPM, Red gear set + E_MOTOR_GEAR_100 = E_MOTOR_GEARSET_36, // 36:1, 100 RPM, Red gear set + E_MOTOR_GEARSET_18 = 1, // 18:1, 200 RPM, Green gear set + E_MOTOR_GEAR_GREEN = E_MOTOR_GEARSET_18, // 18:1, 200 RPM, Green gear set + E_MOTOR_GEAR_200 = E_MOTOR_GEARSET_18, // 18:1, 200 RPM, Green gear set + E_MOTOR_GEARSET_06 = 2, // 6:1, 600 RPM, Blue gear set + E_MOTOR_GEAR_BLUE = E_MOTOR_GEARSET_06, // 6:1, 600 RPM, Blue gear set + E_MOTOR_GEAR_600 = E_MOTOR_GEARSET_06, // 6:1, 600 RPM, Blue gear set + E_MOTOR_GEARSET_INVALID = INT32_MAX, // Error: Invalid Gearset +} motor_gearset_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define MOTOR_BRAKE_COAST pros::E_MOTOR_BRAKE_COAST +#define MOTOR_BRAKE_BRAKE pros::E_MOTOR_BRAKE_BRAKE +#define MOTOR_BRAKE_HOLD pros::E_MOTOR_BRAKE_HOLD +#define MOTOR_BRAKE_INVALID pros::E_MOTOR_BRAKE_INVALID +#define MOTOR_ENCODER_DEGREES pros::E_MOTOR_ENCODER_DEGREES +#define MOTOR_ENCODER_ROTATIONS pros::E_MOTOR_ENCODER_ROTATIONS +#define MOTOR_ENCODER_COUNTS pros::E_MOTOR_ENCODER_COUNTS +#define MOTOR_ENCODER_INVALID pros::E_MOTOR_ENCODER_INVALID +#define MOTOR_GEARSET_36 pros::E_MOTOR_GEARSET_36 +#define MOTOR_GEAR_RED pros::E_MOTOR_GEAR_RED +#define MOTOR_GEAR_100 pros::E_MOTOR_GEAR_100 +#define MOTOR_GEARSET_18 pros::E_MOTOR_GEARSET_18 +#define MOTOR_GEAR_GREEN pros::E_MOTOR_GEAR_GREEN +#define MOTOR_GEAR_200 pros::E_MOTOR_GEAR_200 +#define MOTOR_GEARSET_06 pros::E_MOTOR_GEARSET_06 +#define MOTOR_GEARSET_6 pros::E_MOTOR_GEARSET_06 +#define MOTOR_GEAR_BLUE pros::E_MOTOR_GEAR_BLUE +#define MOTOR_GEAR_600 pros::E_MOTOR_GEAR_600 +#define MOTOR_GEARSET_INVALID pros::E_MOTOR_GEARSET_INVALID +#else +#define MOTOR_BRAKE_COAST E_MOTOR_BRAKE_COAST +#define MOTOR_BRAKE_BRAKE E_MOTOR_BRAKE_BRAKE +#define MOTOR_BRAKE_HOLD E_MOTOR_BRAKE_HOLD +#define MOTOR_BRAKE_INVALID E_MOTOR_BRAKE_INVALID +#define MOTOR_ENCODER_DEGREES E_MOTOR_ENCODER_DEGREES +#define MOTOR_ENCODER_ROTATIONS E_MOTOR_ENCODER_ROTATIONS +#define MOTOR_ENCODER_COUNTS E_MOTOR_ENCODER_COUNTS +#define MOTOR_ENCODER_INVALID E_MOTOR_ENCODER_INVALID +#define MOTOR_GEARSET_36 E_MOTOR_GEARSET_36 +#define MOTOR_GEAR_RED E_MOTOR_GEAR_RED +#define MOTOR_GEAR_100 E_MOTOR_GEAR_100 +#define MOTOR_GEARSET_18 E_MOTOR_GEARSET_18 +#define MOTOR_GEAR_GREEN E_MOTOR_GEAR_GREEN +#define MOTOR_GEAR_200 E_MOTOR_GEAR_200 +#define MOTOR_GEARSET_06 E_MOTOR_GEARSET_06 +#define MOTOR_GEARSET_6 E_MOTOR_GEARSET_06 +#define MOTOR_GEAR_BLUE E_MOTOR_GEAR_BLUE +#define MOTOR_GEAR_600 E_MOTOR_GEAR_600 +#define MOTOR_GEARSET_INVALID E_MOTOR_GEARSET_INVALID +#endif +#endif + +/** + * \struct motor_pid_full_s_t + * + * Holds the information about a Motor's position or velocity PID controls. + * + * These values are in 4.4 format, meaning that a value of 0x20 represents 2.0, + * 0x21 represents 2.0625, 0x22 represents 2.125, etc. + */ +typedef struct motor_pid_full_s { + /// The feedforward constant + uint8_t kf; + /// The proportional constant + uint8_t kp; + /// The integral constants + uint8_t ki; + /// The derivative constant + uint8_t kd; + /// A constant used for filtering the profile acceleration + uint8_t filter; + /// The integral limit + uint16_t limit; + /// The threshold for determining if a position movement hasreached its goa l. This has no effect for velocity PID calculations. + uint8_t threshold; + /// The rate at which the PID computation is run in ms + uint8_t loopspeed; +} motor_pid_full_s_t; + +/** + * \struct motor_pid_s_t + * + * Holds just the constants for a Motor's position or velocity PID controls. + * + * These values are in 4.4 format, meaning that a value of 0x20 represents 2.0, + * 0x21 represents 2.0625, 0x22 represents 2.125, etc. + */ +typedef struct motor_pid_s { + /// The feedforward constant + uint8_t kf; + /// The proportional constant + uint8_t kp; + /// The integral constants + uint8_t ki; + /// The derivative constant + uint8_t kd; +} motor_pid_s_t; + +#ifdef __cplusplus +namespace c { +#endif + +/** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param position + * The new reference position in its encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * motor_move_absolute(1, 100, 100); // This does not cause a movement + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * + * motor_set_zero_position(1, 80); + * motor_move_absolute(1, 100, 100); // Moves 80 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_set_zero_position(int8_t port, const double position); + +/** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * delay(2); + * } + * motor_move_absolute(1, 100, 100); // This does not cause a movement + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * + * motor_tare_position(1); + * motor_move_absolute(1, 100, 100); // Moves 100 units forward + * while (!((motor_get_position(1) - 100 < 105) && (motor_get_position(1) - 100 > 95))) { + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_tare_position(int8_t port); + +/** + * Sets one of motor_brake_mode_e_t to the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param mode + * The motor_brake_mode_e_t to set for the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_brake_mode(1, E_MOTOR_BRAKE_HOLD); + * printf("Brake Mode: %d\n", motor_get_brake_mode(1)); + * } + * \endcode + */ +int32_t motor_set_brake_mode(int8_t port, const motor_brake_mode_e_t mode); + +/** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param limit + * The new current limit in mA + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * motor_set_current_limit(1, 1000); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_set_current_limit(int8_t port, const int32_t limit); + +/** + * Sets one of motor_encoder_units_e_t for the motor encoder. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_encoder_units(1, E_MOTOR_ENCODER_DEGREES); + * printf("Encoder Units: %d\n", motor_get_encoder_units(1)); + * } + * \endcode + */ +int32_t motor_set_encoder_units(int8_t port, const motor_encoder_units_e_t units); + +/** + * Sets one of motor_gearset_e_t for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_gearing(1, E_MOTOR_GEARSET_06); + * printf("Brake Mode: %d\n", motor_get_gearing(1)); + * } + * \endcode + */ +int32_t motor_set_gearing(int8_t port, const motor_gearset_e_t gearset); + +/** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor_set_voltage_limit(1, 10000); + * while (true) { + * motor_move(1, controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y)); + * // The motor will not output more than 10 V + * delay(2); + * } + * } + * \endcode + */ +int32_t motor_set_voltage_limit(int8_t port, const int32_t limit); + +/** + * Gets the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_brake_mode_e_t, according to what was set for the motor, + * or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * motor_set_brake_mode(1, E_MOTOR_BRAKE_HOLD); + * printf("Brake Mode: %d\n", motor_get_brake_mode(1)); + * } + * \endcode + */ +motor_brake_mode_e_t motor_get_brake_mode(int8_t port); + +/** + * Gets the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Current Limit: %d\n", motor_get_current_limit(1)); + * // Prints "Motor Current Limit: 2500" + * } + * \endcode + */ +int32_t motor_get_current_limit(int8_t port); + +/** + * Gets the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_encoder_units_e_t according to what is set for the motor + * or E_MOTOR_ENCODER_INVALID if the operation failed. + */ +motor_encoder_units_e_t motor_get_encoder_units(int8_t port); + +/** + * Gets the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return One of motor_gearset_e_t according to what is set for the motor, + * or E_GEARSET_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Encoder Units: %d\n", motor_get_encoder_units(1)); + * // Prints E_MOTOR_ENCODER_DEGREES by default + * } + * \endcode + */ +motor_gearset_e_t motor_get_gearing(int8_t port); + +/** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation imposed + * on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports |1-21|. + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1 to 21, or from -21 to -1 for reversed motors + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * printf("Motor Voltage Limit: %d\n", motor_get_voltage_limit(1)); + * // Prints 0 by default, indicating no limit + * } + * \endcode + */ +int32_t motor_get_voltage_limit(int8_t port); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_MOTORS_H_ diff --git a/include/pros/motors.hpp b/include/pros/motors.hpp index 850779a..f0de7eb 100644 --- a/include/pros/motors.hpp +++ b/include/pros/motors.hpp @@ -399,29 +399,6 @@ class Motor : public AbstractMotor, public Device { */ double get_target_position(const std::uint8_t index = 0) const; - /** - * Gets a vector containing the target position set for the motor by the user - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * - * \return A vector containing the target position in its encoder units or PROS_ERR_F if the - * operation failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * pros::Motor motor (1); - * motor.move_absolute(100, 100); - * std::cout << "Motor Target: " << motor.get_target_position_all()[0]; - * // Prints 100 - * } - * \endcode - */ - std::vector get_target_position_all(void) const; - /** * Gets the velocity commanded to the motor by the user at the index specified. * @@ -457,32 +434,6 @@ class Motor : public AbstractMotor, public Device { */ std::int32_t get_target_velocity(const std::uint8_t index = 0) const; - /** - * Gets a vector containing the velocity commanded to the motor by the user - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing the commanded motor velocity from +-100, - * +-200, or +-600, or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); - * std::cout << "Motor Velocity: " << motor.get_target_velocity_all()[0]; - * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y - * pros::delay(2); - * } - * } - * \endcode - */ - std::vector get_target_velocity_all(void) const; - ///@} /// \name Motor telemetry functions @@ -522,33 +473,6 @@ class Motor : public AbstractMotor, public Device { */ double get_actual_velocity(const std::uint8_t index = 0) const; - - /** - * Gets a vector containing the actual velocity commanded of the motor - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing the motor's actual velocity in RPM or PROS_ERR_F - * if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); - * std::cout << "Motor Velocity: " << motor.get_actual_velocity_all()[0]; - * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y - * pros::delay(2); - * } - * } - * \endcode - */ - std::vector get_actual_velocity_all(void) const; - /** * Gets the current drawn by the motor in mA. * @@ -585,18 +509,26 @@ class Motor : public AbstractMotor, public Device { */ std::int32_t get_current_draw(const std::uint8_t index = 0) const; - /** - * Gets a vector containing the current drawn by the motor in mA. + * Gets the direction of movement for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor * + * EOVERFLOW - The index is non 0 * - * \return A vector conatining the motor's current in mA or PROS_ERR if the operation failed, - * setting errno. + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. * * \b Example * \code @@ -605,17 +537,22 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Current Draw: " << motor.get_current_draw_all()[0]; + * std::cout << "Motor Direction: " << motor.get_direction(); * pros::delay(2); * } * } * \endcode */ - std::vector get_current_draw_all(void) const; + std::int32_t get_direction(const std::uint8_t index = 0) const; /** - * Gets the direction of movement for the motor. + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. * + * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class * for motors and motor groups @@ -630,9 +567,9 @@ class Motor : public AbstractMotor, public Device { * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * \return 1 for moving in the positive direction, -1 for moving in the - * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. * * \b Example * \code @@ -641,26 +578,36 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Direction: " << motor.get_direction(); + * std::cout << "Motor Efficiency: " << motor.get_efficiency(); * pros::delay(2); * } * } * \endcode */ - std::int32_t get_direction(const std::uint8_t index = 0) const; + double get_efficiency(const std::uint8_t index = 0) const; /** - * Gets a vector containing the direction of movement for the motor. + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor * + * EOVERFLOW - The index is non 0 * - * \return A vecotr containing 1 for moving in the positive direction, -1 for moving in the - * negative direction, and PROS_ERR if the operation failed, setting errno. + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * + * \return A bitfield containing the motor's faults. * * \b Example * \code @@ -669,22 +616,18 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Direction: " << motor.get_direction_all()[0]; - * pros::delay(2); + * std::cout << "Motor Faults: " << motor.get_faults();pros::delay(2); * } * } * \endcode */ - std::vector get_direction_all(void) const; - + std::uint32_t get_faults(const std::uint8_t index = 0) const; + /** - * Gets the efficiency of the motor in percent. + * Gets the flags set by the motor's operation. * - * An efficiency of 100% means that the motor is moving electrically while - * drawing no electrical power, and an efficiency of 0% means that the motor - * is drawing power but not moving. + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. * - * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class * for motors and motor groups @@ -700,8 +643,7 @@ class Motor : public AbstractMotor, public Device { * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return The motor's efficiency in percent or PROS_ERR_F if the operation - * failed, setting errno. + * \return A bitfield containing the motor's flags. * * \b Example * \code @@ -710,29 +652,34 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * std::cout << "Motor Faults: " << motor.get_faults(); * pros::delay(2); * } * } * \endcode */ - double get_efficiency(const std::uint8_t index = 0) const; + std::uint32_t get_flags(const std::uint8_t index = 0) const; /** - * Gets a vector containing the efficiency of the motor in percent. + * Gets the absolute position of the motor in its encoder units. * - * An efficiency of 100% means that the motor is moving electrically while - * drawing no electrical power, and an efficiency of 0% means that the motor - * is drawing power but not moving. + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index * - * \return A vector containing The motor's efficiency in percent or PROS_ERR_F if the operation - * failed, setting errno. + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. * * \b Example * \code @@ -741,18 +688,16 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * std::cout << "Motor Position: " << motor.get_position(); * pros::delay(2); * } * } * \endcode */ - std::vector get_efficiency_all(void) const; + double get_position(const std::uint8_t index = 0) const; /** - * Gets the faults experienced by the motor. - * - * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * Gets the power drawn by the motor in Watts. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -768,9 +713,9 @@ class Motor : public AbstractMotor, public Device { * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * - * \return A bitfield containing the motor's faults. + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. * * \b Example * \code @@ -779,45 +724,62 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Faults: " << motor.get_faults();pros::delay(2); + * std::cout << "Motor Power: " << motor.get_power(); + * pros::delay(2); * } * } * \endcode */ - std::uint32_t get_faults(const std::uint8_t index = 0) const; + double get_power(const std::uint8_t index = 0) const; /** - * Gets a vector of the faults experienced by the motor. + * Gets the raw encoder count of the motor at a given timestamp. * - * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index * - * \return A bitfield containing the motor's faults. + * + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. * * \b Example * \code * void opcontrol() { + * std::uint32_t now = pros::millis(); * pros::Motor motor (1); * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Faults: " << motor.get_faults_all()[0]; - * pros::delay(2); + * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * pros::delay(2); * } * } * \endcode */ - std::vector get_faults_all(void) const; - + std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const; + /** - * Gets the flags set by the motor's operation. - * - * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. - * + * Gets the temperature of the motor in degrees Celsius. + * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class * for motors and motor groups @@ -833,7 +795,8 @@ class Motor : public AbstractMotor, public Device { * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return A bitfield containing the motor's flags. + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. * * \b Example * \code @@ -842,26 +805,34 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Faults: " << motor.get_faults(); + * std::cout << "Motor Temperature: " << motor.get_temperature(); * pros::delay(2); * } * } * \endcode */ - std::uint32_t get_flags(const std::uint8_t index = 0) const; + double get_temperature(const std::uint8_t index = 0) const; /** - * Gets a vector of the flags set by the motor's operation. + * Gets the torque generated by the motor in Newton Meters (Nm). * - * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index * - * - * \return A bitfield containing the motor's flags. + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. * * \b Example * \code @@ -870,16 +841,16 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Faults: " << motor.get_faults_all()[0]; + * std::cout << "Motor Torque: " << motor.get_torque(); * pros::delay(2); * } * } * \endcode */ - std::vector get_flags_all(void) const; + double get_torque(const std::uint8_t index = 0) const; /** - * Gets the absolute position of the motor in its encoder units. + * Gets the voltage delivered to the motor in millivolts. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -895,9 +866,9 @@ class Motor : public AbstractMotor, public Device { * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * \return The motor's absolute position in its encoder units or PROS_ERR_F - * if the operation failed, setting errno. + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. * * \b Example * \code @@ -906,25 +877,35 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Position: " << motor.get_position(); + * std::cout << "Motor Voltage: " << motor.get_voltage(); * pros::delay(2); * } * } * \endcode */ - double get_position(const std::uint8_t index = 0) const; + std::int32_t get_voltage(const std::uint8_t index = 0) const; /** - * Gets a vector containing the absolute position of the motor in its encoder units. + * Checks if the motor is drawing over its current limit. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor - + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index * - * \return A vector containing the motor's absolute position in its encoder units or PROS_ERR_F - * if the operation failed, setting errno. + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. * * \b Example * \code @@ -933,16 +914,16 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Position: " << motor.get_position_all()[0]; + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current(); * pros::delay(2); * } * } * \endcode */ - std::vector get_position_all(void) const; + std::int32_t is_over_current(const std::uint8_t index = 0) const; /** - * Gets the power drawn by the motor in Watts. + * Gets the temperature limit flag for the motor. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -959,8 +940,8 @@ class Motor : public AbstractMotor, public Device { * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return The motor's power draw in Watts or PROS_ERR_F if the operation - * failed, setting errno. + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. * * \b Example * \code @@ -969,42 +950,54 @@ class Motor : public AbstractMotor, public Device { * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Power: " << motor.get_power(); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); * pros::delay(2); * } * } * \endcode */ - double get_power(const std::uint8_t index = 0) const; + std::int32_t is_over_temp(const std::uint8_t index = 0) const; + + ///@} + + /// \name Motor configuration functions + /// These functions allow programmers to configure the behavior of motors + ///@{ /** - * Gets a vector containing the power drawn by the motor in Watts. + * Gets the brake mode that was set for the motor. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor * - * \return A vector containing the motor's power draw in Watts or PROS_ERR_F if the operation - * failed, setting errno. + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return One of Motor_Brake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Power: " << motor.get_power_all()[0]; - * pros::delay(2); - * } + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); * } * \endcode */ - std::vector get_power_all(void) const; + MotorBrake get_brake_mode(const std::uint8_t index = 0) const; /** - * Gets the raw encoder count of the motor at a given timestamp. + * Gets the current limit for the motor in mA. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1017,72 +1010,60 @@ class Motor : public AbstractMotor, public Device { * * EOVERFLOW - The index is non 0 * - * - * \param timestamp - * A pointer to a time in milliseconds for which the encoder count - * will be returned. If NULL, the timestamp at which the encoder - * count was read will not be supplied - * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * - * - * \return The raw encoder count at the given timestamp or PROS_ERR if the - * operation failed. + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. * * \b Example * \code * void opcontrol() { - * std::uint32_t now = pros::millis(); * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * std::cout << "Motor Current Limit: " << motor.get_current_limit(); * pros::delay(2); * } * } * \endcode */ - std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const; + std::int32_t get_current_limit(const std::uint8_t index = 0) const; + /** - * Gets a vector of the raw encoder count of the motor at a given timestamp. + * Gets the encoder units that were set for the motor. * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor * - * \param timestamp - * A pointer to a time in milliseconds for which the encoder count - * will be returned. If NULL, the timestamp at which the encoder - * count was read will not be supplied + * EOVERFLOW - The index is non 0 * - * \return A vector containing the raw encoder count at the given timestamp or PROS_ERR if the - * operation failed. + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return One of Motor_Units according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. * * \b Example * \code - * void opcontrol() { - * std::uint32_t now = pros::millis(); - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Position: " << motor.get_raw_position(&now); - * pros::delay(2); - * } + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << motor.get_encoder_units(); * } * \endcode */ - std::vector get_raw_position_all(std::uint32_t* const timestamp) const; + MotorUnits get_encoder_units(const std::uint8_t index = 0) const; /** - * Gets the temperature of the motor in degrees Celsius. - + * Gets the gearset that was set for the motor. + * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class * for motors and motor groups @@ -1098,51 +1079,52 @@ class Motor : public AbstractMotor, public Device { * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the - * operation failed, setting errno. + * \return One of Motor_Gears according to what is set for the motor, + * or pros::Motor_Gears::invalid if the operation failed. * * \b Example * \code - * void opcontrol() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Temperature: " << motor.get_temperature(); - * pros::delay(2); - * } + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << motor.get_gearing(); * } * \endcode */ - double get_temperature(const std::uint8_t index = 0) const; - + MotorGears get_gearing(const std::uint8_t index = 0) const; + /** - * Gets a vector of the temperature of the motor in degrees Celsius. + * Gets the voltage limit set by the user. * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * * This function uses the following values of errno when an error state is * reached: + * * ENODEV - The port cannot be configured as a motor - * - * \return A vector contaioning the motor's temperature in degrees Celsius - * or PROS_ERR_F if the operation failed, setting errno. + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Temperature: " << motor.get_temperature_all()[0]; - * pros::delay(2); - * } + * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit(); * } * \endcode */ - std::vector get_temperature_all(void) const; + std::int32_t get_voltage_limit(const std::uint8_t index = 0) const; /** - * Gets the torque generated by the motor in Newton Meters (Nm). + * Gets whether the motor is reversed or not * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1150,61 +1132,63 @@ class Motor : public AbstractMotor, public Device { * * This function uses the following values of errno when an error state is * reached: - * - * ENODEV - The port cannot be configured as a motor - * + * * EOVERFLOW - The index is non 0 * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, - * setting errno. + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Torque: " << motor.get_torque(); - * pros::delay(2); - * } + * std::cout << "Is the motor reversed? " << motor.is_reversed(); + * // Prints "0" * } * \endcode */ - double get_torque(const std::uint8_t index = 0) const; + std::int32_t is_reversed(const std::uint8_t index = 0) const; /** - * Gets a vector of the torque generated by the motor in Newton Meters (Nm). - * + * Sets one of Motor_Brake to the motor. + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * * This function uses the following values of errno when an error state is * reached: + * * ENODEV - The port cannot be configured as a motor * - * \return A vector containing the motor's torque in Nm or PROS_ERR_F if the operation failed, - * setting errno. + * EOVERFLOW - The index is non 0 + * + * + * \param mode + * The Motor_Brake to set for the motor + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Torque: " << motor.get_torque(); - * pros::delay(2); - * } + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); * } * \endcode */ - std::vector get_torque_all(void) const; - + std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const; /** - * Gets the voltage delivered to the motor in millivolts. - * + * Sets one of Motor_Brake to the motor. * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class * for motors and motor groups @@ -1216,56 +1200,30 @@ class Motor : public AbstractMotor, public Device { * * EOVERFLOW - The index is non 0 * + * + * \param mode + * The Motor_Brake to set for the motor + * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, - * setting errno. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Voltage: " << motor.get_voltage(); - * pros::delay(2); - * } - * } - * \endcode - */ - std::int32_t get_voltage(const std::uint8_t index = 0) const; - - /** - * Gets a vector of the voltage delivered to the motor in millivolts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * - * \return A vector of the motor's voltage in mV or PROS_ERR_F if the operation failed, - * setting errno. - * - * \b Example - * \code - * void opcontrol() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Motor Voltage: " << motor.get_voltage_all()[0]; - * pros::delay(2); - * } + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); * } * \endcode */ - std::vector get_voltage_all(void) const; + std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const; /** - * Checks if the motor is drawing over its current limit. + * Sets the current limit for the motor in mA. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1278,57 +1236,60 @@ class Motor : public AbstractMotor, public Device { * * EOVERFLOW - The index is non 0 * + * * \param limit + * The new current limit in mA + * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return 1 if the motor's current limit is being exceeded and 0 if the - * current limit is not exceeded, or PROS_ERR if the operation failed, setting - * errno. + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code * void opcontrol() { * pros::Motor motor (1); * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Is the motor over its current limit?: " << motor.is_over_current(); - * pros::delay(2); + * + * motor.set_current_limit(1000); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); * } * } * \endcode */ - std::int32_t is_over_current(const std::uint8_t index = 0) const; + std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const; /** - * Checks if the motor is drawing over its current limit. + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \return A vector containing 1 if the motor's current limit is being exceeded and 0 if the - * current limit is not exceeded, or PROS_ERR if the operation failed, setting - * errno. + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Is the motor over its current limit?: " << motor.is_over_current_all()[0]; - * pros::delay(2); - * } + * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); * } * \endcode */ - std::vector is_over_current_all(void) const; - + std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const; /** - * Gets the temperature limit flag for the motor. + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1345,57 +1306,26 @@ class Motor : public AbstractMotor, public Device { * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * \return 1 if the temperature limit is exceeded and 0 if the temperature is - * below the limit, or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * void opcontrol() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); - * pros::delay(2); - * } - * } - * \endcode - */ - std::int32_t is_over_temp(const std::uint8_t index = 0) const; - - /** - * Gets the temperature limit flag for the motor. + * * \param units + * The new motor encoder units * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing 1 if the temperature limit is exceeded and 0 if the temperature is - * below the limit, or PROS_ERR if the operation failed, setting errno. + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp_all(); - * pros::delay(2); - * } + * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); * } * \endcode */ - std::vector is_over_temp_all(void) const; - - ///@} - - /// \name Motor configuration functions - /// These functions allow programmers to configure the behavior of motors - ///@{ + std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const; /** - * Gets the brake mode that was set for the motor. + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1411,44 +1341,64 @@ class Motor : public AbstractMotor, public Device { * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index + * \param gearset + * The new motor gearset * - * \return One of Motor_Brake, according to what was set for the - * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code * void initialize() { * pros::Motor motor (1); - * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); - * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * motor.set_gearing(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); * } * \endcode */ - MotorBrake get_brake_mode(const std::uint8_t index = 0) const; + std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const; /** - * Gets a vector containing the brake mode that was set for the motor. - * + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * * This function uses the following values of errno when an error state is * reached: + * * ENODEV - The port cannot be configured as a motor + * + * EOVERFLOW - The index is non 0 + * + * \param gearset + * The new motor gearset + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index * - * \return One of Motor_Brake, according to what was set for the - * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code * void initialize() { * pros::Motor motor (1); - * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); - * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * motor.set_gearing(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); * } * \endcode */ - std::vector get_brake_mode_all(void) const; + std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const; /** - * Gets the current limit for the motor in mA. + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1457,57 +1407,64 @@ class Motor : public AbstractMotor, public Device { * This function uses the following values of errno when an error state is * reached: * - * ENODEV - The port cannot be configured as a motor - * * EOVERFLOW - The index is non 0 * + * \param reverse + * True reverses the motor, false is default direction + * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * \return The motor's current limit in mA or PROS_ERR if the operation failed, - * setting errno. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void initialize() { * pros::Motor motor (1); - * while (true) { - * std::cout << "Motor Current Limit: " << motor.get_current_limit(); - * pros::delay(2); - * } + * motor.set_reversed(true); + * std::cout << "Is this motor reversed? " << motor.is_reversed(); * } * \endcode */ - std::int32_t get_current_limit(const std::uint8_t index = 0) const; - + std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0); + /** - * Gets a vector containing the current limit for the motor in mA. - * - * The default value is 2500 mA. + * Sets the voltage limit for the motor in Volts. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \return A vector containing the motor's current limit in mA or PROS_ERR if the operation failed, - * setting errno. + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void opcontrol() { + * void autonomous() { * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_voltage_limit(10000); * while (true) { - * std::cout << "Motor Current Limit: " << motor.get_current_limit_all()[0]; + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will not output more than 10 V * pros::delay(2); * } * } * \endcode */ - std::vector get_current_limit_all(void) const; + std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const; /** - * Gets the encoder units that were set for the motor. + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class @@ -1520,466 +1477,659 @@ class Motor : public AbstractMotor, public Device { * * EOVERFLOW - The index is non 0 * + * \param position + * The new reference position in its encoder units + * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index - * - * \return One of Motor_Units according to what is set for the - * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void initialize() { - * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); - * std::cout << "Motor Encoder Units: " << motor.get_encoder_units(); + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.set_zero_position(80); + * motor.move_absolute(100, 100); // Moves 80 units forward * } * \endcode + * */ - MotorUnits get_encoder_units(const std::uint8_t index = 0) const; + std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const; /** - * Gets a vector containing the encoder units that were set for the motor. + * Sets the "absolute" zero position of the motor to its current position. * + * \note This is one of many Motor functions that takes in an optional index parameter. + * This parameter can be ignored by most users but exists to give a shared base class + * for motors and motor groups + * * This function uses the following values of errno when an error state is * reached: + * * ENODEV - The port cannot be configured as a motor - * - * \return A vector containing One of Motor_Units according to what is set for the - * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * EOVERFLOW - The index is non 0 + * + * \param index Optional parameter. + * The zero-indexed index of the motor to get the target position of. + * By default index is 0, and will return an error for a non-zero index + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. * * \b Example * \code - * void initialize() { - * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); - * std::cout << "Motor Encoder Units: " << motor.get_encoder_units_all()[0]; + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward * } * \endcode */ - std::vector get_encoder_units_all(void) const; + std::int32_t tare_position(const std::uint8_t index = 0) const; /** - * Gets the gearset that was set for the motor. + * Gets the number of motors. + * + * \return Always returns 1 + * + */ + std::int8_t size(void) const; + + /** + * gets the port number of the motor * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups + * \return The signed port of the motor. (negative if the motor is reversed) * + */ + std::int8_t get_port(const std::uint8_t index = 0) const; + + ///@} + + /// \name Additional motor functions + /// These functions allow for motors and motor groups to be used interchangeably + ///@{ + /** + * Gets a vector containing the target position set for the motor by the user + * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index * - * \return One of Motor_Gears according to what is set for the motor, - * or pros::Motor_Gears::invalid if the operation failed. + * + * \return A vector containing the target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. * * \b Example * \code - * void initialize() { - * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); - * std::cout << "Motor Gearing: " << motor.get_gearing(); + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); + * std::cout << "Motor Target: " << motor.get_target_position_all()[0]; + * // Prints 100 * } * \endcode */ - MotorGears get_gearing(const std::uint8_t index = 0) const; - + std::vector get_target_position_all(void) const; + /** - * Gets a vector containing the gearset that was set for the motor. + * Gets a vector containing the velocity commanded to the motor by the user * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \return A vector containing one of Motor_Gears according to what is set for the motor, - * or pros::Motor_Gears::invalid if the operation failed. + * \return A vector containing the commanded motor velocity from +-100, + * +-200, or +-600, or PROS_ERR if the operation failed, setting errno. * * \b Example * \code - * void initialize() { - * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); - * std::cout << "Motor Gearing: " << motor.get_gearing_all()[0]; + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_target_velocity_all()[0]; + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } * } * \endcode */ - std::vector get_gearing_all(void) const; + std::vector get_target_velocity_all(void) const; /** - * Gets returns a vector with all the port numbers in the motor group. + * Gets a vector containing the actual velocity commanded of the motor * - * \return A vector containing the signed port of the motor. (negaitve if the motor is reversed) - */ - std::vector get_port_all(void) const; + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's actual velocity in RPM or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_actual_velocity_all()[0]; + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_actual_velocity_all(void) const; /** - * Gets the voltage limit set by the user. + * Gets a vector containing the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing the motor's current in mA or PROS_ERR if the operation failed, + * setting errno. * - * Default value is 0V, which means that there is no software limitation - * imposed on the voltage. + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Current Draw: " << motor.get_current_draw_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_current_draw_all(void) const; + + /** + * Gets a vector containing the direction of movement for the motor. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: * * ENODEV - The port cannot be configured as a motor * - * EOVERFLOW - The index is non 0 * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index + * \return A vector containing 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit(); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Direction: " << motor.get_direction_all()[0]; + * pros::delay(2); + * } * } * \endcode */ - std::int32_t get_voltage_limit(const std::uint8_t index = 0) const; + std::vector get_direction_all(void) const; + + /** + * Gets a vector containing the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * + * \return A vector containing The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_efficiency_all(void) const; /** - * Gets a vector of the voltage limit set by the user. + * Gets a vector of the faults experienced by the motor. * - * Default value is 0V, which means that there is no software limitation - * imposed on the voltage. + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A bitfield containing the motor's faults. * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_faults_all(void) const; + + /** + * Gets a vector of the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * * This function uses the following values of errno when an error state is * reached: + * * ENODEV - The port cannot be configured as a motor * - * \return A vector containing the motor's voltage limit in V or PROS_ERR if the operation failed, - * setting errno. + * + * \return A bitfield containing the motor's flags. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit_all()[0]; + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults_all()[0]; + * pros::delay(2); + * } * } * \endcode */ - std::vector get_voltage_limit_all(void) const; + std::vector get_flags_all(void) const; + + /** + * Gets a vector containing the absolute position of the motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + + * + * \return A vector containing the motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_position_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_position_all(void) const; /** - * Gets whether the motor is reversed or not + * Gets a vector containing the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << motor.get_power_all()[0]; + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_power_all(void) const; + + /** + * Gets a vector of the raw encoder count of the motor at a given timestamp. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups * * This function uses the following values of errno when an error state is * reached: - * - * EOVERFLOW - The index is non 0 * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index + * ENODEV - The port cannot be configured as a motor + * + * \param timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return A vector containing the raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. * - * \return 1 if the motor has been reversed and 0 if the motor was not - * reversed, or PROS_ERR if the operation failed, setting errno. + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * pros::delay(2); + * } + * } + * \endcode + */ + std::vector get_raw_position_all(std::uint32_t* const timestamp) const; + + /** + * Gets a vector of the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector contaioning the motor's temperature in degrees Celsius + * or PROS_ERR_F if the operation failed, setting errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * std::cout << "Is the motor reversed? " << motor.is_reversed(); - * // Prints "0" + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << motor.get_temperature_all()[0]; + * pros::delay(2); + * } * } * \endcode */ - std::int32_t is_reversed(const std::uint8_t index = 0) const; + std::vector get_temperature_all(void) const; /** - * Gets a vector containg whether the motor is reversed or not + * Gets a vector of the torque generated by the motor in Newton Meters (Nm). * - * \return A vector containing 1 if the motor has been reversed and 0 if the motor was not - * reversed, or PROS_ERR if the operation failed, setting errno. + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing the motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * std::cout << "Is the motor reversed? " << motor.is_reversed_all()[0]; - * // Prints "0" + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << motor.get_torque(); + * pros::delay(2); + * } * } * \endcode */ - std::vector is_reversed_all(void) const; - + std::vector get_torque_all(void) const; + /** - * Sets one of Motor_Brake to the motor. - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * + * Gets a vector of the voltage delivered to the motor in millivolts. + * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor * - * EOVERFLOW - The index is non 0 - * - * - * \param mode - * The Motor_Brake to set for the motor - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return A vector of the motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); - * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << motor.get_voltage_all()[0]; + * pros::delay(2); + * } * } * \endcode */ - std::int32_t set_brake_mode(const MotorBrake mode, const std::uint8_t index = 0) const; + std::vector get_voltage_all(void) const; + /** - * Sets one of Motor_Brake to the motor. - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * + * Checks if the motor is drawing over its current limit. + * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * - * \param mode - * The Motor_Brake to set for the motor - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return A vector containing 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); - * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current_all()[0]; + * pros::delay(2); + * } * } * \endcode */ - std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const; + std::vector is_over_current_all(void) const; /** - * Sets one of Motor_Brake to the motor. + * Gets the temperature limit flag for the motor. * * This function uses the following values of errno when an error state is * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param mode - * The Motor_Brake to set for the motor - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * ENODEV - The port cannot be configured as a motor + * + * \return A vector containing 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); - * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp_all(); + * pros::delay(2); + * } * } * \endcode */ - std::int32_t set_brake_mode_all(const MotorBrake mode) const; + std::vector is_over_temp_all(void) const; + /** - * Sets one of Motor_Brake to the motor. + * Gets a vector containing the brake mode that was set for the motor. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \param mode - * The Motor_Brake to set for the motor - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return One of Motor_Brake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. * * \b Example * \code * void initialize() { * pros::Motor motor (1); - * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); * std::cout << "Brake Mode: " << motor.get_brake_mode(); * } * \endcode */ - std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const; + std::vector get_brake_mode_all(void) const; + /** - * Sets the current limit for the motor in mA. + * Gets a vector containing the current limit for the motor in mA. + * + * The default value is 2500 mA. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * * \param limit - * The new current limit in mA - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return A vector containing the motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. * * \b Example * \code * void opcontrol() { * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * - * motor.set_current_limit(1000); - * while (true) { - * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * // The motor will reduce its output at 1000 mA instead of the default 2500 mA - * pros::delay(2); + * while (true) { + * std::cout << "Motor Current Limit: " << motor.get_current_limit_all()[0]; + * pros::delay(2); * } * } * \endcode */ - std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + std::vector get_current_limit_all(void) const; + /** - * Sets the current limit for the motor in mA. + * Gets a vector containing the encoder units that were set for the motor. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \param limit - * The new current limit in mA - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return A vector containing One of Motor_Units according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. * * \b Example * \code - * void opcontrol() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * - * motor.set_current_limit(1000); - * while (true) { - * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * // The motor will reduce its output at 1000 mA instead of the default 2500 mA - * pros::delay(2); - * } + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << motor.get_encoder_units_all()[0]; * } * \endcode */ - std::int32_t set_current_limit_all(const std::int32_t limit) const; + std::vector get_encoder_units_all(void) const; + /** - * Sets one of Motor_Units for the motor encoder. Works with the C - * enum and the C++ enum class. + * Gets a vector containing the gearset that was set for the motor. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \param units - * The new motor encoder units - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return A vector containing one of Motor_Gears according to what is set for the motor, + * or pros::Motor_Gears::invalid if the operation failed. * * \b Example * \code * void initialize() { - * pros::Motor motor (1); - * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); - * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * pros::Motor motor (1, E_MOTOR_GEARSET_06, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << motor.get_gearing_all()[0]; * } * \endcode */ - std::int32_t set_encoder_units(const MotorUnits units, const std::uint8_t index = 0) const; + std::vector get_gearing_all(void) const; + /** - * Sets one of Motor_Units for the motor encoder. Works with the C - * enum and the C++ enum class. + * Gets returns a vector with all the port numbers in the motor group. + * + * \return A vector containing the signed port of the motor. (negative if the motor is reversed) + */ + std::vector get_port_all(void) const; + + /** + * Gets a vector of the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index - * - * * \param units - * The new motor encoder units * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. + * \return A vector containing the motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. * * \b Example * \code * void initialize() { * pros::Motor motor (1); - * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); - * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit_all()[0]; * } * \endcode */ - std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const; + std::vector get_voltage_limit_all(void) const; + /** - * Sets one of Motor_Units for the motor encoder. Works with the C - * enum and the C++ enum class. + * Gets a vector containg whether the motor is reversed or not + * + * \return A vector containing 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Is the motor reversed? " << motor.is_reversed_all()[0]; + * // Prints "0" + * } + * \endcode + */ + std::vector is_reversed_all(void) const; + + /** + * Sets one of Motor_Brake to the motor. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * * \param units - * The new motor encoder units - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index + * + * \param mode + * The Motor_Brake to set for the motor * * \return 1 if the operation was successful or PROS_ERR if the operation * failed, setting errno. @@ -1988,23 +2138,22 @@ class Motor : public AbstractMotor, public Device { * \code * void initialize() { * pros::Motor motor (1); - * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); - * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); * } * \endcode */ - std::int32_t set_encoder_units_all(const MotorUnits units) const; + std::int32_t set_brake_mode_all(const MotorBrake mode) const; /** - * Sets one of Motor_Units for the motor encoder. Works with the C - * enum and the C++ enum class. + * Sets one of Motor_Brake to the motor. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \param units - * The new motor encoder units + * \param mode + * The Motor_Brake to set for the motor * * \return 1 if the operation was successful or PROS_ERR if the operation * failed, setting errno. @@ -2013,52 +2162,47 @@ class Motor : public AbstractMotor, public Device { * \code * void initialize() { * pros::Motor motor (1); - * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); - * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * motor.set_brake_mode_all(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); * } * \endcode */ - std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const; - + std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const; + /** - * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with - * the C++ enum class and the C enum. + * Sets the current limit for the motor in mA. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * * This function uses the following values of errno when an error state is * reached: - * * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index - * \param gearset - * The new motor gearset + * + * \param limit + * The new current limit in mA * * \return 1 if the operation was successful or PROS_ERR if the operation * failed, setting errno. * * \b Example * \code - * void initialize() { + * void opcontrol() { * pros::Motor motor (1); - * motor.set_gearing(E_MOTOR_GEARSET_06); - * std::cout << "Gearset: " << motor.get_gearing(); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_current_limit_all(1000); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } * } * \endcode */ - std::int32_t set_gearing(const MotorGears gearset, const std::uint8_t index = 0) const; - + std::int32_t set_current_limit_all(const std::int32_t limit) const; + /** - * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with - * the C++ enum class and the C enum. - + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. + * * \note This is one of many Motor functions that takes in an optional index parameter. * This parameter can be ignored by most users but exists to give a shared base class * for motors and motor groups @@ -2070,14 +2214,13 @@ class Motor : public AbstractMotor, public Device { * * EOVERFLOW - The index is non 0 * - * \param gearset - * The new motor gearset + * * \param units + * The new motor encoder units * * \param index Optional parameter. * The zero-indexed index of the motor to get the target position of. * By default index is 0, and will return an error for a non-zero index * - * * \return 1 if the operation was successful or PROS_ERR if the operation * failed, setting errno. * @@ -2085,23 +2228,23 @@ class Motor : public AbstractMotor, public Device { * \code * void initialize() { * pros::Motor motor (1); - * motor.set_gearing(E_MOTOR_GEARSET_06); - * std::cout << "Gearset: " << motor.get_gearing(); + * motor.set_encoder_units_all(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); * } * \endcode */ - std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const; + std::int32_t set_encoder_units_all(const MotorUnits units) const; /** - * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with - * the C++ enum class and the C enum. + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * - * \param gearset - * The new motor gearset + * \param units + * The new motor encoder units * * \return 1 if the operation was successful or PROS_ERR if the operation * failed, setting errno. @@ -2110,13 +2253,14 @@ class Motor : public AbstractMotor, public Device { * \code * void initialize() { * pros::Motor motor (1); - * motor.set_gearing_all(E_MOTOR_GEARSET_06); - * std::cout << "Gearset: " << motor.get_gearing(); + * motor.set_encoder_units_all(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); * } * \endcode */ - std::int32_t set_gearing_all(const MotorGears gearset) const; + std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const; + /** * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with * the C++ enum class and the C enum. @@ -2140,29 +2284,18 @@ class Motor : public AbstractMotor, public Device { * } * \endcode */ - std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const; - - + std::int32_t set_gearing_all(const MotorGears gearset) const; + /** - * Sets the reverse flag for the motor. - * - * This will invert its movements and the values returned for its position. + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * * This function uses the following values of errno when an error state is * reached: - * - * EOVERFLOW - The index is non 0 - * - * \param reverse - * True reverses the motor, false is default direction - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset * * \return 1 if the operation was successful or PROS_ERR if the operation * failed, setting errno. @@ -2171,12 +2304,13 @@ class Motor : public AbstractMotor, public Device { * \code * void initialize() { * pros::Motor motor (1); - * motor.set_reversed(true); - * std::cout << "Is this motor reversed? " << motor.is_reversed(); + * motor.set_gearing_all(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); * } * \endcode */ - std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0); + std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const; + /** * Sets the reverse flag for the motor. * @@ -2198,36 +2332,6 @@ class Motor : public AbstractMotor, public Device { * \endcode */ std::int32_t set_reversed_all(const bool reverse); - - /** - * Sets the voltage limit for the motor in Volts. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param limit - * The new voltage limit in Volts - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * pros::Motor motor (1); - * pros::Controller master (E_CONTROLLER_MASTER); - * - * motor.set_voltage_limit(10000); - * while (true) { - * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); - * // The motor will not output more than 10 V - * pros::delay(2); - * } - * } - * \endcode - */ - std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const; /** * Sets the voltage limit for the motor in Volts. @@ -2269,49 +2373,6 @@ class Motor : public AbstractMotor, public Device { * \endcode */ std::int32_t set_voltage_limit_all(const std::int32_t limit) const; - - /** - * Sets the position for the motor in its encoder units. - * - * This will be the future reference point for the motor's "absolute" - * position. - * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * \param position - * The new reference position in its encoder units - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index - * - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * pros::Motor motor (1); - * motor.move_absolute(100, 100); // Moves 100 units forward - * motor.move_absolute(100, 100); // This does not cause a movement - * - * motor.set_zero_position(80); - * motor.move_absolute(100, 100); // Moves 80 units forward - * } - * \endcode - * - */ - std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const; /** * Sets the position for the motor in its encoder units. @@ -2344,41 +2405,6 @@ class Motor : public AbstractMotor, public Device { */ std::int32_t set_zero_position_all(const double position) const; - /** - * Sets the "absolute" zero position of the motor to its current position. - * - * \note This is one of many Motor functions that takes in an optional index parameter. - * This parameter can be ignored by most users but exists to give a shared base class - * for motors and motor groups - * - * This function uses the following values of errno when an error state is - * reached: - * - * ENODEV - The port cannot be configured as a motor - * - * EOVERFLOW - The index is non 0 - * - * \param index Optional parameter. - * The zero-indexed index of the motor to get the target position of. - * By default index is 0, and will return an error for a non-zero index - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * pros::Motor motor (1); - * motor.move_absolute(100, 100); // Moves 100 units forward - * motor.move_absolute(100, 100); // This does not cause a movement - * - * motor.tare_position(); - * motor.move_absolute(100, 100); // Moves 100 units forward - * } - * \endcode - */ - std::int32_t tare_position(const std::uint8_t index = 0) const; - /** * Sets the "absolute" zero position of the motor to its current position. * @@ -2403,21 +2429,7 @@ class Motor : public AbstractMotor, public Device { */ std::int32_t tare_position_all(void) const; - /** - * Gets the number of motors. - * - * \return Always returns 1 - * - */ - std::int8_t size(void) const; - - /** - * gets the port number of the motor - * - * \return A vector containing the signed port of the motor. (negaitve if the motor is reversed) - * - */ - std::int8_t get_port(const std::uint8_t index = 0) const; + ///@} private: std::int8_t _port; diff --git a/include/pros/optical.h b/include/pros/optical.h index c7e02d3..049c395 100644 --- a/include/pros/optical.h +++ b/include/pros/optical.h @@ -1,473 +1,473 @@ -/** - * \file pros/optical.h - * \ingroup c-optical - * - * Contains prototypes for functions related to the VEX Optical sensor. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-optical VEX Optical Sensor C API - */ - -#ifndef _PROS_OPTICAL_H_ -#define _PROS_OPTICAL_H_ - -#include -#include -#include "error.h" - -#define OPT_GESTURE_ERR (INT8_MAX) -#define OPT_COUNT_ERR (INT16_MAX) -#define OPT_TIME_ERR PROS_ERR - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif - -/** - * \ingroup c-optical - */ - -/** - * \addtogroup c-optical - * @{ - */ - -/** - * \enum optical_direction_e_t - */ -typedef enum optical_direction_e { NO_GESTURE = 0, - /// The direction indicating an upward gesture. - UP = 1, - /// The direction indicating a downward gesture. - DOWN = 2, - /// The direction indicating a rightward gesture. - RIGHT = 3, - /// The direction indicating a leftward gesture. - LEFT = 4, - ERROR = PROS_ERR -} optical_direction_e_t; - -/** - * \struct optical_rgb_s_t - * The RGB and Brightness values for the optical sensor. - */ -typedef struct optical_rgb_s { - double red; - double green; - double blue; - double brightness; -} optical_rgb_s_t; - -/** - * \struct optical_raw_s_t - * The RGB and clear values for the optical sensor. - */ -typedef struct optical_raw_s { - uint32_t clear; - uint32_t red; - uint32_t green; - uint32_t blue; -} optical_raw_s_t; - -/** - * \struct optical_gesture_s_t - * This structure contains the raw gesture data. - */ -typedef struct optical_gesture_s { - uint8_t udata; ///Up data - uint8_t ddata; ///Down data - uint8_t ldata; ///Left data - uint8_t rdata; ///Right data - uint8_t type; ///Type of gesture - uint8_t pad; ///Padding - uint16_t count; ///Number of gestures - uint32_t time; ///Time since gesture recognized -} optical_gesture_s_t; - -/** - * \name Functions - * @{ - */ - -/** - * Get the detected color hue - * - * This is not available if gestures are being detected. Hue has a - * range of 0 to 359.999 - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return hue value if the operation was successful or PROS_ERR_F if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Hue value: %lf \n", optical_get_hue(OPTICAL_PORT)); - * delay(20); - * } - * } - * \endcode - */ -double optical_get_hue(uint8_t port); - -/** - * Get the detected color saturation - * - * This is not available if gestures are being detected. Saturation has a - * range of 0 to 1.0 - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return saturation value if the operation was successful or PROS_ERR_F if - * the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Saturation value: %lf \n", optical_get_saturation(OPTICAL_PORT)); - * delay(20); - * } - * } - * \endcode - */ -double optical_get_saturation(uint8_t port); - -/** - * Get the detected color brightness - * - * This is not available if gestures are being detected. Brightness has a - * range of 0 to 1.0 - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return brightness value if the operation was successful or PROS_ERR_F if - * the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Brightness value: %lf \n", optical_get_brightness(OPTICAL_PORT)); - * delay(20); - * } - * } - * \endcode - */ -double optical_get_brightness(uint8_t port); - -/** - * Get the detected proximity value - * - * This is not available if gestures are being detected. proximity has - * a range of 0 to 255. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return poximity value if the operation was successful or PROS_ERR if - * the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Proximity value: %d \n", optical_get_proximity(OPTICAL_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t optical_get_proximity(uint8_t port); - -/** - * Set the pwm value of the White LED - * - * value that ranges from 0 to 100 - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return 1 if the operation is successful or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * optical_set_led_pwm(OPTICAL_PORT, 50); - * delay(20); - * } - * } - * \endcode - */ -int32_t optical_set_led_pwm(uint8_t port, uint8_t value); - -/** - * Get the pwm value of the White LED - * - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return LED pwm value that ranges from 0 to 100 if the operation was - * successful or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("PWM Value: %d \n", optical_get_led_pwm(OPTICAL_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t optical_get_led_pwm(uint8_t port); - -/** - * Get the processed RGBC data from the sensor - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return rgb value if the operation was successful or an optical_rgb_s_t with - * all fields set to PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * optical_rgb_s_t RGB_values; - * void opcontrol() { - * while (true) { - * RGB_values = optical_get_rgb(OPTICAL_PORT); - * printf("Red value: %lf \n", RGB_values.red); - * printf("Green value: %lf \n", RGB_values.green); - * printf("Blue value: %lf \n", RGB_values.blue); - * printf("Brightness value: %lf \n", RGB_values.brightness); - * delay(20); - * } - * } - * \endcode - */ -optical_rgb_s_t optical_get_rgb(uint8_t port); - -/** - * Get the raw, unprocessed RGBC data from the sensor - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return raw rgb value if the operation was successful or an optical_raw_s_t - * with all fields set to PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * optical_raw_s_t raw_values; - * void opcontrol() { - * while (true) { - * raw_values = optical_get_raw(OPTICAL_PORT); - * printf("Red value: %ld \n", raw_values.red); - * printf("Green value: %ld \n", raw_values.green); - * printf("Blue value: %ld \n", raw_values.blue); - * printf("Clear value: %ld \n", raw_values.clear); - * delay(20); - * } - * } - * \endcode - */ -optical_raw_s_t optical_get_raw(uint8_t port); - -/** - * Get the most recent gesture data from the sensor - * - * Gestures will be cleared after 500mS - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return gesture value if the operation was successful or PROS_ERR if - * the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * optical_direction_e_t gesture; - * void opcontrol() { - * while (true) { - * gesture = optical_get_gesture(OPTICAL_PORT); - * printf("Gesture value: %d \n", gesture); - * delay(20); - * } - * } - * \endcode - */ -optical_direction_e_t optical_get_gesture(uint8_t port); - -/** - * Get the most recent raw gesture data from the sensor - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return gesture value if the operation was successful or an optical_gesture_s_t - * with all fields set to PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * optical_gesture_s_t raw_gesture; - * void opcontrol() { - * while (true) { - * raw_gesture = optical_get_gesture_raw(OPTICAL_PORT); - * printf("Up data: %u \n", raw_gesture.udata); - * printf("Down data: %u \n", raw_gesture.ddata); - * printf("Left data: %u \n", raw_gesture.ldata); - * printf("Right data: %u \n", raw_gesture.rdata); - * printf("Type: %u \n", raw_gesture.type); - * printf("Count: %u \n", raw_gesture.count); - * printf("Time: %lu \n", raw_gesture.time); - * delay(20); - * } - * } - * \endcode - */ -optical_gesture_s_t optical_get_gesture_raw(uint8_t port); - -/** - * Enable gesture detection on the sensor - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return 1 if the operation is successful or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * optical_enable_gesture(OPTICAL_PORT); - * delay(20); - * } - * } - * \endcode - */ -int32_t optical_enable_gesture(uint8_t port); - -/** - * Disable gesture detection on the sensor - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Optical Sensor - * - * \param port - * The V5 Optical Sensor port number from 1-21 - * \return 1 if the operation is successful or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example - * \code - * #define OPTICAL_PORT 1 - * - * void opcontrol() { - * while (true) { - * optical_disable_gesture(OPTICAL_PORT); - * delay(20); - * } - * } - * \endcode - */ -int32_t optical_disable_gesture(uint8_t port); - -///@} - -///@} - -#ifdef __cplusplus -} -} -} -#endif - -#endif +/** + * \file pros/optical.h + * \ingroup c-optical + * + * Contains prototypes for functions related to the VEX Optical sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-optical VEX Optical Sensor C API + */ + +#ifndef _PROS_OPTICAL_H_ +#define _PROS_OPTICAL_H_ + +#include +#include +#include "error.h" + +#define OPT_GESTURE_ERR (INT8_MAX) +#define OPT_COUNT_ERR (INT16_MAX) +#define OPT_TIME_ERR PROS_ERR + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-optical + */ + +/** + * \addtogroup c-optical + * @{ + */ + +/** + * \enum optical_direction_e_t + */ +typedef enum optical_direction_e { NO_GESTURE = 0, + /// The direction indicating an upward gesture. + UP = 1, + /// The direction indicating a downward gesture. + DOWN = 2, + /// The direction indicating a rightward gesture. + RIGHT = 3, + /// The direction indicating a leftward gesture. + LEFT = 4, + ERROR = PROS_ERR +} optical_direction_e_t; + +/** + * \struct optical_rgb_s_t + * The RGB and Brightness values for the optical sensor. + */ +typedef struct optical_rgb_s { + double red; + double green; + double blue; + double brightness; +} optical_rgb_s_t; + +/** + * \struct optical_raw_s_t + * The RGB and clear values for the optical sensor. + */ +typedef struct optical_raw_s { + uint32_t clear; + uint32_t red; + uint32_t green; + uint32_t blue; +} optical_raw_s_t; + +/** + * \struct optical_gesture_s_t + * This structure contains the raw gesture data. + */ +typedef struct optical_gesture_s { + uint8_t udata; ///Up data + uint8_t ddata; ///Down data + uint8_t ldata; ///Left data + uint8_t rdata; ///Right data + uint8_t type; ///Type of gesture + uint8_t pad; ///Padding + uint16_t count; ///Number of gestures + uint32_t time; ///Time since gesture recognized +} optical_gesture_s_t; + +/** + * \name Functions + * @{ + */ + +/** + * Get the detected color hue + * + * This is not available if gestures are being detected. Hue has a + * range of 0 to 359.999 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return hue value if the operation was successful or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Hue value: %lf \n", optical_get_hue(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double optical_get_hue(uint8_t port); + +/** + * Get the detected color saturation + * + * This is not available if gestures are being detected. Saturation has a + * range of 0 to 1.0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return saturation value if the operation was successful or PROS_ERR_F if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Saturation value: %lf \n", optical_get_saturation(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double optical_get_saturation(uint8_t port); + +/** + * Get the detected color brightness + * + * This is not available if gestures are being detected. Brightness has a + * range of 0 to 1.0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return brightness value if the operation was successful or PROS_ERR_F if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Brightness value: %lf \n", optical_get_brightness(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +double optical_get_brightness(uint8_t port); + +/** + * Get the detected proximity value + * + * This is not available if gestures are being detected. proximity has + * a range of 0 to 255. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return poximity value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Proximity value: %d \n", optical_get_proximity(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_get_proximity(uint8_t port); + +/** + * Set the pwm value of the White LED + * + * value that ranges from 0 to 100 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * optical_set_led_pwm(OPTICAL_PORT, 50); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_set_led_pwm(uint8_t port, uint8_t value); + +/** + * Get the pwm value of the White LED + * + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return LED pwm value that ranges from 0 to 100 if the operation was + * successful or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("PWM Value: %d \n", optical_get_led_pwm(OPTICAL_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_get_led_pwm(uint8_t port); + +/** + * Get the processed RGBC data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return rgb value if the operation was successful or an optical_rgb_s_t with + * all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_rgb_s_t RGB_values; + * void opcontrol() { + * while (true) { + * RGB_values = optical_get_rgb(OPTICAL_PORT); + * printf("Red value: %lf \n", RGB_values.red); + * printf("Green value: %lf \n", RGB_values.green); + * printf("Blue value: %lf \n", RGB_values.blue); + * printf("Brightness value: %lf \n", RGB_values.brightness); + * delay(20); + * } + * } + * \endcode + */ +optical_rgb_s_t optical_get_rgb(uint8_t port); + +/** + * Get the raw, unprocessed RGBC data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return raw rgb value if the operation was successful or an optical_raw_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_raw_s_t raw_values; + * void opcontrol() { + * while (true) { + * raw_values = optical_get_raw(OPTICAL_PORT); + * printf("Red value: %ld \n", raw_values.red); + * printf("Green value: %ld \n", raw_values.green); + * printf("Blue value: %ld \n", raw_values.blue); + * printf("Clear value: %ld \n", raw_values.clear); + * delay(20); + * } + * } + * \endcode + */ +optical_raw_s_t optical_get_raw(uint8_t port); + +/** + * Get the most recent gesture data from the sensor + * + * Gestures will be cleared after 500mS + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return gesture value if the operation was successful or PROS_ERR if + * the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_direction_e_t gesture; + * void opcontrol() { + * while (true) { + * gesture = optical_get_gesture(OPTICAL_PORT); + * printf("Gesture value: %d \n", gesture); + * delay(20); + * } + * } + * \endcode + */ +optical_direction_e_t optical_get_gesture(uint8_t port); + +/** + * Get the most recent raw gesture data from the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return gesture value if the operation was successful or an optical_gesture_s_t + * with all fields set to PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * optical_gesture_s_t raw_gesture; + * void opcontrol() { + * while (true) { + * raw_gesture = optical_get_gesture_raw(OPTICAL_PORT); + * printf("Up data: %u \n", raw_gesture.udata); + * printf("Down data: %u \n", raw_gesture.ddata); + * printf("Left data: %u \n", raw_gesture.ldata); + * printf("Right data: %u \n", raw_gesture.rdata); + * printf("Type: %u \n", raw_gesture.type); + * printf("Count: %u \n", raw_gesture.count); + * printf("Time: %lu \n", raw_gesture.time); + * delay(20); + * } + * } + * \endcode + */ +optical_gesture_s_t optical_get_gesture_raw(uint8_t port); + +/** + * Enable gesture detection on the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * optical_enable_gesture(OPTICAL_PORT); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_enable_gesture(uint8_t port); + +/** + * Disable gesture detection on the sensor + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * #define OPTICAL_PORT 1 + * + * void opcontrol() { + * while (true) { + * optical_disable_gesture(OPTICAL_PORT); + * delay(20); + * } + * } + * \endcode + */ +int32_t optical_disable_gesture(uint8_t port); + +///@} + +///@} + +#ifdef __cplusplus +} +} +} +#endif + +#endif diff --git a/include/pros/rotation.h b/include/pros/rotation.h index 3495a97..1c1c731 100644 --- a/include/pros/rotation.h +++ b/include/pros/rotation.h @@ -1,390 +1,390 @@ -/** - * \file pros/rotation.h - * \ingroup c-rotation - * - * Contains prototypes for functions related to the VEX Rotation Sensor. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-rotation VEX Rotation Sensor C API - */ - -#ifndef _PROS_ROTATION_H_ -#define _PROS_ROTATION_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif - -/** - * \ingroup c-rotation - */ - -/** - * \addtogroup c-rotation - * @{ - */ - -#define ROTATION_MINIMUM_DATA_RATE 5 - -/** - * Reset Rotation Sensor - * - * Reset the current absolute position to be the same as the - * Rotation Sensor angle. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_reset(ROTATION_PORT); - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_reset(uint8_t port); - -/** - * Set the Rotation Sensor's refresh interval in milliseconds. - * - * The rate may be specified in increments of 5ms, and will be rounded down to - * the nearest increment. The minimum allowable refresh rate is 5ms. The default - * rate is 10ms. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \param rate The data refresh interval in milliseconds - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void initialize() { - * pros::Rotation rotation_sensor(ROTATION_PORT); - * rotation_set_data_rate(ROTATION_PORT, 5); - * } - * \endcode - */ -int32_t rotation_set_data_rate(uint8_t port, uint32_t rate); - -/** - * Set the Rotation Sensor position reading to a desired rotation value - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \param position - * The position in terms of ticks - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_set_position(ROTATION_PORT, 600); - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_set_position(uint8_t port, uint32_t position); - -/** - * Reset the Rotation Sensor position to 0 - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_reset_position(ROTATION_PORT); - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_reset_position(uint8_t port); - -/** - * Get the Rotation Sensor's current position in centidegrees - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \return The position value or PROS_ERR_F if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Position: %d centidegrees \n", rotation_get_position(ROTATION_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_get_position(uint8_t port); - -/** - * Get the Rotation Sensor's current velocity in centidegrees per second - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \return The velocity value or PROS_ERR_F if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Velocity: %d centidegrees per second \n", rotation_get_velocity(ROTATION_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_get_velocity(uint8_t port); - -/** - * Get the Rotation Sensor's current angle in centidegrees (0-36000) - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \return The angle value (0-36000) or PROS_ERR_F if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Angle: %d centidegrees \n", rotation_get_angle(ROTATION_PORT)); - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_get_angle(uint8_t port); - -/** - * Set the Rotation Sensor's direction reversed flag - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \param value - * Determines if the direction of the Rotation Sensor is reversed or not. - * - * \return 1 if operation succeeded or PROS_ERR if the operation failed, setting - * errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * Rotation rotation_sensor(ROTATION_PORT); - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_set_reversed(ROTATION_PORT, true); // Reverses the Rotation Sensor on ROTATION_PORT - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_set_reversed(uint8_t port, bool value); - -/** - * Reverse the Rotation Sensor's direction - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * Rotation rotation_sensor(ROTATION_PORT); - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_reverse(ROTATION_PORT); - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_reverse(uint8_t port); - -/** - * Initialize the Rotation Sensor with a reverse flag - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * \param reverse_flag - * Determines if the Rotation Sensor is reversed or not. - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * Rotation rotation_sensor(ROTATION_PORT); - * bool reverse_flag = true; - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_init_reverse(ROTATION_PORT, reverse_flag); - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_init_reverse(uint8_t port, bool reverse_flag); - -/** - * Get the Rotation Sensor's reversed flag - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as an Rotation Sensor - * - * \param port - * The V5 Rotation Sensor port number from 1-21 - * - * \return Boolean value of if the Rotation Sensor's direction is reversed or not - * or PROS_ERR if the operation failed, setting errno. - * - * \b Example - * \code - * #define ROTATION_PORT 1 - * - * void opcontrol() { - * Rotation rotation_sensor(ROTATION_PORT); - * while (true) { - * - * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ - * rotation_get_reversed(ROTATION_PORT); - * } - * delay(20); - * } - * } - * \endcode - */ -int32_t rotation_get_reversed(uint8_t port); - -///@} - -#ifdef __cplusplus -} //namespace C -} //namespace pros -} //extern "C" -#endif - -#endif +/** + * \file pros/rotation.h + * \ingroup c-rotation + * + * Contains prototypes for functions related to the VEX Rotation Sensor. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-rotation VEX Rotation Sensor C API + */ + +#ifndef _PROS_ROTATION_H_ +#define _PROS_ROTATION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-rotation + */ + +/** + * \addtogroup c-rotation + * @{ + */ + +#define ROTATION_MINIMUM_DATA_RATE 5 + +/** + * Reset Rotation Sensor + * + * Reset the current absolute position to be the same as the + * Rotation Sensor angle. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_reset(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_reset(uint8_t port); + +/** + * Set the Rotation Sensor's refresh interval in milliseconds. + * + * The rate may be specified in increments of 5ms, and will be rounded down to + * the nearest increment. The minimum allowable refresh rate is 5ms. The default + * rate is 10ms. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param rate The data refresh interval in milliseconds + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void initialize() { + * pros::Rotation rotation_sensor(ROTATION_PORT); + * rotation_set_data_rate(ROTATION_PORT, 5); + * } + * \endcode + */ +int32_t rotation_set_data_rate(uint8_t port, uint32_t rate); + +/** + * Set the Rotation Sensor position reading to a desired rotation value + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param position + * The position in terms of ticks + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_set_position(ROTATION_PORT, 600); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_set_position(uint8_t port, uint32_t position); + +/** + * Reset the Rotation Sensor position to 0 + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_reset_position(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_reset_position(uint8_t port); + +/** + * Get the Rotation Sensor's current position in centidegrees + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The position value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Position: %d centidegrees \n", rotation_get_position(ROTATION_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_position(uint8_t port); + +/** + * Get the Rotation Sensor's current velocity in centidegrees per second + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The velocity value or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Velocity: %d centidegrees per second \n", rotation_get_velocity(ROTATION_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_velocity(uint8_t port); + +/** + * Get the Rotation Sensor's current angle in centidegrees (0-36000) + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \return The angle value (0-36000) or PROS_ERR_F if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Angle: %d centidegrees \n", rotation_get_angle(ROTATION_PORT)); + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_angle(uint8_t port); + +/** + * Set the Rotation Sensor's direction reversed flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param value + * Determines if the direction of the Rotation Sensor is reversed or not. + * + * \return 1 if operation succeeded or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_set_reversed(ROTATION_PORT, true); // Reverses the Rotation Sensor on ROTATION_PORT + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_set_reversed(uint8_t port, bool value); + +/** + * Reverse the Rotation Sensor's direction + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_reverse(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_reverse(uint8_t port); + +/** + * Initialize the Rotation Sensor with a reverse flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * \param reverse_flag + * Determines if the Rotation Sensor is reversed or not. + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * bool reverse_flag = true; + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_init_reverse(ROTATION_PORT, reverse_flag); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_init_reverse(uint8_t port, bool reverse_flag); + +/** + * Get the Rotation Sensor's reversed flag + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as an Rotation Sensor + * + * \param port + * The V5 Rotation Sensor port number from 1-21 + * + * \return Boolean value of if the Rotation Sensor's direction is reversed or not + * or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * #define ROTATION_PORT 1 + * + * void opcontrol() { + * Rotation rotation_sensor(ROTATION_PORT); + * while (true) { + * + * if(controller_get_digital(CONTROLLER_MASTER, E_CONTROLLER_DIGITAL_X)){ + * rotation_get_reversed(ROTATION_PORT); + * } + * delay(20); + * } + * } + * \endcode + */ +int32_t rotation_get_reversed(uint8_t port); + +///@} + +#ifdef __cplusplus +} //namespace C +} //namespace pros +} //extern "C" +#endif + +#endif diff --git a/include/pros/rotation.hpp b/include/pros/rotation.hpp index b58ad91..25806c3 100644 --- a/include/pros/rotation.hpp +++ b/include/pros/rotation.hpp @@ -53,27 +53,7 @@ class Rotation : public Device { * } * \endcode */ - explicit Rotation(const std::uint8_t port) : Device(port, DeviceType::rotation) {}; - - /** - * Constructs a new Rotation Sensor object - * - * ENXIO - The given value is not within the range of V5 ports |1-21|. - * ENODEV - The port cannot be configured as a Rotation Sensor - * - * \param port - * The V5 port number from 1 to 21, or from -21 to -1 for reversed Rotation Sensors. - * \param reverse_flag - * Determines if the Rotation Sensor is reversed or not. - * - * \b Example - * \code - * void opcontrol() { - * pros::Rotation rotation_sensor(1, true); //Creates a reversed Rotation Sensor on port 1 - * } - * \endcode - */ - explicit Rotation(const std::uint8_t port, const bool reverse_flag); + explicit Rotation(const std::int8_t port); /** * Reset the Rotation Sensor diff --git a/include/pros/rtos.h b/include/pros/rtos.h index 27adc14..d6b9be4 100644 --- a/include/pros/rtos.h +++ b/include/pros/rtos.h @@ -1,1108 +1,1108 @@ -/** - * \file pros/rtos.h - * \ingroup c-rtos - * - * Contains declarations for the PROS RTOS kernel for use by typical VEX - * programmers. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-rtos RTOS Facilities C API - * \note Additional example code for this module can be found in its [Tutorial.](@ref multitasking) - */ - -#ifndef _PROS_RTOS_H_ -#define _PROS_RTOS_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/// \ingroup c-rtos - -/// \addtogroup c-rtos -/// @{ - -/// \name Macros -/// @{ - -/** - * The highest priority that can be assigned to a task. - * - * A task with this priority will always run if it is available to. Beware of - * deadlocks when using this priority. - */ -#define TASK_PRIORITY_MAX 16 - -/** - * The lowest priority that can be assigned to a task. - * - * This can cause severe performance problems and is generally not recommended - * that users use this priority. - */ -#define TASK_PRIORITY_MIN 1 - -/** - * The default task priority, which should be used for most tasks unless you - * have a specific need for a higher or lower priority task. - * - * The default tasks, such as autonomous(), are run with this priority - */ -#define TASK_PRIORITY_DEFAULT 8 - -/** - * The recommended stack size for a new task. - * - * This stack size is used for the default tasks such as autonomous(). This - * size is 8,192 words, or 32,768 bytes. This should be enough for the majority - * of tasks - */ -#define TASK_STACK_DEPTH_DEFAULT 0x2000 - -/** - * The minimal stack size for a task. - * - * This equates to 512 words, or 2,048 bytes. - */ -#define TASK_STACK_DEPTH_MIN 0x200 - -/** - * The maximum number of characters allowed in a task's name. - */ -#define TASK_NAME_MAX_LEN 32 - -/** - * The maximum timeout value that can be given to, for instance, a mutex grab. - */ -#define TIMEOUT_MAX ((uint32_t)0xffffffffUL) - -/// @} Name: Macros - -/// \name Typedefs -/// @{ - -/** - * An opaque type that pontis to a task handle. This is used for referencing a - * task. - */ -typedef void* task_t; - -/** - * A pointer to a task's function. - * - * Such a function is called when a task starts, and exiting said function will - * terminate the task. - */ -typedef void (*task_fn_t)(void*); - -/// @} Name: Typedefs - - -/// \name Enumerations -/// @{ - -/** - * The state of a task. - */ -typedef enum { - E_TASK_STATE_RUNNING = 0, /**< The task is actively executing. */ - E_TASK_STATE_READY, /**< The task exists and is available to run, but is not currently running. */ - E_TASK_STATE_BLOCKED, /**< The task is delayed or blocked by a mutex, semaphore, or I/O operation. */ - E_TASK_STATE_SUSPENDED, /**< The task is supended using task_suspend. */ - E_TASK_STATE_DELETED, /**< The task has been deleted using task_delete. */ - E_TASK_STATE_INVALID /**< The task handle does not point to a current or past task.*/ -} task_state_e_t; - -/** - * brief The action to take when a task is notified. - */ -typedef enum { - E_NOTIFY_ACTION_NONE, /**< The task’s notification value will not be touched.*/ - E_NOTIFY_ACTION_BITS, /**< The task’s notification value will be bitwise ORed with the new value.*/ - E_NOTIFY_ACTION_INCR, /**< The task’s notification value will be incremented by one, effectively using it as a notification counter.*/ - E_NOTIFY_ACTION_OWRITE, /**< The task’s notification value will be unconditionally set to the new value.*/ - E_NOTIFY_ACTION_NO_OWRITE /**< The task’s notification value will be set to the new value if the task does not already have a pending notification.*/ -} notify_action_e_t; - -/// @} Name: Enumerations - -/// \name Simple enum names -/// @{ - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define TASK_STATE_RUNNING pros::E_TASK_STATE_RUNNING -#define TASK_STATE_READY pros::E_TASK_STATE_READY -#define TASK_STATE_BLOCKED pros::E_TASK_STATE_BLOCKED -#define TASK_STATE_SUSPENDED pros::E_TASK_STATE_SUSPENDED -#define TASK_STATE_DELETED pros::E_TASK_STATE_DELETED -#define TASK_STATE_INVALID pros::E_TASK_STATE_INVALID -#define NOTIFY_ACTION_NONE pros::E_NOTIFY_ACTION_NONE -#define NOTIFY_ACTION_BITS pros::E_NOTIFY_ACTION_BITS -#define NOTIFY_ACTION_INCR pros::E_NOTIFY_ACTION_INCR -#define NOTIFY_ACTION_OWRITE pros::E_NOTIFY_ACTION_OWRITE -#define NOTIFY_ACTION_NO_OWRITE pros::E_NOTIFY_ACTION_NO_OWRITE -#else -#define TASK_STATE_RUNNING E_TASK_STATE_RUNNING -#define TASK_STATE_READY E_TASK_STATE_READY -#define TASK_STATE_BLOCKED E_TASK_STATE_BLOCKED -#define TASK_STATE_SUSPENDED E_TASK_STATE_SUSPENDED -#define TASK_STATE_DELETED E_TASK_STATE_DELETED -#define TASK_STATE_INVALID E_TASK_STATE_INVALID -#define NOTIFY_ACTION_NONE E_NOTIFY_ACTION_NONE -#define NOTIFY_ACTION_BITS E_NOTIFY_ACTION_BITS -#define NOTIFY_ACTION_INCR E_NOTIFY_ACTION_INCR -#define NOTIFY_ACTION_OWRITE E_NOTIFY_ACTION_OWRITE -#define NOTIFY_ACTION_NO_OWRITE E_NOTIFY_ACTION_NO_OWRITE -#endif -#endif - -/// @} Name: Simple enum names - -/// \name Typedefs - -/** - * A [mutex.](@ref multitasking) - * - * A mutex is a synchronization object that can be used to protect a shared - * resource from being accessed by multiple tasks at the same time. A mutex can - * be claimed by a task, which will prevent other tasks from claiming it until - * that task releases it. - */ -typedef void* mutex_t; - -/// @} Name: Typedefs - -/** - * The task handle of the currently running task. - */ -#ifdef __cplusplus -#define CURRENT_TASK ((pros::task_t)NULL) -#else -#define CURRENT_TASK ((task_t)NULL) -#endif - -/// @} (add to group: c-rtos) - -#ifdef __cplusplus -namespace c { -#endif - -/// \ingroup c-rtos -/// \addtogroup c-rtos -/// @{ - -/** - * Gets the number of milliseconds since PROS initialized. - * - * \return The number of milliseconds since PROS initialized - * - * \b Example - * \code - * void opcontrol() { - * uint32_t now = millis(); - * while (true) { - * // Do opcontrol things - * task_delay_until(&now, 2); - * } - * } - * \endcode - */ -uint32_t millis(void); - -/** - * Gets the number of microseconds since PROS initialized, - * - * \return The number of microseconds since PROS initialized - * - * \b Example - * \code - * void opcontrol() { - * uint64_t now = micros(); - * while (true) { - * // Do opcontrol things - * task_delay_until(&now, 2000); - * } - * } - * \endcode - */ -uint64_t micros(void); - -/** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Pointer to the task entry function - * \param parameters - * Pointer to memory that will be used as a parameter for the task being - * created. This memory should not typically come from stack, but rather - * from dynamically (i.e., malloc'd) or statically allocated memory. - * \param prio - * The priority at which the task should run. - * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. - * \param stack_depth - * The number of words (i.e. 4 * stack_depth) available on the task's - * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \return A handle by which the newly created task can be referenced. If an - * error occurred, NULL will be returned and errno can be checked for hints as - * to why task_create failed. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * } - * \endcode - */ -task_t task_create(task_fn_t function, void* const parameters, uint32_t prio, const uint16_t stack_depth, - const char* const name); - -/** - * Removes a task from the RTOS real time kernel's management. The task being - * deleted will be removed from all ready, blocked, suspended and event lists. - * - * Memory dynamically allocated by the task is not automatically freed, and - * should be freed before the task is deleted. - * - * \param task - * The handle of the task to be deleted. Passing NULL will cause the - * calling task to be deleted. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * // Do other things - * task_delete(my_task); - * } - * \endcode - */ -void task_delete(task_t task); - -/** - * Delays the current task for a given number of milliseconds. - * - * This is not the best method to have a task execute code at predefined - * intervals, as the delay time is measured from when the delay is requested. - * To delay cyclically, use task_delay_until(). - * - * \param milliseconds - * The number of milliseconds to wait (1000 milliseconds per second) - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * // Do opcontrol things - * task_delay(2); - * } - * } - * \endcode - */ -void task_delay(const uint32_t milliseconds); - -/** - * Delays the current task for a given number of milliseconds. - * - * This is not the best method to have a task execute code at predefined - * intervals, as the delay time is measured from when the delay is requested. - * To delay cyclically, use task_delay_until(). - * - * \param milliseconds - * The number of milliseconds to wait (1000 milliseconds per second) - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * // Do opcontrol things - * delay(2); - * } - * } - * \endcode - */ -void delay(const uint32_t milliseconds); - -/** - * Delays the current task until a specified time. This function can be used - * by periodic tasks to ensure a constant execution frequency. - * - * The task will be woken up at the time *prev_time + delta, and *prev_time will - * be updated to reflect the time at which the task will unblock. - * - * \param prev_time - * A pointer to the location storing the setpoint time. This should - * typically be initialized to the return value of millis(). - * \param delta - * The number of milliseconds to wait (1000 milliseconds per second) - * - * \b Example - * \code - * void opcontrol() { - * uint32_t now = millis(); - * while (true) { - * // Do opcontrol things - * task_delay_until(&now, 2); - * } - * } - * \endcode - */ -void task_delay_until(uint32_t* const prev_time, const uint32_t delta); - -/** - * Gets the priority of the specified task. - * - * \param task - * The task to check - * - * \return The priority of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * printf("Task Priority: %d\n", task_get_priority(my_task)); - * } - * \endcode - */ -uint32_t task_get_priority(task_t task); - -/** - * Sets the priority of the specified task. - * - * If the specified task's state is available to be scheduled (e.g. not blocked) - * and new priority is higher than the currently running task, a context switch - * may occur. - * - * \param task - * The task to set - * \param prio - * The new priority of the task - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * // Do things - * } - * - * void opcontrol() { - * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "Example Task"); - * task_set_priority(my_task, TASK_PRIORITY_DEFAULT + 1); - * } - * \endcode - */ -void task_set_priority(task_t task, uint32_t prio); - -/** - * Gets the state of the specified task. - * - * \param task - * The task to check - * - * \return The state of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * printf("Task's State: %d\n", task_get_state(my_task)); - * } - * \endcode - */ -task_state_e_t task_get_state(task_t task); - -/** - * Suspends the specified task, making it ineligible to be scheduled. - * - * \param task - * The task to suspend - * - * \b Example - * \code - * mutex_t counter_mutex; - * int counter = 0; - * - * void my_task_fn(void* param) { - * while(true) { - * mutex_take(counter_mutex, TIMEOUT_MAX);// Mutexes are used for protecting shared resources - * counter++; - * mutex_give(counter_mutex); - * pros::delay(10); - * } - * } - * - * void opcontrol() { - * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,; - * - * while(true) { - * mutex_take(counter_mutex, TIMEOUT_MAX); - * if(counter > 100) { - * task_suspepend(task); - * } - * mutex_give(counter_mutex); - * pros::delay(10); - * } - * } - * \endcode - */ -void task_suspend(task_t task); - -/** - * Resumes the specified task, making it eligible to be scheduled. - * - * \param task - * The task to resume - * - * \b Example - * \code - * void my_task_fn(void* param) { - * while(true) { - * // Do stuff - * delay(10); - * } - * } - * - * task_t task; - * - * void initialize() { - * task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * } - * - * void autonomous() { - * task_resume(task); - * - * // Run autonomous , then suspend the task so it doesn't interfere run - * - * // outside of autonomous or opcontrol - * task_suspend(task); - * } - * - * void opcontrol() { - * task_resume(task); - * // Opctonrol code here - * task_suspend(task); - * } - * - * \endcode - */ -void task_resume(task_t task); - -/** - * Gets the number of tasks the kernel is currently managing, including all - * ready, blocked, or suspended tasks. A task that has been deleted, but not yet - * reaped by the idle task will also be included in the count. Tasks recently - * created may take one context switch to be counted. - * - * \return The number of tasks that are currently being managed by the kernel. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * printf("Number of Running Tasks: %d\n", task_get_count()); - * } - * \endcode - */ -uint32_t task_get_count(void); - -/** - * Gets the name of the specified task. - * - * \param task - * The task to check - * - * \return A pointer to the name of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * printf("Task Name: %d\n", task_get_name(my_task)); - * } - * \endcode - */ -char* task_get_name(task_t task); - -/** - * Gets a task handle from the specified name - * - * The operation takes a relatively long time and should be used sparingly. - * - * \param name - * The name to query - * - * \return A task handle with a matching name, or NULL if none were found. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * // Do other things - * task_delete(task_get_by_name("My Task")); - * } - * \endcode - */ -task_t task_get_by_name(const char* name); - -/** - * Get the currently running task handle. This could be useful if a task - * wants to tell another task about itself. - * - * \return The currently running task handle. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * task_t this_task = task_get_current(); - * if (task_get_state(this_take) == E_TASK_STATE_RUNNING) { - * printf("This task is currently running\n"); - * } - * // ... - * } - * - * void initialize() { - * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * } - * \endcode - */ -task_t task_get_current(); - -/** - * Sends a simple notification to task and increments the notification counter. - * - * \param task - * The task to notify - * - * \return Always returns true. - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * while(task_notify_take(true) == 0) { - * // Code while waiting - * } - * puts("I was unblocked!"); - * } - * - * void opcontrol() { - * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task_notify(my_task); - * } - * } - * } - * \endcode - */ -uint32_t task_notify(task_t task); - -/** - * - * Utilizes task notifications to wait until specified task is complete and deleted, - * then continues to execute the program. Analogous to std::thread::join in C++. - * - * \param task - * The handle of the task to wait on. - * - * \return void - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * lcd_print(1, "%s running", task_get_name(NULL)); - * task_delay(1000); - * lcd_print(2, "End of %s", task_get_name(NULL)); - * } - * - * void opcontrol() { - * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "Example Task"); - * lcd_set_text(0, "Running task."); - * task_join(my_task); - * lcd_set_text(3, "Task completed."); - * } - * \endcode - */ -void task_join(task_t task); - -/** - * Sends a notification to a task, optionally performing some action. Will also - * retrieve the value of the notification in the target task before modifying - * the notification value. - * - * \param task - * The task to notify - * \param value - * The value used in performing the action - * \param action - * An action to optionally perform on the receiving task's notification - * value - * \param prev_value - * A pointer to store the previous value of the target task's - * notification, may be NULL - * - * \return Dependent on the notification action. - * For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without - * needing to overwrite, 1 otherwise. - * For all other NOTIFY_ACTION values: always return 0 - * - * \b Example - * \code - * void my_task_fn(void* param) { - * while(true) { - * // Wait until we have been notified 20 times before running the code - * if(task_notify_take(false, TIMEOUT_MAX) == 20) { - * // ... Code to do stuff here ... - * - * // Reset the notification counter - * task_notify_take(true, TIMEOUT_MAX); - * } - * delay(10); - * } - * } - * - * void opcontrol() { - * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * - * int count = 0; - * - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task_notify_ext(task, 1, NOTIFY_ACTION_INCREMENT, &count); - * } - * - * delay(20); - * } - * } - * \endcode - */ -uint32_t task_notify_ext(task_t task, uint32_t value, notify_action_e_t action, uint32_t* prev_value); - -/** - * Waits for a notification to be nonzero. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \param clear_on_exit - * If true (1), then the notification value is cleared. - * If false (0), then the notification value is decremented. - * \param timeout - * Specifies the amount of time to be spent waiting for a notification - * to occur. - * - * \return The value of the task's notification value before it is decremented - * or cleared - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * task_t current_task = task_get_current(); - * while(task_notify_take(current_task, true, TIMEOUT_MAX)) { - * puts("I was unblocked!"); - * } - * } - * - * void opcontrol() { - * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task_notify(my_task); - * } - * } - * } - * \endcode - */ -uint32_t task_notify_take(bool clear_on_exit, uint32_t timeout); - -/** - * Clears the notification for a task. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \param task - * The task to clear - * - * \return False if there was not a notification waiting, true if there was - * - * \b Example - * \code - * void my_task_fn(void* param) { - * task_t task = task_get_current(); - * while(true) { - * printf("Waiting for notification...\n"); - * printf("Got a notification: %d\n", task_notify_take(task, false, TIMEOUT_MAX)); - * - * task_notify_clear(task); - * delay(10): - * } - * } - * - * void opcontrol() { - * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, - * TASK_STACK_DEPTH_DEFAULT, "My Task"); - * - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task_notify(task); - * } - * delay(10); - * } - * } - * \endcode - */ -bool task_notify_clear(task_t task); - -/** - * Creates a mutex. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes - * for details. - * - * \return A handle to a newly created mutex. If an error occurred, NULL will be - * returned and errno can be checked for hints as to why mutex_create failed. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * mutex_t odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * mutex_take(odom_mutex, MAX_DELAY); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * mutex_give(odom_mutex); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * mutex_take(odom_mutex, MAX_DELAY); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * mutex_give(odom_mutex); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * mutex_take(odom_mutex, MAX_DELAY); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * mutex_give(odom_mutex); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = mutex_create(); - * - * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); - * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); - * } - * \endcode - */ -mutex_t mutex_create(void); - -/** - * Takes and locks a mutex, waiting for up to a certain number of milliseconds - * before timing out. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes - * for details. - * - * \param mutex - * Mutex to attempt to lock. - * \param timeout - * Time to wait before the mutex becomes available. A timeout of 0 can - * be used to poll the mutex. TIMEOUT_MAX can be used to block - * indefinitely. - * - * \return True if the mutex was successfully taken, false otherwise. If false - * is returned, then errno is set with a hint about why the the mutex - * couldn't be taken. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * mutex_t odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * mutex_take(odom_mutex, MAX_DELAY); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * mutex_give(odom_mutex); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * mutex_take(odom_mutex, MAX_DELAY); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * mutex_give(odom_mutex); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * mutex_take(odom_mutex, MAX_DELAY); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * mutex_give(odom_mutex); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = mutex_create(); - * - * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); - * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); - * } - * \endcode - */ -bool mutex_take(mutex_t mutex, uint32_t timeout); - -/** - * Unlocks a mutex. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes - * for details. - * - * \param mutex - * Mutex to unlock. - * - * \return True if the mutex was successfully returned, false otherwise. If - * false is returned, then errno is set with a hint about why the mutex - * couldn't be returned. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * mutex_t odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * mutex_take(odom_mutex, MAX_DELAY); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * mutex_give(odom_mutex); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * mutex_take(odom_mutex, MAX_DELAY); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * mutex_give(odom_mutex); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * mutex_take(odom_mutex, MAX_DELAY); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * mutex_give(odom_mutex); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = mutex_create(); - * - * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); - * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); - * } - * \endcode - */ -bool mutex_give(mutex_t mutex); - -/** - * Deletes a mutex - * - * \param mutex - * Mutex to unlock. - * - * \b Example - * \code - * mutex_t mutex = mutex_create(); - * // Acquire the mutex; other tasks using this command will wait until the mutex is released - * // timeout can specify the maximum time to wait, or MAX_DELAY to wait forever - * // If the timeout expires, "false" will be returned, otherwise "true" - * mutex_take(mutex, MAX_DELAY); - * // do some work - * // Release the mutex for other tasks - * mutex_give(mutex); - * // Delete the mutex - * mutex_delete(mutex); - * \endcode - */ -void mutex_delete(mutex_t mutex); - -/// @} Add to group: c-rtos - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - -#endif // _PROS_RTOS_H_ +/** + * \file pros/rtos.h + * \ingroup c-rtos + * + * Contains declarations for the PROS RTOS kernel for use by typical VEX + * programmers. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-rtos RTOS Facilities C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref multitasking) + */ + +#ifndef _PROS_RTOS_H_ +#define _PROS_RTOS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/// \ingroup c-rtos + +/// \addtogroup c-rtos +/// @{ + +/// \name Macros +/// @{ + +/** + * The highest priority that can be assigned to a task. + * + * A task with this priority will always run if it is available to. Beware of + * deadlocks when using this priority. + */ +#define TASK_PRIORITY_MAX 16 + +/** + * The lowest priority that can be assigned to a task. + * + * This can cause severe performance problems and is generally not recommended + * that users use this priority. + */ +#define TASK_PRIORITY_MIN 1 + +/** + * The default task priority, which should be used for most tasks unless you + * have a specific need for a higher or lower priority task. + * + * The default tasks, such as autonomous(), are run with this priority + */ +#define TASK_PRIORITY_DEFAULT 8 + +/** + * The recommended stack size for a new task. + * + * This stack size is used for the default tasks such as autonomous(). This + * size is 8,192 words, or 32,768 bytes. This should be enough for the majority + * of tasks + */ +#define TASK_STACK_DEPTH_DEFAULT 0x2000 + +/** + * The minimal stack size for a task. + * + * This equates to 512 words, or 2,048 bytes. + */ +#define TASK_STACK_DEPTH_MIN 0x200 + +/** + * The maximum number of characters allowed in a task's name. + */ +#define TASK_NAME_MAX_LEN 32 + +/** + * The maximum timeout value that can be given to, for instance, a mutex grab. + */ +#define TIMEOUT_MAX ((uint32_t)0xffffffffUL) + +/// @} Name: Macros + +/// \name Typedefs +/// @{ + +/** + * An opaque type that pontis to a task handle. This is used for referencing a + * task. + */ +typedef void* task_t; + +/** + * A pointer to a task's function. + * + * Such a function is called when a task starts, and exiting said function will + * terminate the task. + */ +typedef void (*task_fn_t)(void*); + +/// @} Name: Typedefs + + +/// \name Enumerations +/// @{ + +/** + * The state of a task. + */ +typedef enum { + E_TASK_STATE_RUNNING = 0, /**< The task is actively executing. */ + E_TASK_STATE_READY, /**< The task exists and is available to run, but is not currently running. */ + E_TASK_STATE_BLOCKED, /**< The task is delayed or blocked by a mutex, semaphore, or I/O operation. */ + E_TASK_STATE_SUSPENDED, /**< The task is supended using task_suspend. */ + E_TASK_STATE_DELETED, /**< The task has been deleted using task_delete. */ + E_TASK_STATE_INVALID /**< The task handle does not point to a current or past task.*/ +} task_state_e_t; + +/** + * brief The action to take when a task is notified. + */ +typedef enum { + E_NOTIFY_ACTION_NONE, /**< The task’s notification value will not be touched.*/ + E_NOTIFY_ACTION_BITS, /**< The task’s notification value will be bitwise ORed with the new value.*/ + E_NOTIFY_ACTION_INCR, /**< The task’s notification value will be incremented by one, effectively using it as a notification counter.*/ + E_NOTIFY_ACTION_OWRITE, /**< The task’s notification value will be unconditionally set to the new value.*/ + E_NOTIFY_ACTION_NO_OWRITE /**< The task’s notification value will be set to the new value if the task does not already have a pending notification.*/ +} notify_action_e_t; + +/// @} Name: Enumerations + +/// \name Simple enum names +/// @{ + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define TASK_STATE_RUNNING pros::E_TASK_STATE_RUNNING +#define TASK_STATE_READY pros::E_TASK_STATE_READY +#define TASK_STATE_BLOCKED pros::E_TASK_STATE_BLOCKED +#define TASK_STATE_SUSPENDED pros::E_TASK_STATE_SUSPENDED +#define TASK_STATE_DELETED pros::E_TASK_STATE_DELETED +#define TASK_STATE_INVALID pros::E_TASK_STATE_INVALID +#define NOTIFY_ACTION_NONE pros::E_NOTIFY_ACTION_NONE +#define NOTIFY_ACTION_BITS pros::E_NOTIFY_ACTION_BITS +#define NOTIFY_ACTION_INCR pros::E_NOTIFY_ACTION_INCR +#define NOTIFY_ACTION_OWRITE pros::E_NOTIFY_ACTION_OWRITE +#define NOTIFY_ACTION_NO_OWRITE pros::E_NOTIFY_ACTION_NO_OWRITE +#else +#define TASK_STATE_RUNNING E_TASK_STATE_RUNNING +#define TASK_STATE_READY E_TASK_STATE_READY +#define TASK_STATE_BLOCKED E_TASK_STATE_BLOCKED +#define TASK_STATE_SUSPENDED E_TASK_STATE_SUSPENDED +#define TASK_STATE_DELETED E_TASK_STATE_DELETED +#define TASK_STATE_INVALID E_TASK_STATE_INVALID +#define NOTIFY_ACTION_NONE E_NOTIFY_ACTION_NONE +#define NOTIFY_ACTION_BITS E_NOTIFY_ACTION_BITS +#define NOTIFY_ACTION_INCR E_NOTIFY_ACTION_INCR +#define NOTIFY_ACTION_OWRITE E_NOTIFY_ACTION_OWRITE +#define NOTIFY_ACTION_NO_OWRITE E_NOTIFY_ACTION_NO_OWRITE +#endif +#endif + +/// @} Name: Simple enum names + +/// \name Typedefs + +/** + * A [mutex.](@ref multitasking) + * + * A mutex is a synchronization object that can be used to protect a shared + * resource from being accessed by multiple tasks at the same time. A mutex can + * be claimed by a task, which will prevent other tasks from claiming it until + * that task releases it. + */ +typedef void* mutex_t; + +/// @} Name: Typedefs + +/** + * The task handle of the currently running task. + */ +#ifdef __cplusplus +#define CURRENT_TASK ((pros::task_t)NULL) +#else +#define CURRENT_TASK ((task_t)NULL) +#endif + +/// @} (add to group: c-rtos) + +#ifdef __cplusplus +namespace c { +#endif + +/// \ingroup c-rtos +/// \addtogroup c-rtos +/// @{ + +/** + * Gets the number of milliseconds since PROS initialized. + * + * \return The number of milliseconds since PROS initialized + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * // Do opcontrol things + * task_delay_until(&now, 2); + * } + * } + * \endcode + */ +uint32_t millis(void); + +/** + * Gets the number of microseconds since PROS initialized, + * + * \return The number of microseconds since PROS initialized + * + * \b Example + * \code + * void opcontrol() { + * uint64_t now = micros(); + * while (true) { + * // Do opcontrol things + * task_delay_until(&now, 2000); + * } + * } + * \endcode + */ +uint64_t micros(void); + +/** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Pointer to the task entry function + * \param parameters + * Pointer to memory that will be used as a parameter for the task being + * created. This memory should not typically come from stack, but rather + * from dynamically (i.e., malloc'd) or statically allocated memory. + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \return A handle by which the newly created task can be referenced. If an + * error occurred, NULL will be returned and errno can be checked for hints as + * to why task_create failed. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +task_t task_create(task_fn_t function, void* const parameters, uint32_t prio, const uint16_t stack_depth, + const char* const name); + +/** + * Removes a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * Memory dynamically allocated by the task is not automatically freed, and + * should be freed before the task is deleted. + * + * \param task + * The handle of the task to be deleted. Passing NULL will cause the + * calling task to be deleted. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * // Do other things + * task_delete(my_task); + * } + * \endcode + */ +void task_delete(task_t task); + +/** + * Delays the current task for a given number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * task_delay(2); + * } + * } + * \endcode + */ +void task_delay(const uint32_t milliseconds); + +/** + * Delays the current task for a given number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * delay(2); + * } + * } + * \endcode + */ +void delay(const uint32_t milliseconds); + +/** + * Delays the current task until a specified time. This function can be used + * by periodic tasks to ensure a constant execution frequency. + * + * The task will be woken up at the time *prev_time + delta, and *prev_time will + * be updated to reflect the time at which the task will unblock. + * + * \param prev_time + * A pointer to the location storing the setpoint time. This should + * typically be initialized to the return value of millis(). + * \param delta + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * uint32_t now = millis(); + * while (true) { + * // Do opcontrol things + * task_delay_until(&now, 2); + * } + * } + * \endcode + */ +void task_delay_until(uint32_t* const prev_time, const uint32_t delta); + +/** + * Gets the priority of the specified task. + * + * \param task + * The task to check + * + * \return The priority of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Task Priority: %d\n", task_get_priority(my_task)); + * } + * \endcode + */ +uint32_t task_get_priority(task_t task); + +/** + * Sets the priority of the specified task. + * + * If the specified task's state is available to be scheduled (e.g. not blocked) + * and new priority is higher than the currently running task, a context switch + * may occur. + * + * \param task + * The task to set + * \param prio + * The new priority of the task + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * // Do things + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Example Task"); + * task_set_priority(my_task, TASK_PRIORITY_DEFAULT + 1); + * } + * \endcode + */ +void task_set_priority(task_t task, uint32_t prio); + +/** + * Gets the state of the specified task. + * + * \param task + * The task to check + * + * \return The state of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Task's State: %d\n", task_get_state(my_task)); + * } + * \endcode + */ +task_state_e_t task_get_state(task_t task); + +/** + * Suspends the specified task, making it ineligible to be scheduled. + * + * \param task + * The task to suspend + * + * \b Example + * \code + * mutex_t counter_mutex; + * int counter = 0; + * + * void my_task_fn(void* param) { + * while(true) { + * mutex_take(counter_mutex, TIMEOUT_MAX);// Mutexes are used for protecting shared resources + * counter++; + * mutex_give(counter_mutex); + * pros::delay(10); + * } + * } + * + * void opcontrol() { + * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,; + * + * while(true) { + * mutex_take(counter_mutex, TIMEOUT_MAX); + * if(counter > 100) { + * task_suspepend(task); + * } + * mutex_give(counter_mutex); + * pros::delay(10); + * } + * } + * \endcode + */ +void task_suspend(task_t task); + +/** + * Resumes the specified task, making it eligible to be scheduled. + * + * \param task + * The task to resume + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while(true) { + * // Do stuff + * delay(10); + * } + * } + * + * task_t task; + * + * void initialize() { + * task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * + * void autonomous() { + * task_resume(task); + * + * // Run autonomous , then suspend the task so it doesn't interfere run + * + * // outside of autonomous or opcontrol + * task_suspend(task); + * } + * + * void opcontrol() { + * task_resume(task); + * // Opctonrol code here + * task_suspend(task); + * } + * + * \endcode + */ +void task_resume(task_t task); + +/** + * Gets the number of tasks the kernel is currently managing, including all + * ready, blocked, or suspended tasks. A task that has been deleted, but not yet + * reaped by the idle task will also be included in the count. Tasks recently + * created may take one context switch to be counted. + * + * \return The number of tasks that are currently being managed by the kernel. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Number of Running Tasks: %d\n", task_get_count()); + * } + * \endcode + */ +uint32_t task_get_count(void); + +/** + * Gets the name of the specified task. + * + * \param task + * The task to check + * + * \return A pointer to the name of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * printf("Task Name: %d\n", task_get_name(my_task)); + * } + * \endcode + */ +char* task_get_name(task_t task); + +/** + * Gets a task handle from the specified name + * + * The operation takes a relatively long time and should be used sparingly. + * + * \param name + * The name to query + * + * \return A task handle with a matching name, or NULL if none were found. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * // Do other things + * task_delete(task_get_by_name("My Task")); + * } + * \endcode + */ +task_t task_get_by_name(const char* name); + +/** + * Get the currently running task handle. This could be useful if a task + * wants to tell another task about itself. + * + * \return The currently running task handle. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * task_t this_task = task_get_current(); + * if (task_get_state(this_take) == E_TASK_STATE_RUNNING) { + * printf("This task is currently running\n"); + * } + * // ... + * } + * + * void initialize() { + * task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ +task_t task_get_current(); + +/** + * Sends a simple notification to task and increments the notification counter. + * + * \param task + * The task to notify + * + * \return Always returns true. + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * while(task_notify_take(true) == 0) { + * // Code while waiting + * } + * puts("I was unblocked!"); + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify(my_task); + * } + * } + * } + * \endcode + */ +uint32_t task_notify(task_t task); + +/** + * + * Utilizes task notifications to wait until specified task is complete and deleted, + * then continues to execute the program. Analogous to std::thread::join in C++. + * + * \param task + * The handle of the task to wait on. + * + * \return void + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * lcd_print(1, "%s running", task_get_name(NULL)); + * task_delay(1000); + * lcd_print(2, "End of %s", task_get_name(NULL)); + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Example Task"); + * lcd_set_text(0, "Running task."); + * task_join(my_task); + * lcd_set_text(3, "Task completed."); + * } + * \endcode + */ +void task_join(task_t task); + +/** + * Sends a notification to a task, optionally performing some action. Will also + * retrieve the value of the notification in the target task before modifying + * the notification value. + * + * \param task + * The task to notify + * \param value + * The value used in performing the action + * \param action + * An action to optionally perform on the receiving task's notification + * value + * \param prev_value + * A pointer to store the previous value of the target task's + * notification, may be NULL + * + * \return Dependent on the notification action. + * For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without + * needing to overwrite, 1 otherwise. + * For all other NOTIFY_ACTION values: always return 0 + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while(true) { + * // Wait until we have been notified 20 times before running the code + * if(task_notify_take(false, TIMEOUT_MAX) == 20) { + * // ... Code to do stuff here ... + * + * // Reset the notification counter + * task_notify_take(true, TIMEOUT_MAX); + * } + * delay(10); + * } + * } + * + * void opcontrol() { + * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * + * int count = 0; + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify_ext(task, 1, NOTIFY_ACTION_INCREMENT, &count); + * } + * + * delay(20); + * } + * } + * \endcode + */ +uint32_t task_notify_ext(task_t task, uint32_t value, notify_action_e_t action, uint32_t* prev_value); + +/** + * Waits for a notification to be nonzero. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param clear_on_exit + * If true (1), then the notification value is cleared. + * If false (0), then the notification value is decremented. + * \param timeout + * Specifies the amount of time to be spent waiting for a notification + * to occur. + * + * \return The value of the task's notification value before it is decremented + * or cleared + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * task_t current_task = task_get_current(); + * while(task_notify_take(current_task, true, TIMEOUT_MAX)) { + * puts("I was unblocked!"); + * } + * } + * + * void opcontrol() { + * task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify(my_task); + * } + * } + * } + * \endcode + */ +uint32_t task_notify_take(bool clear_on_exit, uint32_t timeout); + +/** + * Clears the notification for a task. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param task + * The task to clear + * + * \return False if there was not a notification waiting, true if there was + * + * \b Example + * \code + * void my_task_fn(void* param) { + * task_t task = task_get_current(); + * while(true) { + * printf("Waiting for notification...\n"); + * printf("Got a notification: %d\n", task_notify_take(task, false, TIMEOUT_MAX)); + * + * task_notify_clear(task); + * delay(10): + * } + * } + * + * void opcontrol() { + * task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT, + * TASK_STACK_DEPTH_DEFAULT, "My Task"); + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task_notify(task); + * } + * delay(10); + * } + * } + * \endcode + */ +bool task_notify_clear(task_t task); + +/** + * Creates a mutex. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return A handle to a newly created mutex. If an error occurred, NULL will be + * returned and errno can be checked for hints as to why mutex_create failed. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * mutex_t odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * mutex_take(odom_mutex, MAX_DELAY); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * mutex_give(odom_mutex); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * mutex_take(odom_mutex, MAX_DELAY); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * mutex_give(odom_mutex); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * mutex_take(odom_mutex, MAX_DELAY); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * mutex_give(odom_mutex); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = mutex_create(); + * + * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); + * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); + * } + * \endcode + */ +mutex_t mutex_create(void); + +/** + * Takes and locks a mutex, waiting for up to a certain number of milliseconds + * before timing out. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param mutex + * Mutex to attempt to lock. + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * mutex_t odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * mutex_take(odom_mutex, MAX_DELAY); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * mutex_give(odom_mutex); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * mutex_take(odom_mutex, MAX_DELAY); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * mutex_give(odom_mutex); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * mutex_take(odom_mutex, MAX_DELAY); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * mutex_give(odom_mutex); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = mutex_create(); + * + * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); + * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); + * } + * \endcode + */ +bool mutex_take(mutex_t mutex, uint32_t timeout); + +/** + * Unlocks a mutex. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param mutex + * Mutex to unlock. + * + * \return True if the mutex was successfully returned, false otherwise. If + * false is returned, then errno is set with a hint about why the mutex + * couldn't be returned. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * mutex_t odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * mutex_take(odom_mutex, MAX_DELAY); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * mutex_give(odom_mutex); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * mutex_take(odom_mutex, MAX_DELAY); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * mutex_give(odom_mutex); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * mutex_take(odom_mutex, MAX_DELAY); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * mutex_give(odom_mutex); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = mutex_create(); + * + * task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task"); + * task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task"); + * } + * \endcode + */ +bool mutex_give(mutex_t mutex); + +/** + * Deletes a mutex + * + * \param mutex + * Mutex to unlock. + * + * \b Example + * \code + * mutex_t mutex = mutex_create(); + * // Acquire the mutex; other tasks using this command will wait until the mutex is released + * // timeout can specify the maximum time to wait, or MAX_DELAY to wait forever + * // If the timeout expires, "false" will be returned, otherwise "true" + * mutex_take(mutex, MAX_DELAY); + * // do some work + * // Release the mutex for other tasks + * mutex_give(mutex); + * // Delete the mutex + * mutex_delete(mutex); + * \endcode + */ +void mutex_delete(mutex_t mutex); + +/// @} Add to group: c-rtos + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_RTOS_H_ diff --git a/include/pros/rtos.hpp b/include/pros/rtos.hpp index 0a98d8c..f02495c 100644 --- a/include/pros/rtos.hpp +++ b/include/pros/rtos.hpp @@ -1,1580 +1,1580 @@ -/** - * \file pros/rtos.hpp - * \ingroup cpp-rtos - * - * Contains declarations for the PROS RTOS kernel for use by typical VEX - * programmers. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup cpp-rtos RTOS Facilities C++ API - * \note Additional example code for this module can be found in its [Tutorial.](@ref multitasking) - */ - -#ifndef _PROS_RTOS_HPP_ -#define _PROS_RTOS_HPP_ - -#include "pros/rtos.h" -#undef delay -#include -#include -#include -#include -#include -#include -#include - -namespace pros { -inline namespace rtos { -/** - * \ingroup cpp-rtos - */ -class Task { - /** - * \addtogroup cpp-rtos - * @{ - */ - public: - /** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Pointer to the task entry function - * \param parameters - * Pointer to memory that will be used as a parameter for the task - * being created. This memory should not typically come from stack, - * but rather from dynamically (i.e., malloc'd) or statically - * allocated memory. - * \param prio - * The priority at which the task should run. - * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. - * \param stack_depth - * The number of words (i.e. 4 * stack_depth) available on the task's - * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, (void*)"PROS"); - * } - * \endcode - */ - Task(task_fn_t function, void* parameters = nullptr, std::uint32_t prio = TASK_PRIORITY_DEFAULT, - std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = ""); - - /** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Pointer to the task entry function - * \param parameters - * Pointer to memory that will be used as a parameter for the task - * being created. This memory should not typically come from stack, - * but rather from dynamically (i.e., malloc'd) or statically - * allocated memory. - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, (void*)"PROS", "My Task"); - * } - * \endcode - */ - Task(task_fn_t function, void* parameters, const char* name); - - /** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Callable object to use as entry function - * \param prio - * The priority at which the task should run. - * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. - * \param stack_depth - * The number of words (i.e. 4 * stack_depth) available on the task's - * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::c::task_t my_task = pros::Task::create(my_task_fn, (void*)"PROS"); - * } - * \endcode - */ - template - static task_t create(F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, - std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") { - static_assert(std::is_invocable_r_v); - return pros::c::task_create( - [](void* parameters) { - std::unique_ptr> ptr{static_cast*>(parameters)}; - (*ptr)(); - }, - new std::function(std::forward(function)), prio, stack_depth, name); - } - - /** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Callable object to use as entry function - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); - * } - * \endcode - */ - template - static task_t create(F&& function, const char* name) { - return Task::create(std::forward(function), TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, name); - } - - /** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Callable object to use as entry function - * \param prio - * The priority at which the task should run. - * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. - * \param stack_depth - * The number of words (i.e. 4 * stack_depth) available on the task's - * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficient. - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \b Example - * \code - * - * void initialize() { - * // Create a task function using lambdas - * auto task_fn = [](void* param) { - * printf("Hello %s\n", (char*)param); - * } - * - * pros::Task my_task(task_fn, (void*)"PROS", "My Task"); - * } - * \endcode - */ - template - explicit Task(F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, - std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") - : Task( - [](void* parameters) { - std::unique_ptr> ptr{static_cast*>(parameters)}; - (*ptr)(); - }, - new std::function(std::forward(function)), prio, stack_depth, name) { - static_assert(std::is_invocable_r_v); - } - - /** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * This function uses the following values of errno when an error state is - * reached: - * ENOMEM - The stack cannot be used as the TCB was not created. - * - * \param function - * Callable object to use as entry function - * \param name - * A descriptive name for the task. This is mainly used to facilitate - * debugging. The name may be up to 32 characters long. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task( - * [](void* param) { - * printf("Inside the task!\n"); - * }, - * "My Task" - * ); - * } - * \endcode - */ - template - Task(F&& function, const char* name) - : Task(std::forward(function), TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, name) {} - - /** - * Create a C++ task object from a task handle - * - * \param task - * A task handle from task_create() for which to create a pros::Task - * object. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); - * - * pros::Task my_task_cpp(my_task); - * } - * \endcode - */ - explicit Task(task_t task); - - /** - * Get the currently running Task - * - * @return The currently running Task. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, pros::TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); - * } - * \endcode - */ - static Task current(); - - /** - * Creates a task object from the passed task handle. - * - * \param in - * A task handle from task_create() for which to create a pros::Task - * object. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() - * } - * - * void initialize() { - * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); - * - * pros::Task my_task_cpp = my_task; - * } - * \endcode - */ - Task& operator=(task_t in); - - /** - * Removes the Task from the RTOS real time kernel's management. This task - * will be removed from all ready, blocked, suspended and event lists. - * - * Memory dynamically allocated by the task is not automatically freed, and - * should be freed before the task is deleted. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, "My Task"); - * - * my_task.remove(); - * } - * \endcode - */ - void remove(); - - /** - * Gets the priority of the specified task. - * - * \return The priority of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, "My Task"); - * - * printf("Task Priority: %d\n", my_task.get_priority()); - * } - * \endcode - */ - std::uint32_t get_priority(); - - /** - * Sets the priority of the specified task. - * - * If the specified task's state is available to be scheduled (e.g. not - * blocked) and new priority is higher than the currently running task, - * a context switch may occur. - * - * \param prio - * The new priority of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, "My Task"); - * - * Task.set_priority(pros::DEFAULT_PRIORITY + 1); - * } - * \endcode - */ - void set_priority(std::uint32_t prio); - - /** - * Gets the state of the specified task. - * - * \return The state of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, "My Task"); - * - * printf("Task State: %d\n", my_task.get_state()); - * } - * \endcode - */ - std::uint32_t get_state(); - - /** - * Suspends the specified task, making it ineligible to be scheduled. - * - * \b Example - * \code - * pros::Mutex counter_mutex; - * int counter = 0; - * - * void my_task_fn(void* param) { - * while(true) { - * counter_mutex.take(); // Mutexes are used for protecting shared resources - * counter++; - * counter_mutex.give(); - * pros::delay(10); - * } - * } - * - * void opcontrol() { - * pros::Task task(my_task_fn, "My Task"); - * - * while(true) { - * counter_mutex.take(); - * if(counter > 100) { - * task_suspepend(task); - * } - * counter_mutex.give(); - * pros::delay(10); - * } - * } - * \endcode - */ - void suspend(); - - /** - * Resumes the specified task, making it eligible to be scheduled. - * - * \param task - * The task to resume - * - * \b Example - * \code - * void my_task_fn(void* param) { - * while(true) { - * // Do stuff - * pros::delay(10); - * } - * } - * - * pros::Task task(my_task_fn); - * - * void autonomous() { - * task.resume(); - * - * // Run autonomous , then suspend the task so it doesn't interfere run - * // outside of autonomous or opcontrol - * task.suspend(); - * } - * - * void opcontrol() { - * task.resume(); - * // Opctonrol code here - * task.suspend(); - * } - * - * \endcode - */ - void resume(); - - /** - * Gets the name of the specified task. - * - * \return A pointer to the name of the task - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, "My Task"); - * printf("Number of Running Tasks: %d\n", my_task.get_name()); - * } - * \endcode - */ - const char* get_name(); - - /** - * Convert this object to a C task_t handle - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void initialize() { - * pros::Task my_task(my_task_fn, "My Task"); - * - * pros::c::task_t my_task_c = (pros::c::task_t)my_task; - * } - * \endcode - */ - explicit operator task_t() { - return task; - } - - /** - * Sends a simple notification to task and increments the notification - * counter. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \return Always returns true. - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * while(pros::Task::current_task().notify_take(true) == 0) { - * // Code while waiting - * } - * puts("I was unblocked!"); - * } - * - * void opcontrol() { - * pros::Task my_task(my_task_fn); - * - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * my_task.notify(); - * } - * } - * } - * \endcode - */ - std::uint32_t notify(); - - /** - * Utilizes task notifications to wait until specified task is complete and deleted, - * then continues to execute the program. Analogous to std::thread::join in C++. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \return void - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * lcd_print(1, "%s running", pros::Task::current_task().get_name()); - * task_delay(1000); - * lcd_print(2, "End of %s", pros::Task::current_task().get_name()); - * } - * - * void opcontrol() { - * pros::Task my_task(my_task_fn); - * pros::lcd::set_text(0, "Running task."); - * my_task.join(); - * pros::lcd::lcd_set_text(3, "Task completed."); - * } - * \endcode - */ - void join(); - - /** - * Sends a notification to a task, optionally performing some action. Will - * also retrieve the value of the notification in the target task before - * modifying the notification value. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \param value - * The value used in performing the action - * \param action - * An action to optionally perform on the receiving task's notification - * value - * \param prev_value - * A pointer to store the previous value of the target task's - * notification, may be NULL - * - * \return Dependent on the notification action. - * For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without - * needing to overwrite, 1 otherwise. - * For all other NOTIFY_ACTION values: always return 0 - * - * \b Example - * \code - * void my_task_fn(void* param) { - * pros::Task task = pros::Task::current(); - * - * while(true) { - * // Wait until we have been notified 20 times before running the code - * if(task.notify_take(false, TIMEOUT_MAX) == 20) { - * // ... Code to do stuff here ... - * - * // Reset the notification counter - * task.notify_clear(); - * } - * delay(10); - * } - * } - * - * void opcontrol() { - * pros::Task task(my_task_fn); - * - * int count = 0; - * - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task.notify_ext(1, NOTIFY_ACTION_INCREMENT, &count); - * } - * - * delay(20); - * } - * } - * \endcode - */ - std::uint32_t notify_ext(std::uint32_t value, notify_action_e_t action, std::uint32_t* prev_value); - - /** - * Waits for a notification to be nonzero. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \param clear_on_exit - * If true (1), then the notification value is cleared. - * If false (0), then the notification value is decremented. - * \param timeout - * Specifies the amount of time to be spent waiting for a notification - * to occur. - * - * \return The value of the task's notification value before it is decremented - * or cleared - * - * \b Example - * \code - * void my_task_fn(void* ign) { - * pros::Task task = pros::task::current(); - * while(task.notify_take(true, TIMEOUT_MAX)) { - * puts("I was unblocked!"); - * } - * } - * - * void opcontrol() { - * pros::Task task(my_task_fn); - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task.notify(my_task); - * } - * } - * } - * \endcode - */ - static std::uint32_t notify_take(bool clear_on_exit, std::uint32_t timeout); - - /** - * Clears the notification for a task. - * - * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for - * details. - * - * \return False if there was not a notification waiting, true if there was - * \b Example - * \code - * void my_task_fn(void* param) { - * pros::Task task = pros::Task::current(); - * while(true) { - * printf("Waiting for notification...\n"); - * printf("Got a notification: %d\n", task.notify_take(false, TIMEOUT_MAX)); - * - * tasK_notify(task); - * delay(10): - * } - * } - * - * void opcontrol() { - * pros::Task task(my_task_fn); - * while(true) { - * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { - * task.notify(); - * } - * delay(10); - * } - * } - * \endcode - */ - bool notify_clear(); - - /** - * Delays the current task for a specified number of milliseconds. - * - * This is not the best method to have a task execute code at predefined - * intervals, as the delay time is measured from when the delay is requested. - * To delay cyclically, use task_delay_until(). - * - * \param milliseconds - * The number of milliseconds to wait (1000 milliseconds per second) - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * // Do opcontrol things - * pros::Task::delay(2); - * } - * \endcode - */ - static void delay(const std::uint32_t milliseconds); - - /** - * Delays the current Task until a specified time. This function can be used by - * periodic tasks to ensure a constant execution frequency. - * - * The task will be woken up at the time *prev_time + delta, and *prev_time - * will be updated to reflect the time at which the task will unblock. - * - * \param prev_time - * A pointer to the location storing the setpoint time. This should - * typically be initialized to the return value from pros::millis(). - * \param delta - * The number of milliseconds to wait (1000 milliseconds per second) - * - * \b Example - * \code - * void opcontrol() { - * while (true) { - * // Do opcontrol things - * pros::Task::delay(2); - * } - * } - * \endcode - */ - static void delay_until(std::uint32_t* const prev_time, const std::uint32_t delta); - - /** - * Gets the number of tasks the kernel is currently managing, including all - * ready, blocked, or suspended tasks. A task that has been deleted, but not - * yet reaped by the idle task will also be included in the count. - * Tasks recently created may take one context switch to be counted. - * - * \return The number of tasks that are currently being managed by the kernel. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * printf("Hello %s\n", (char*)param); - * // ... - * } - * - * void opcontrol() { - * pros::Task my_task(my_task_fn); - * printf("There are %d tasks running\n", pros::Task::get_count()); - * } - * \endcode - */ - static std::uint32_t get_count(); - - private: - task_t task{}; -}; - -// STL Clock compliant clock -struct Clock { - using rep = std::uint32_t; - using period = std::milli; - using duration = std::chrono::duration; - using time_point = std::chrono::time_point; - const bool is_steady = true; - - /** - * Gets the current time. - * - * Effectively a wrapper around pros::millis() - * - * \return The current time - * - * \b Example - * \code - * void opcontrol() { - * pros::Clock::time_point start = pros::Clock::now(); - * pros::Clock::time_point end = pros::Clock::now(); - * pros::Clock::duration duration = end - start; - * printf("Duration: %d\n", duration.count()); - * - * if(duration.count() == 500) { - * // If you see this comment in the DOCS, ping @pros in VTOW. - * // If you are the first person to do so, you will receive a free PROS - * // holo! - * printf("Duration is 500 milliseconds\n"); - * } - * } - * \endcode - */ - static time_point now(); -}; - -class Mutex { - std::shared_ptr> mutex; - - public: - Mutex(); - - // disable copy and move construction and assignment per Mutex requirements - // (see https://en.cppreference.com/w/cpp/named_req/Mutex) - Mutex(const Mutex&) = delete; - Mutex(Mutex&&) = delete; - - Mutex& operator=(const Mutex&) = delete; - Mutex& operator=(Mutex&&) = delete; - - /** - * Takes and locks a mutex indefinetly. - * - * See - * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes - * for details. - * - * \return True if the mutex was successfully taken, false otherwise. If false - * is returned, then errno is set with a hint about why the the mutex - * couldn't be taken - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * pros::Mutex odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * odom_mutex.take(); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * odom_mutex.give(); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * odom_mutex.take(); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * odom_mutex.give(); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * odom_mutex.take(); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * odom_mutex.give(); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = pros::Mutex(); - * - * pros::Task odom_task(odom_task, "Odometry Task"); - * pros::Task chassis_task(odom_task, "Chassis Control Task"); - * } - * \endcode. - */ - bool take(); - - /** - * Takes and locks a mutex, waiting for up to a certain number of milliseconds - * before timing out. - * - * See - * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes - * for details. - * - * \param timeout - * Time to wait before the mutex becomes available. A timeout of 0 can - * be used to poll the mutex. TIMEOUT_MAX can be used to block - * indefinitely. - * - * \return True if the mutex was successfully taken, false otherwise. If false - * is returned, then errno is set with a hint about why the the mutex - * couldn't be taken. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * pros::Mutex odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * odom_mutex.take(); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * odom_mutex.give(); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * odom_mutex.take(); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * odom_mutex.give(); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * odom_mutex.take(); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * odom_mutex.give(); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = pros::Mutex(); - * - * pros::Task odom_task(odom_task, "Odometry Task"); - * pros::Task chassis_task(odom_task, "Chassis Control Task"); - * } - * \endcode. - */ - bool take(std::uint32_t timeout); - - /** - * Unlocks a mutex. - * - * See - * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes - * for details. - * - * \return True if the mutex was successfully returned, false otherwise. If - * false is returned, then errno is set with a hint about why the mutex - * couldn't be returned. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * pros::Mutex odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * odom_mutex.take(); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * odom_mutex.give(); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * odom_mutex.take(); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * odom_mutex.give(); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * odom_mutex.take(); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * odom_mutex.give(); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = pros::Mutex(); - * - * pros::Task odom_task(odom_task, "Odometry Task"); - * pros::Task chassis_task(odom_task, "Chassis Control Task"); - * } - * \endcode. - */ - bool give(); - - /** - * Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds. - * - * Effectively equivalent to calling pros::Mutex::take with TIMEOUT_MAX as - * the parameter. - * - * Conforms to named requirment BasicLockable - * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable - * - * \note Consider using a std::unique_lock, std::lock_guard, or - * std::scoped_lock instead of interacting with the Mutex directly. - * - * \exception std::system_error Mutex could not be locked within TIMEOUT_MAX - * milliseconds. see errno for details. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * pros::Mutex odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * odom_mutex.lock(); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * odom_mutex.unlock(); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * odom_mutex.lock(); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * odom_mutex.unlock(); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * odom_mutex.lock(); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * odom_mutex.unlock(); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = pros::Mutex(); - * - * pros::Task odom_task(odom_task, "Odometry Task"); - * pros::Task chassis_task(odom_task, "Chassis Control Task"); - * } - * \endcode. - */ - void lock(); - - /** - * Unlocks a mutex. - * - * Equivalent to calling pros::Mutex::give. - * - * Conforms to named requirement BasicLockable - * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable - * - * \note Consider using a std::unique_lock, std::lock_guard, or - * std::scoped_lock instead of interacting with the Mutex direcly. - * - * \b Example - * \code - * // Global variables for the robot's odometry, which the rest of the robot's - * // subsystems will utilize - * double odom_x = 0.0; - * double odom_y = 0.0; - * double odom_heading = 0.0; - * - * // This mutex protects the odometry data. Whenever we read or write to the - * // odometry data, we should make copies into the local variables, and read - * // all 3 values at once to avoid errors. - * pros::Mutex odom_mutex; - * - * void odom_task(void* param) { - * while(true) { - * // First we fetch the odom coordinates from the previous iteration of the - * // odometry task. These are put into local variables so that we can - * // keep the size of the critical section as small as possible. This lets - * // other tasks that need to use the odometry data run until we need to - * // update it again. - * odom_mutex.lock(); - * double x_old = odom_x; - * double y_old = odom_y; - * double heading_old = odom_heading; - * odom_mutex.unlock(); - * - * double x_new = 0.0; - * double y_new = 0.0; - * double heading_new = 0.0; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * odom_mutex.lock(); - * odom_x = x_new; - * odom_y = y_new; - * odom_heading = heading_new; - * odom_mutex.unlock(); - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * // Here we copy the current odom values into local variables so that - * // we can use them without worrying about the odometry task changing say, - * // the y value right after we've read the x. This ensures our values are - * // sound. - * odom_mutex.lock(); - * double current_x = odom_x; - * double current_y = odom_y; - * double current_heading = odom_heading; - * odom_mutex.unlock(); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = pros::Mutex(); - * - * pros::Task odom_task(odom_task, "Odometry Task"); - * pros::Task chassis_task(odom_task, "Chassis Control Task"); - * } - * \endcode. - */ - void unlock(); - - /** - * Try to lock a mutex. - * - * Returns immediately if unsucessful. - * - * Conforms to named requirement Lockable - * \see https://en.cppreference.com/w/cpp/named_req/Lockable - * - * \return True when lock was acquired succesfully, or false otherwise. - * - * pros::Mutex mutex; - * - * void my_task_fn(void* param) { - * while (true) { - * if(mutex.try_lock()) { - * printf("Mutex aquired successfully!\n"); - * // Do stuff that requires the protected resource here - * } - * else { - * printf("Mutex not aquired!\n"); - * } - * } - * } - */ - bool try_lock(); - - /** - * Takes and locks a mutex, waiting for a specified duration. - * - * Equivalent to calling pros::Mutex::take with a duration specified in - * milliseconds. - * - * Conforms to named requirement TimedLockable - * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable - * - * \param rel_time Time to wait before the mutex becomes available. - * \return True if the lock was acquired succesfully, otherwise false. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * while (true) { - * if(mutex.try_lock_for(std::chrono::milliseconds(100))) { - * printf("Mutex aquired successfully!\n"); - * // Do stuff that requires the protected resource here - * } - * else { - * printf("Mutex not aquired after 100 milliseconds!\n"); - * } - * } - * } - * \endcode - */ - template - bool try_lock_for(const std::chrono::duration& rel_time) { - return take(std::chrono::duration_cast(rel_time).count()); - } - - /** - * Takes and locks a mutex, waiting until a specified time. - * - * Conforms to named requirement TimedLockable - * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable - * - * \param abs_time Time point until which to wait for the mutex. - * \return True if the lock was acquired succesfully, otherwise false. - * - * \b Example - * \code - * void my_task_fn(void* param) { - * while (true) { - * // Get the current time point - * auto now = std::chrono::system_clock::now(); - * - * // Calculate the time point 100 milliseconds from now - * auto abs_time = now + std::chrono::milliseconds(100); - * - * if(mutex.try_lock_until(abs_time)) { - * printf("Mutex aquired successfully!\n"); - * // Do stuff that requires the protected resource here - * } - * else { - * printf("Mutex not aquired after 100 milliseconds!\n"); - * } - * } - * } - * \endcode - */ - template - bool try_lock_until(const std::chrono::time_point& abs_time) { - return take(std::max(static_cast(0), (abs_time - Clock::now()).count())); - } - ///@} -}; - -template -class MutexVar; - -template -class MutexVarLock { - Mutex& mutex; - Var& var; - - friend class MutexVar; - - constexpr MutexVarLock(Mutex& mutex, Var& var) : mutex(mutex), var(var) {} - - public: - /** - * Accesses the value of the mutex-protected variable. - */ - constexpr Var& operator*() const { - return var; - } - - /** - * Accesses the value of the mutex-protected variable. - */ - constexpr Var* operator->() const { - return &var; - } - - ~MutexVarLock() { - mutex.unlock(); - } -}; - -template -class MutexVar { - Mutex mutex; - Var var; - - public: - /** - * Creates a mutex-protected variable which is initialized with the given - * constructor arguments. - * - * \param args - * The arguments to provide to the Var constructor. - * - * \b Example - * \code - * // We create a pose class to contain all our odometry data in a single - * // variable that can be protected by a MutexVar. Otherwise, we would have - * // three seperate variables which could not be protected in a single - * // MutexVar - * struct Pose { - * double x; - * double y; - * double heading; - * } - * - * pros::MutexVar odom_pose(0.0, 0.0, 0.0); - * - * void odom_task(void* param) { - * while(true) { - * Pose old_pose = *odom_pose.lock(); - * - * Pose new_pose{0.0, 0.0, 0.0}; - * - * // --- Calculate new pose for the robot here --- - * - * // Now that we have the new pose, we can update the global variables - * - * *odom_pose.take() = new_pose; - * - * delay(10); - * } - * } - * - * void chassis_task(void* param) { - * while(true) { - * - * Pose cur_pose = *odom_pose.take(); - * - * // ---- Move the robot using the current locations goes here ---- - * - * delay(10); - * } - * } - * - * void initialize() { - * odom_mutex = pros::Mutex(); - * - * pros::Task odom_task(odom_task, "Odometry Task"); - * pros::Task chassis_task(odom_task, "Chassis Control Task"); - * } - * - * \endcode - */ - template - MutexVar(Args&&... args) : mutex(), var(std::forward(args)...) {} - - /** - * Try to lock the mutex-protected variable. - * - * \param timeout - * Time to wait before the mutex becomes available, in milliseconds. A - * timeout of 0 can be used to poll the mutex. - * - * \return A std::optional which contains a MutexVarLock providing access to - * the protected variable if locking is successful. - * - * \b Example - * \code - * pros::MutexVar odom_pose; - * - * void my_task(void* param) { - * while(true) { - * std::optional> cur_pose_opt = odom_pose.try_lock(100); - * - * if(cur_pose_opt.has_value()) { - * Pose* cur_pose = **cur_pose_opt; - * } - * else { - * printf("Could not lock the mutex var!"); - * } - * - * pros::delay(10); - * } - * } - * \endcode - */ - std::optional> try_lock(std::uint32_t timeout) { - if (mutex.take(timeout)) { - return {{mutex, var}}; - } else { - return {}; - } - } - - /** - * Try to lock the mutex-protected variable. - * - * \param timeout - * Time to wait before the mutex becomes available. A timeout of 0 can - * be used to poll the mutex. - * - * \return A std::optional which contains a MutexVarLock providing access to - * the protected variable if locking is successful. - * - * \b Example - * \code - * pros::MutexVar odom_pose; - * - * void my_task(void* param) { - * while(true) { - * std::chrono::duration timeout(100); - * std::optional> cur_pose_opt = odom_pose.try_lock(timeout); - * - * if(cur_pose_opt.has_value()) { - * Pose* cur_pose = **cur_pose_opt; - * } - * else { - * printf("Could not lock the mutex var!"); - * } - * - * pros::delay(10); - * } - * } - * \endcode - */ - template - std::optional> try_lock(const std::chrono::duration& rel_time) { - try_lock(std::chrono::duration_cast(rel_time).count()); - } - - /** - * Lock the mutex-protected variable, waiting indefinitely. - * - * \return A MutexVarLock providing access to the protected variable. - * - * \b Example - * \code - * pros::MutexVar odom_pose; - * - * void my_task(void* param) { - * while(true) { - * pros::delay(10); - * - * pros::MutexVarLock cur_pose = odom_pose.lock(); - * Pose cur_pose = *cur_pose; - * - * // do stuff with cur_pose - * } - * } - * \endcode - */ - MutexVarLock lock() { - while (!mutex.take(TIMEOUT_MAX)) - ; - return {mutex, var}; - } -}; - -/** - * Gets the number of milliseconds since PROS initialized. - * - * \return The number of milliseconds since PROS initialized - */ -using pros::c::millis; - -/** - * Gets the number of microseconds since PROS initialized. - * - * \return The number of microseconds since PROS initialized - */ -using pros::c::micros; - -/** - * Delays a task for a given number of milliseconds. - * - * This is not the best method to have a task execute code at predefined - * intervals, as the delay time is measured from when the delay is requested. - * To delay cyclically, use task_delay_until(). - * - * \param milliseconds - * The number of milliseconds to wait (1000 milliseconds per second) - */ -using pros::c::delay; -} // namespace rtos -} // namespace pros - -#endif // _PROS_RTOS_HPP_ +/** + * \file pros/rtos.hpp + * \ingroup cpp-rtos + * + * Contains declarations for the PROS RTOS kernel for use by typical VEX + * programmers. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-rtos RTOS Facilities C++ API + * \note Additional example code for this module can be found in its [Tutorial.](@ref multitasking) + */ + +#ifndef _PROS_RTOS_HPP_ +#define _PROS_RTOS_HPP_ + +#include "pros/rtos.h" +#undef delay +#include +#include +#include +#include +#include +#include +#include + +namespace pros { +inline namespace rtos { +/** + * \ingroup cpp-rtos + */ +class Task { + /** + * \addtogroup cpp-rtos + * @{ + */ + public: + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Pointer to the task entry function + * \param parameters + * Pointer to memory that will be used as a parameter for the task + * being created. This memory should not typically come from stack, + * but rather from dynamically (i.e., malloc'd) or statically + * allocated memory. + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, (void*)"PROS"); + * } + * \endcode + */ + Task(task_fn_t function, void* parameters = nullptr, std::uint32_t prio = TASK_PRIORITY_DEFAULT, + std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = ""); + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Pointer to the task entry function + * \param parameters + * Pointer to memory that will be used as a parameter for the task + * being created. This memory should not typically come from stack, + * but rather from dynamically (i.e., malloc'd) or statically + * allocated memory. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, (void*)"PROS", "My Task"); + * } + * \endcode + */ + Task(task_fn_t function, void* parameters, const char* name); + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, (void*)"PROS"); + * } + * \endcode + */ + template + static task_t create(F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, + std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") { + static_assert(std::is_invocable_r_v); + return pros::c::task_create( + [](void* parameters) { + std::unique_ptr> ptr{static_cast*>(parameters)}; + (*ptr)(); + }, + new std::function(std::forward(function)), prio, stack_depth, name); + } + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); + * } + * \endcode + */ + template + static task_t create(F&& function, const char* name) { + return Task::create(std::forward(function), TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, name); + } + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param prio + * The priority at which the task should run. + * TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used. + * \param stack_depth + * The number of words (i.e. 4 * stack_depth) available on the task's + * stack. TASK_STACK_DEPTH_DEFAULT is typically sufficient. + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * + * void initialize() { + * // Create a task function using lambdas + * auto task_fn = [](void* param) { + * printf("Hello %s\n", (char*)param); + * } + * + * pros::Task my_task(task_fn, (void*)"PROS", "My Task"); + * } + * \endcode + */ + template + explicit Task(F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, + std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") + : Task( + [](void* parameters) { + std::unique_ptr> ptr{static_cast*>(parameters)}; + (*ptr)(); + }, + new std::function(std::forward(function)), prio, stack_depth, name) { + static_assert(std::is_invocable_r_v); + } + + /** + * Creates a new task and add it to the list of tasks that are ready to run. + * + * This function uses the following values of errno when an error state is + * reached: + * ENOMEM - The stack cannot be used as the TCB was not created. + * + * \param function + * Callable object to use as entry function + * \param name + * A descriptive name for the task. This is mainly used to facilitate + * debugging. The name may be up to 32 characters long. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task( + * [](void* param) { + * printf("Inside the task!\n"); + * }, + * "My Task" + * ); + * } + * \endcode + */ + template + Task(F&& function, const char* name) + : Task(std::forward(function), TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, name) {} + + /** + * Create a C++ task object from a task handle + * + * \param task + * A task handle from task_create() for which to create a pros::Task + * object. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); + * + * pros::Task my_task_cpp(my_task); + * } + * \endcode + */ + explicit Task(task_t task); + + /** + * Get the currently running Task + * + * @return The currently running Task. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, pros::TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); + * } + * \endcode + */ + static Task current(); + + /** + * Creates a task object from the passed task handle. + * + * \param in + * A task handle from task_create() for which to create a pros::Task + * object. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() + * } + * + * void initialize() { + * pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); + * + * pros::Task my_task_cpp = my_task; + * } + * \endcode + */ + Task& operator=(task_t in); + + /** + * Removes the Task from the RTOS real time kernel's management. This task + * will be removed from all ready, blocked, suspended and event lists. + * + * Memory dynamically allocated by the task is not automatically freed, and + * should be freed before the task is deleted. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * my_task.remove(); + * } + * \endcode + */ + void remove(); + + /** + * Gets the priority of the specified task. + * + * \return The priority of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * printf("Task Priority: %d\n", my_task.get_priority()); + * } + * \endcode + */ + std::uint32_t get_priority(); + + /** + * Sets the priority of the specified task. + * + * If the specified task's state is available to be scheduled (e.g. not + * blocked) and new priority is higher than the currently running task, + * a context switch may occur. + * + * \param prio + * The new priority of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * Task.set_priority(pros::DEFAULT_PRIORITY + 1); + * } + * \endcode + */ + void set_priority(std::uint32_t prio); + + /** + * Gets the state of the specified task. + * + * \return The state of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * printf("Task State: %d\n", my_task.get_state()); + * } + * \endcode + */ + std::uint32_t get_state(); + + /** + * Suspends the specified task, making it ineligible to be scheduled. + * + * \b Example + * \code + * pros::Mutex counter_mutex; + * int counter = 0; + * + * void my_task_fn(void* param) { + * while(true) { + * counter_mutex.take(); // Mutexes are used for protecting shared resources + * counter++; + * counter_mutex.give(); + * pros::delay(10); + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn, "My Task"); + * + * while(true) { + * counter_mutex.take(); + * if(counter > 100) { + * task_suspepend(task); + * } + * counter_mutex.give(); + * pros::delay(10); + * } + * } + * \endcode + */ + void suspend(); + + /** + * Resumes the specified task, making it eligible to be scheduled. + * + * \param task + * The task to resume + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while(true) { + * // Do stuff + * pros::delay(10); + * } + * } + * + * pros::Task task(my_task_fn); + * + * void autonomous() { + * task.resume(); + * + * // Run autonomous , then suspend the task so it doesn't interfere run + * // outside of autonomous or opcontrol + * task.suspend(); + * } + * + * void opcontrol() { + * task.resume(); + * // Opctonrol code here + * task.suspend(); + * } + * + * \endcode + */ + void resume(); + + /** + * Gets the name of the specified task. + * + * \return A pointer to the name of the task + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * printf("Number of Running Tasks: %d\n", my_task.get_name()); + * } + * \endcode + */ + const char* get_name(); + + /** + * Convert this object to a C task_t handle + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void initialize() { + * pros::Task my_task(my_task_fn, "My Task"); + * + * pros::c::task_t my_task_c = (pros::c::task_t)my_task; + * } + * \endcode + */ + explicit operator task_t() { + return task; + } + + /** + * Sends a simple notification to task and increments the notification + * counter. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \return Always returns true. + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * while(pros::Task::current_task().notify_take(true) == 0) { + * // Code while waiting + * } + * puts("I was unblocked!"); + * } + * + * void opcontrol() { + * pros::Task my_task(my_task_fn); + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * my_task.notify(); + * } + * } + * } + * \endcode + */ + std::uint32_t notify(); + + /** + * Utilizes task notifications to wait until specified task is complete and deleted, + * then continues to execute the program. Analogous to std::thread::join in C++. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \return void + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * lcd_print(1, "%s running", pros::Task::current_task().get_name()); + * task_delay(1000); + * lcd_print(2, "End of %s", pros::Task::current_task().get_name()); + * } + * + * void opcontrol() { + * pros::Task my_task(my_task_fn); + * pros::lcd::set_text(0, "Running task."); + * my_task.join(); + * pros::lcd::lcd_set_text(3, "Task completed."); + * } + * \endcode + */ + void join(); + + /** + * Sends a notification to a task, optionally performing some action. Will + * also retrieve the value of the notification in the target task before + * modifying the notification value. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param value + * The value used in performing the action + * \param action + * An action to optionally perform on the receiving task's notification + * value + * \param prev_value + * A pointer to store the previous value of the target task's + * notification, may be NULL + * + * \return Dependent on the notification action. + * For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without + * needing to overwrite, 1 otherwise. + * For all other NOTIFY_ACTION values: always return 0 + * + * \b Example + * \code + * void my_task_fn(void* param) { + * pros::Task task = pros::Task::current(); + * + * while(true) { + * // Wait until we have been notified 20 times before running the code + * if(task.notify_take(false, TIMEOUT_MAX) == 20) { + * // ... Code to do stuff here ... + * + * // Reset the notification counter + * task.notify_clear(); + * } + * delay(10); + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn); + * + * int count = 0; + * + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task.notify_ext(1, NOTIFY_ACTION_INCREMENT, &count); + * } + * + * delay(20); + * } + * } + * \endcode + */ + std::uint32_t notify_ext(std::uint32_t value, notify_action_e_t action, std::uint32_t* prev_value); + + /** + * Waits for a notification to be nonzero. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \param clear_on_exit + * If true (1), then the notification value is cleared. + * If false (0), then the notification value is decremented. + * \param timeout + * Specifies the amount of time to be spent waiting for a notification + * to occur. + * + * \return The value of the task's notification value before it is decremented + * or cleared + * + * \b Example + * \code + * void my_task_fn(void* ign) { + * pros::Task task = pros::task::current(); + * while(task.notify_take(true, TIMEOUT_MAX)) { + * puts("I was unblocked!"); + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task.notify(my_task); + * } + * } + * } + * \endcode + */ + static std::uint32_t notify_take(bool clear_on_exit, std::uint32_t timeout); + + /** + * Clears the notification for a task. + * + * See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + * details. + * + * \return False if there was not a notification waiting, true if there was + * \b Example + * \code + * void my_task_fn(void* param) { + * pros::Task task = pros::Task::current(); + * while(true) { + * printf("Waiting for notification...\n"); + * printf("Got a notification: %d\n", task.notify_take(false, TIMEOUT_MAX)); + * + * tasK_notify(task); + * delay(10): + * } + * } + * + * void opcontrol() { + * pros::Task task(my_task_fn); + * while(true) { + * if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { + * task.notify(); + * } + * delay(10); + * } + * } + * \endcode + */ + bool notify_clear(); + + /** + * Delays the current task for a specified number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * pros::Task::delay(2); + * } + * \endcode + */ + static void delay(const std::uint32_t milliseconds); + + /** + * Delays the current Task until a specified time. This function can be used by + * periodic tasks to ensure a constant execution frequency. + * + * The task will be woken up at the time *prev_time + delta, and *prev_time + * will be updated to reflect the time at which the task will unblock. + * + * \param prev_time + * A pointer to the location storing the setpoint time. This should + * typically be initialized to the return value from pros::millis(). + * \param delta + * The number of milliseconds to wait (1000 milliseconds per second) + * + * \b Example + * \code + * void opcontrol() { + * while (true) { + * // Do opcontrol things + * pros::Task::delay(2); + * } + * } + * \endcode + */ + static void delay_until(std::uint32_t* const prev_time, const std::uint32_t delta); + + /** + * Gets the number of tasks the kernel is currently managing, including all + * ready, blocked, or suspended tasks. A task that has been deleted, but not + * yet reaped by the idle task will also be included in the count. + * Tasks recently created may take one context switch to be counted. + * + * \return The number of tasks that are currently being managed by the kernel. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * printf("Hello %s\n", (char*)param); + * // ... + * } + * + * void opcontrol() { + * pros::Task my_task(my_task_fn); + * printf("There are %d tasks running\n", pros::Task::get_count()); + * } + * \endcode + */ + static std::uint32_t get_count(); + + private: + task_t task{}; +}; + +// STL Clock compliant clock +struct Clock { + using rep = std::uint32_t; + using period = std::milli; + using duration = std::chrono::duration; + using time_point = std::chrono::time_point; + const bool is_steady = true; + + /** + * Gets the current time. + * + * Effectively a wrapper around pros::millis() + * + * \return The current time + * + * \b Example + * \code + * void opcontrol() { + * pros::Clock::time_point start = pros::Clock::now(); + * pros::Clock::time_point end = pros::Clock::now(); + * pros::Clock::duration duration = end - start; + * printf("Duration: %d\n", duration.count()); + * + * if(duration.count() == 500) { + * // If you see this comment in the DOCS, ping @pros in VTOW. + * // If you are the first person to do so, you will receive a free PROS + * // holo! + * printf("Duration is 500 milliseconds\n"); + * } + * } + * \endcode + */ + static time_point now(); +}; + +class Mutex { + std::shared_ptr> mutex; + + public: + Mutex(); + + // disable copy and move construction and assignment per Mutex requirements + // (see https://en.cppreference.com/w/cpp/named_req/Mutex) + Mutex(const Mutex&) = delete; + Mutex(Mutex&&) = delete; + + Mutex& operator=(const Mutex&) = delete; + Mutex& operator=(Mutex&&) = delete; + + /** + * Takes and locks a mutex indefinetly. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool take(); + + /** + * Takes and locks a mutex, waiting for up to a certain number of milliseconds + * before timing out. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. TIMEOUT_MAX can be used to block + * indefinitely. + * + * \return True if the mutex was successfully taken, false otherwise. If false + * is returned, then errno is set with a hint about why the the mutex + * couldn't be taken. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool take(std::uint32_t timeout); + + /** + * Unlocks a mutex. + * + * See + * https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + * for details. + * + * \return True if the mutex was successfully returned, false otherwise. If + * false is returned, then errno is set with a hint about why the mutex + * couldn't be returned. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.take(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.give(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.take(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.give(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.take(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.give(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + bool give(); + + /** + * Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds. + * + * Effectively equivalent to calling pros::Mutex::take with TIMEOUT_MAX as + * the parameter. + * + * Conforms to named requirment BasicLockable + * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable + * + * \note Consider using a std::unique_lock, std::lock_guard, or + * std::scoped_lock instead of interacting with the Mutex directly. + * + * \exception std::system_error Mutex could not be locked within TIMEOUT_MAX + * milliseconds. see errno for details. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.lock(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.unlock(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.lock(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.unlock(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.lock(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.unlock(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + void lock(); + + /** + * Unlocks a mutex. + * + * Equivalent to calling pros::Mutex::give. + * + * Conforms to named requirement BasicLockable + * \see https://en.cppreference.com/w/cpp/named_req/BasicLockable + * + * \note Consider using a std::unique_lock, std::lock_guard, or + * std::scoped_lock instead of interacting with the Mutex direcly. + * + * \b Example + * \code + * // Global variables for the robot's odometry, which the rest of the robot's + * // subsystems will utilize + * double odom_x = 0.0; + * double odom_y = 0.0; + * double odom_heading = 0.0; + * + * // This mutex protects the odometry data. Whenever we read or write to the + * // odometry data, we should make copies into the local variables, and read + * // all 3 values at once to avoid errors. + * pros::Mutex odom_mutex; + * + * void odom_task(void* param) { + * while(true) { + * // First we fetch the odom coordinates from the previous iteration of the + * // odometry task. These are put into local variables so that we can + * // keep the size of the critical section as small as possible. This lets + * // other tasks that need to use the odometry data run until we need to + * // update it again. + * odom_mutex.lock(); + * double x_old = odom_x; + * double y_old = odom_y; + * double heading_old = odom_heading; + * odom_mutex.unlock(); + * + * double x_new = 0.0; + * double y_new = 0.0; + * double heading_new = 0.0; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * odom_mutex.lock(); + * odom_x = x_new; + * odom_y = y_new; + * odom_heading = heading_new; + * odom_mutex.unlock(); + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * // Here we copy the current odom values into local variables so that + * // we can use them without worrying about the odometry task changing say, + * // the y value right after we've read the x. This ensures our values are + * // sound. + * odom_mutex.lock(); + * double current_x = odom_x; + * double current_y = odom_y; + * double current_heading = odom_heading; + * odom_mutex.unlock(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * \endcode. + */ + void unlock(); + + /** + * Try to lock a mutex. + * + * Returns immediately if unsucessful. + * + * Conforms to named requirement Lockable + * \see https://en.cppreference.com/w/cpp/named_req/Lockable + * + * \return True when lock was acquired succesfully, or false otherwise. + * + * pros::Mutex mutex; + * + * void my_task_fn(void* param) { + * while (true) { + * if(mutex.try_lock()) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired!\n"); + * } + * } + * } + */ + bool try_lock(); + + /** + * Takes and locks a mutex, waiting for a specified duration. + * + * Equivalent to calling pros::Mutex::take with a duration specified in + * milliseconds. + * + * Conforms to named requirement TimedLockable + * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable + * + * \param rel_time Time to wait before the mutex becomes available. + * \return True if the lock was acquired succesfully, otherwise false. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while (true) { + * if(mutex.try_lock_for(std::chrono::milliseconds(100))) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired after 100 milliseconds!\n"); + * } + * } + * } + * \endcode + */ + template + bool try_lock_for(const std::chrono::duration& rel_time) { + return take(std::chrono::duration_cast(rel_time).count()); + } + + /** + * Takes and locks a mutex, waiting until a specified time. + * + * Conforms to named requirement TimedLockable + * \see https://en.cppreference.com/w/cpp/named_req/TimedLockable + * + * \param abs_time Time point until which to wait for the mutex. + * \return True if the lock was acquired succesfully, otherwise false. + * + * \b Example + * \code + * void my_task_fn(void* param) { + * while (true) { + * // Get the current time point + * auto now = std::chrono::system_clock::now(); + * + * // Calculate the time point 100 milliseconds from now + * auto abs_time = now + std::chrono::milliseconds(100); + * + * if(mutex.try_lock_until(abs_time)) { + * printf("Mutex aquired successfully!\n"); + * // Do stuff that requires the protected resource here + * } + * else { + * printf("Mutex not aquired after 100 milliseconds!\n"); + * } + * } + * } + * \endcode + */ + template + bool try_lock_until(const std::chrono::time_point& abs_time) { + return take(std::max(static_cast(0), (abs_time - Clock::now()).count())); + } + ///@} +}; + +template +class MutexVar; + +template +class MutexVarLock { + Mutex& mutex; + Var& var; + + friend class MutexVar; + + constexpr MutexVarLock(Mutex& mutex, Var& var) : mutex(mutex), var(var) {} + + public: + /** + * Accesses the value of the mutex-protected variable. + */ + constexpr Var& operator*() const { + return var; + } + + /** + * Accesses the value of the mutex-protected variable. + */ + constexpr Var* operator->() const { + return &var; + } + + ~MutexVarLock() { + mutex.unlock(); + } +}; + +template +class MutexVar { + Mutex mutex; + Var var; + + public: + /** + * Creates a mutex-protected variable which is initialized with the given + * constructor arguments. + * + * \param args + * The arguments to provide to the Var constructor. + * + * \b Example + * \code + * // We create a pose class to contain all our odometry data in a single + * // variable that can be protected by a MutexVar. Otherwise, we would have + * // three seperate variables which could not be protected in a single + * // MutexVar + * struct Pose { + * double x; + * double y; + * double heading; + * } + * + * pros::MutexVar odom_pose(0.0, 0.0, 0.0); + * + * void odom_task(void* param) { + * while(true) { + * Pose old_pose = *odom_pose.lock(); + * + * Pose new_pose{0.0, 0.0, 0.0}; + * + * // --- Calculate new pose for the robot here --- + * + * // Now that we have the new pose, we can update the global variables + * + * *odom_pose.take() = new_pose; + * + * delay(10); + * } + * } + * + * void chassis_task(void* param) { + * while(true) { + * + * Pose cur_pose = *odom_pose.take(); + * + * // ---- Move the robot using the current locations goes here ---- + * + * delay(10); + * } + * } + * + * void initialize() { + * odom_mutex = pros::Mutex(); + * + * pros::Task odom_task(odom_task, "Odometry Task"); + * pros::Task chassis_task(odom_task, "Chassis Control Task"); + * } + * + * \endcode + */ + template + MutexVar(Args&&... args) : mutex(), var(std::forward(args)...) {} + + /** + * Try to lock the mutex-protected variable. + * + * \param timeout + * Time to wait before the mutex becomes available, in milliseconds. A + * timeout of 0 can be used to poll the mutex. + * + * \return A std::optional which contains a MutexVarLock providing access to + * the protected variable if locking is successful. + * + * \b Example + * \code + * pros::MutexVar odom_pose; + * + * void my_task(void* param) { + * while(true) { + * std::optional> cur_pose_opt = odom_pose.try_lock(100); + * + * if(cur_pose_opt.has_value()) { + * Pose* cur_pose = **cur_pose_opt; + * } + * else { + * printf("Could not lock the mutex var!"); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + std::optional> try_lock(std::uint32_t timeout) { + if (mutex.take(timeout)) { + return {{mutex, var}}; + } else { + return {}; + } + } + + /** + * Try to lock the mutex-protected variable. + * + * \param timeout + * Time to wait before the mutex becomes available. A timeout of 0 can + * be used to poll the mutex. + * + * \return A std::optional which contains a MutexVarLock providing access to + * the protected variable if locking is successful. + * + * \b Example + * \code + * pros::MutexVar odom_pose; + * + * void my_task(void* param) { + * while(true) { + * std::chrono::duration timeout(100); + * std::optional> cur_pose_opt = odom_pose.try_lock(timeout); + * + * if(cur_pose_opt.has_value()) { + * Pose* cur_pose = **cur_pose_opt; + * } + * else { + * printf("Could not lock the mutex var!"); + * } + * + * pros::delay(10); + * } + * } + * \endcode + */ + template + std::optional> try_lock(const std::chrono::duration& rel_time) { + try_lock(std::chrono::duration_cast(rel_time).count()); + } + + /** + * Lock the mutex-protected variable, waiting indefinitely. + * + * \return A MutexVarLock providing access to the protected variable. + * + * \b Example + * \code + * pros::MutexVar odom_pose; + * + * void my_task(void* param) { + * while(true) { + * pros::delay(10); + * + * pros::MutexVarLock cur_pose = odom_pose.lock(); + * Pose cur_pose = *cur_pose; + * + * // do stuff with cur_pose + * } + * } + * \endcode + */ + MutexVarLock lock() { + while (!mutex.take(TIMEOUT_MAX)) + ; + return {mutex, var}; + } +}; + +/** + * Gets the number of milliseconds since PROS initialized. + * + * \return The number of milliseconds since PROS initialized + */ +using pros::c::millis; + +/** + * Gets the number of microseconds since PROS initialized. + * + * \return The number of microseconds since PROS initialized + */ +using pros::c::micros; + +/** + * Delays a task for a given number of milliseconds. + * + * This is not the best method to have a task execute code at predefined + * intervals, as the delay time is measured from when the delay is requested. + * To delay cyclically, use task_delay_until(). + * + * \param milliseconds + * The number of milliseconds to wait (1000 milliseconds per second) + */ +using pros::c::delay; +} // namespace rtos +} // namespace pros + +#endif // _PROS_RTOS_HPP_ diff --git a/include/pros/screen.h b/include/pros/screen.h index a1038fa..2e1592b 100644 --- a/include/pros/screen.h +++ b/include/pros/screen.h @@ -1,796 +1,796 @@ -/** - * \file screen.h - * \ingroup c-screen - * - * Brain screen display and touch functions. - * - * Contains user calls to the v5 screen for touching and displaying graphics. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-screen Simplified Brain Screen C API - * - */ - -#ifndef _PROS_SCREEN_H_ -#define _PROS_SCREEN_H_ - -#include -#include -#define _GNU_SOURCE -#include -#undef _GNU_SOURCE -#include - -#include "pros/colors.h" // c color macros - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/** - * \ingroup c-screen - */ - -/** - * \addtogroup c-screen - * @{ - */ - -/** - * \enum text_format_e_t - * Different font sizes that can be used in printing text. - */ -typedef enum { - /// Small text font size - E_TEXT_SMALL = 0, - /// Normal/Medium text font size - E_TEXT_MEDIUM, - /// Large text font size - E_TEXT_LARGE, - /// Medium centered text - E_TEXT_MEDIUM_CENTER, - /// Large centered text - E_TEXT_LARGE_CENTER -} text_format_e_t; - -/** - * \enum last_touch_e_t - * Enum indicating what the current touch status is for the touchscreen. - */ -typedef enum { - /// Last interaction with screen was a quick press - E_TOUCH_RELEASED = 0, - /// Last interaction with screen was a release - E_TOUCH_PRESSED, - /// User is holding screen down - E_TOUCH_HELD, - /// An error occured while taking/returning the mutex - E_TOUCH_ERROR -} last_touch_e_t; - -/** - * \struct screen_touch_status_s_t - * Struct representing screen touch status, screen last x, screen last y, press count, release count. - */ -typedef struct screen_touch_status_s { - /// Represents if the screen is being held, released, or pressed. - last_touch_e_t touch_status; - /// Represents the x value of the location of the touch. - int16_t x; - /// Represents the y value of the location of the touch. - int16_t y; - /// Represents how many times the screen has be pressed. - int32_t press_count; - /// Represents how many times the user released after a touch on the screen. - int32_t release_count; -} screen_touch_status_s_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define TEXT_SMALL pros::E_TEXT_SMALL -#define TEXT_MEDIUM pros::E_TEXT_MEDIUM -#define TEXT_LARGE pros::E_TEXT_LARGE -#define TEXT_MEDIUM_CENTER pros::E_TEXT_MEDIUM_CENTER -#define TEXT_LARGE_CENTER pros::E_LARGE_CENTER -#define TOUCH_RELEASED pros::E_TOUCH_RELEASED -#define TOUCH_PRESSED pros::E_TOUCH_PRESSED -#define TOUCH_HELD pros::E_TOUCH_HELD -#else -#define TEXT_SMALL E_TEXT_SMALL -#define TEXT_MEDIUM E_TEXT_MEDIUM -#define TEXT_LARGE E_TEXT_LARGE -#define TEXT_MEDIUM_CENTER E_TEXT_MEDIUM_CENTER -#define TEXT_LARGE_CENTER E_TEXT_LARGE_CENTER -#define TOUCH_RELEASED E_TOUCH_RELEASED -#define TOUCH_PRESSED E_TOUCH_PRESSED -#define TOUCH_HELD E_TOUCH_HELD -#endif -#endif - -typedef void (*touch_event_cb_fn_t)(); - -#ifdef __cplusplus -namespace c { -#endif - -/// \name Screen Graphical Display Functions -/// These functions allow programmers to display shapes on the v5 screen -///@{ - -/** - * Set the pen color for subsequent graphics operations - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param color The pen color to set (it is recommended to use values - * from the enum defined in colors.h) - * - * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if - * there was an error either taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * screen_set_pen(COLOR_RED); - * } - * - * void opcontrol() { - * int iter = 0; - * while(1){ - * // This should print in red. - * screen_print(TEXT_MEDIUM, 1, "%d", iter++); - * } - * } - * \endcode - */ -uint32_t screen_set_pen(uint32_t color); - -/** - * Set the eraser color for erasing and the current background. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param color The background color to set (it is recommended to use values - * from the enum defined in colors.h) - * - * \return Returns 1 if the mutex was successfully returned, or - * PROS_ERR if there was an error either taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * screen_set_eraser(COLOR_RED); - * } - * - * void opcontrol() { - * while(1){ - * // This should turn the screen red. - * screen_erase(); - * } - * } - * \endcode - */ -uint32_t screen_set_eraser(uint32_t color); - -/** - * Get the current pen color. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \return The current pen color in the form of a value from the enum defined - * in colors.h, or PROS_ERR if there was an error taking or returning - * the screen mutex. - * - * \b Example - * \code - * void initialize() { - * screen_set_pen(COLOR_RED); - * } - * - * void opcontrol() { - * while(1){ - * // Should print number equivalent to COLOR_RED defined in colors.h. - * screen_print(TEXT_MEDIUM, 1, "%d", screen_get_pen()); - * } - * } - * \endcode - */ -uint32_t screen_get_pen(void); - -/** - * Get the current eraser color. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \return The current eraser color in the form of a value from the enum - * defined in colors.h, or PROS_ERR if there was an error taking or - * returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * screen_set_eraser(COLOR_RED); - * } - * - * void opcontrol() { - * while(1){ - * // Should print number equivalent to COLOR_RED defined in colors.h. - * screen_print(TEXT_MEDIUM, 1, "%d", screen_get_eraser()); - * } - * } - * \endcode - */ -uint32_t screen_get_eraser(void); - -/** - * Clear display with eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * screen_set_eraser(COLOR_RED); - * } - * - * void opcontrol() { - * while(1){ - * // This should turn the screen red. - * screen_erase(); - * } - * } - * \endcode - */ -uint32_t screen_erase(void); - -/** - * Scroll lines on the display upwards. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param start_line The line from which scrolling will start - * \param lines The number of lines to scroll up - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * screen_print(TEXT_MEDIUM, 4, "Line Here"); - * // Scroll 3 lines - * screen_scroll(4, 3); - * } - * \endcode - */ -uint32_t screen_scroll(int16_t start_line, int16_t lines); - -/** - * Scroll lines within a region on the display - * - * This function behaves in the same way as `screen_scroll`, except that you - * specify a rectangular region within which to scroll lines instead of a start - * line. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first corner of the - * rectangular region - * \param x1, y1 The (x,y) coordinates of the second corner of the - * rectangular region - * \param lines The number of lines to scroll upwards - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * screen_print(TEXT_MEDIUM, 1, "Line Here"); - * // Scrolls area of screen upwards slightly. including line of text - * screen_scroll_area(0,0, 400, 200, 3); - * } - * \endcode - */ -uint32_t screen_scroll_area(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t lines); - -/** - * Copy a screen region (designated by a rectangle) from an off-screen buffer - * to the screen - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first corner of the - * rectangular region of the screen - * \param x1, y1 The (x,y) coordinates of the second corner of the - * rectangular region of the screen - * \param buf Off-screen buffer containing screen data - * \param stride Off-screen buffer width in pixels, such that image size - * is stride-padding - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * uint32_t* buf = malloc(sizeof(uint32_t) * 400 * 200); - * screen_print(TEXT_MEDIUM, 1, "Line Here"); - * // Copies area of the screen including text - * screen_copy_area(0, 0, 400, 200, (uint32_t*)buf, 400 + 1); - * // Equation for stride is x2 - x1 + 1 - * } - * \endcode - */ -uint32_t screen_copy_area(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t* buf, int32_t stride); - -/** - * Draw a single pixel on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the pixel - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * int i = 0; - * void opcontrol() { - * while(i < 200){ - * screen_draw_pixel(100,i++); - * // Draws a line at x = 100 gradually down the screen, pixel by pixel - * delay(200); - * } - * } - * \endcode - */ -uint32_t screen_draw_pixel(int16_t x, int16_t y); - -/** - * Erase a pixel from the screen (Sets the location) - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the erased - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Color the Screen in Red - * screen_set_pen(COLOR_RED); - * screen_fill_rect(0,0,400,200); - * int i = 0; - * while(i < 200){ - * screen_erase_pixel(100,i++); - * // Erases a line at x = 100 gradually down the screen, pixel by pixel - * delay(200); - * } - * } - * \endcode - */ -uint32_t screen_erase_pixel(int16_t x, int16_t y); - -/** - * Draw a line on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x, y) coordinates of the first point of the line - * \param x1, y1 The (x, y) coordinates of the second point of the line - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * screen_set_pen(COLOR_RED); - * // Draw line down the screen at x = 100 - * screen_draw_line(100,0,100,200); - * } - * \endcode - */ -uint32_t screen_draw_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1); - -/** - * Erase a line on the screen using the current eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x, y) coordinates of the first point of the line - * \param x1, y1 The (x, y) coordinates of the second point of the line - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Color the Screen in Red - * screen_set_pen(COLOR_RED); - * screen_fill_rect(0,0,400,200); - * // Erase line down the screen at x = 100 - * screen_erase_line(100,0,100,200); - * } - * \endcode - */ -uint32_t screen_erase_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1); - -/** - * Draw a rectangle on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first point of the rectangle - * \param x1, y1 The (x,y) coordinates of the second point of the rectangle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * screen_set_pen(COLOR_RED); - * screen_draw_rect(1,1,480,200); - * } - * \endcode - */ -uint32_t screen_draw_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); - -/** - * Erase a rectangle on the screen using the current eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first point of the rectangle - * \param x1, y1 The (x,y) coordinates of the second point of the rectangle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Draw Box Around Half the Screen in Red - * screen_set_eraser(COLOR_RED); - * screen_erase_rect(5,5,240,200); - * } - * \endcode - */ -uint32_t screen_erase_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); - -/** - * Fill a rectangular region of the screen using the current pen - * color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first point of the rectangle - * \param x1, y1 The (x,y) coordinates of the second point of the rectangle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Fill Around Half the Screen in Red - * screen_set_pen(COLOR_RED); - * screen_fill_rect(5,5,240,200); - * } - * \endcode - */ -uint32_t screen_fill_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); - -/** - * Draw a circle on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the center of the circle - * \param r The radius of the circle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Draw a circle with radius of 100 in red - * screen_set_pen(COLOR_RED); - * screen_draw_circle(240, 200, 100); - * } - * \endcode - */ -uint32_t screen_draw_circle(int16_t x, int16_t y, int16_t radius); - -/** - * Erase a circle on the screen using the current eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the center of the circle - * \param r The radius of the circle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * screen_set_pen(COLOR_RED); - * screen_fill_rect(5,5,240,200); - * // Erase a circle with radius of 100 in COLOR_BLUE - * screen_set_pen(COLOR_BLUE); - * screen_erase_circle(240, 200, 100); - * } - * \endcode - */ -uint32_t screen_erase_circle(int16_t x, int16_t y, int16_t radius); - -/** - * Fill a circular region of the screen using the current pen - * color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the center of the circle - * \param r The radius of the circle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * screen_set_pen(COLOR_RED); - * screen_fill_rect(5,5,240,200); - * // Fill a circlular area with radius of 100 in COLOR_BLUE - * screen_set_pen(COLOR_BLUE); - * screen_fill_circle(240, 200, 100); - * } - * \endcode - */ -uint32_t screen_fill_circle(int16_t x, int16_t y, int16_t radius); - -///@} - -/// \name Screen Text Display Functions -/// These functions allow programmers to display text on the v5 screen -///@{ - -/** - * Print a formatted string to the screen on the specified line - * - * Will default to a medium sized font by default if invalid txt_fmt is given. - * - * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES - * NOT SUPPORT SMALL) \param line The line number on which to print \param text Format string \param ... Optional list - * of arguments for the format string - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * int i = 0; - * - * screen_set_pen(COLOR_BLUE); - * while(1){ - * // Will print seconds started since program started on line 3 - * screen_print(TEXT_MEDIUM, 3, "Seconds Passed: %3d", i++); - * delay(1000); - * } - * } - * \endcode - */ -uint32_t screen_print(text_format_e_t txt_fmt, const int16_t line, const char* text, ...); - -/** - * Print a formatted string to the screen at the specified point - * - * Will default to a medium sized font by default if invalid txt_fmt is given. - * - * Text formats medium_center and large_center will default to medium and large respectively. - * - * \param txt_fmt Text format enum that determines if the text is small, medium, or large. - * \param x The y coordinate of the top left corner of the string - * \param y The x coordinate of the top left corner of the string - * \param text Format string - * \param ... Optional list of arguments for the format string - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * int i = 0; - * - * screen_set_pen(COLOR_BLUE); - * while(1){ - * // Will print seconds started since program started. - * screen_print_at(TEXT_SMALL, 3, "Seconds Passed: %3d", i++); - * delay(1000); - * } - * } - * \endcode - */ -uint32_t screen_print_at(text_format_e_t txt_fmt, const int16_t x, const int16_t y, const char* text, ...); - -/** - * Print a formatted string to the screen on the specified line - * - * Same as `display_printf` except that this uses a `va_list` instead of the - * ellipsis operator so this can be used by other functions. - * - * Will default to a medium sized font by default if invalid txt_fmt is given. - * Exposed mostly for writing libraries and custom functions. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES - * NOT SUPPORT SMALL) \param line The line number on which to print \param text Format string \param args List of - * arguments for the format string - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * while taking or returning the screen mutex. - * - * - */ -uint32_t screen_vprintf(text_format_e_t txt_fmt, const int16_t line, const char* text, va_list args); - -/** - * Print a formatted string to the screen at the specified coordinates - * - * Same as `display_printf_at` except that this uses a `va_list` instead of the - * ellipsis operator so this can be used by other functions. - * - * Will default to a medium sized font by default if invalid txt_fmt is given. - * - * Text formats medium_center and large_center will default to medium and large respectively. - * Exposed mostly for writing libraries and custom functions. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param txt_fmt Text format enum that determines if the text is small, medium, or large. - * \param x, y The (x,y) coordinates of the top left corner of the string - * \param text Format string - * \param args List of arguments for the format string - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * while taking or returning the screen mutex. - * - */ -uint32_t screen_vprintf_at(text_format_e_t txt_fmt, const int16_t x, const int16_t y, const char* text, va_list args); - -///@} - -/// \name Screen Touch Functions -/// These functions allow programmers to access information about screen touches -///@{ - -/** - * Gets the touch status of the last touch of the screen. - * - * \return The last_touch_e_t enum specifier that indicates the last touch status of the screen (E_TOUCH_EVENT_RELEASE, - * E_TOUCH_EVENT_PRESS, or E_TOUCH_EVENT_PRESS_AND_HOLD). This will be released by default if no action was taken. If an - * error occured, the screen_touch_status_s_t will have its last_touch_e_t enum specifier set to E_TOUCH_ERR, and other - * values set to -1. - * - * \b Example - * \code - * void opcontrol() { - * int i = 0; - * screen_touch_status_s_t status; - * while(1){ - * status = screen_touch_status(); - * - * // Will print various information about the last touch - * screen_print(TEXT_MEDIUM, 1, "Touch Status (Type): %d", status.touch_status); - * screen_print(TEXT_MEDIUM, 2, "Last X: %d", status.x); - * screen_print(TEXT_MEDIUM, 3, "Last Y: %d", status.y); - * screen_print(TEXT_MEDIUM, 4, "Press Count: %d", status.press_count); - * screen_print(TEXT_MEDIUM, 5, "Release Count: %d", status.release_count); - * delay(20); - * } - * } - * \endcode - */ -screen_touch_status_s_t screen_touch_status(void); - -/** - * Assigns a callback function to be called when a certain touch event happens. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param cb Function pointer to callback when event type happens - * \param event_type Touch event that will trigger the callback. - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * while taking or returning the screen mutex. - * - * \b Example - * \code - * touch_event_cb_fn_t changePixel(){ - * screen_touch_status_s_t status = screen_touch_status(); - * screen_draw_pixel(status.x,status.y); - * return NULL; - * } - * - * void opcontrol() { - * screen_touch_callback(changePixel(), TOUCH_PRESSED); - * while(1) delay(20); - * } - * \endcode - */ -uint32_t screen_touch_callback(touch_event_cb_fn_t cb, last_touch_e_t event_type); - -///@} - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - -#endif +/** + * \file screen.h + * \ingroup c-screen + * + * Brain screen display and touch functions. + * + * Contains user calls to the v5 screen for touching and displaying graphics. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-screen Simplified Brain Screen C API + * + */ + +#ifndef _PROS_SCREEN_H_ +#define _PROS_SCREEN_H_ + +#include +#include +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#include + +#include "pros/colors.h" // c color macros + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \ingroup c-screen + */ + +/** + * \addtogroup c-screen + * @{ + */ + +/** + * \enum text_format_e_t + * Different font sizes that can be used in printing text. + */ +typedef enum { + /// Small text font size + E_TEXT_SMALL = 0, + /// Normal/Medium text font size + E_TEXT_MEDIUM, + /// Large text font size + E_TEXT_LARGE, + /// Medium centered text + E_TEXT_MEDIUM_CENTER, + /// Large centered text + E_TEXT_LARGE_CENTER +} text_format_e_t; + +/** + * \enum last_touch_e_t + * Enum indicating what the current touch status is for the touchscreen. + */ +typedef enum { + /// Last interaction with screen was a quick press + E_TOUCH_RELEASED = 0, + /// Last interaction with screen was a release + E_TOUCH_PRESSED, + /// User is holding screen down + E_TOUCH_HELD, + /// An error occured while taking/returning the mutex + E_TOUCH_ERROR +} last_touch_e_t; + +/** + * \struct screen_touch_status_s_t + * Struct representing screen touch status, screen last x, screen last y, press count, release count. + */ +typedef struct screen_touch_status_s { + /// Represents if the screen is being held, released, or pressed. + last_touch_e_t touch_status; + /// Represents the x value of the location of the touch. + int16_t x; + /// Represents the y value of the location of the touch. + int16_t y; + /// Represents how many times the screen has be pressed. + int32_t press_count; + /// Represents how many times the user released after a touch on the screen. + int32_t release_count; +} screen_touch_status_s_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define TEXT_SMALL pros::E_TEXT_SMALL +#define TEXT_MEDIUM pros::E_TEXT_MEDIUM +#define TEXT_LARGE pros::E_TEXT_LARGE +#define TEXT_MEDIUM_CENTER pros::E_TEXT_MEDIUM_CENTER +#define TEXT_LARGE_CENTER pros::E_LARGE_CENTER +#define TOUCH_RELEASED pros::E_TOUCH_RELEASED +#define TOUCH_PRESSED pros::E_TOUCH_PRESSED +#define TOUCH_HELD pros::E_TOUCH_HELD +#else +#define TEXT_SMALL E_TEXT_SMALL +#define TEXT_MEDIUM E_TEXT_MEDIUM +#define TEXT_LARGE E_TEXT_LARGE +#define TEXT_MEDIUM_CENTER E_TEXT_MEDIUM_CENTER +#define TEXT_LARGE_CENTER E_TEXT_LARGE_CENTER +#define TOUCH_RELEASED E_TOUCH_RELEASED +#define TOUCH_PRESSED E_TOUCH_PRESSED +#define TOUCH_HELD E_TOUCH_HELD +#endif +#endif + +typedef void (*touch_event_cb_fn_t)(); + +#ifdef __cplusplus +namespace c { +#endif + +/// \name Screen Graphical Display Functions +/// These functions allow programmers to display shapes on the v5 screen +///@{ + +/** + * Set the pen color for subsequent graphics operations + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The pen color to set (it is recommended to use values + * from the enum defined in colors.h) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if + * there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_pen(COLOR_RED); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * screen_print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * \endcode + */ +uint32_t screen_set_pen(uint32_t color); + +/** + * Set the eraser color for erasing and the current background. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The background color to set (it is recommended to use values + * from the enum defined in colors.h) + * + * \return Returns 1 if the mutex was successfully returned, or + * PROS_ERR if there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_eraser(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * screen_erase(); + * } + * } + * \endcode + */ +uint32_t screen_set_eraser(uint32_t color); + +/** + * Get the current pen color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current pen color in the form of a value from the enum defined + * in colors.h, or PROS_ERR if there was an error taking or returning + * the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_pen(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to COLOR_RED defined in colors.h. + * screen_print(TEXT_MEDIUM, 1, "%d", screen_get_pen()); + * } + * } + * \endcode + */ +uint32_t screen_get_pen(void); + +/** + * Get the current eraser color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current eraser color in the form of a value from the enum + * defined in colors.h, or PROS_ERR if there was an error taking or + * returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_eraser(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to COLOR_RED defined in colors.h. + * screen_print(TEXT_MEDIUM, 1, "%d", screen_get_eraser()); + * } + * } + * \endcode + */ +uint32_t screen_get_eraser(void); + +/** + * Clear display with eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * screen_set_eraser(COLOR_RED); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * screen_erase(); + * } + * } + * \endcode + */ +uint32_t screen_erase(void); + +/** + * Scroll lines on the display upwards. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param start_line The line from which scrolling will start + * \param lines The number of lines to scroll up + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_print(TEXT_MEDIUM, 4, "Line Here"); + * // Scroll 3 lines + * screen_scroll(4, 3); + * } + * \endcode + */ +uint32_t screen_scroll(int16_t start_line, int16_t lines); + +/** + * Scroll lines within a region on the display + * + * This function behaves in the same way as `screen_scroll`, except that you + * specify a rectangular region within which to scroll lines instead of a start + * line. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region + * \param lines The number of lines to scroll upwards + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_print(TEXT_MEDIUM, 1, "Line Here"); + * // Scrolls area of screen upwards slightly. including line of text + * screen_scroll_area(0,0, 400, 200, 3); + * } + * \endcode + */ +uint32_t screen_scroll_area(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t lines); + +/** + * Copy a screen region (designated by a rectangle) from an off-screen buffer + * to the screen + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region of the screen + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region of the screen + * \param buf Off-screen buffer containing screen data + * \param stride Off-screen buffer width in pixels, such that image size + * is stride-padding + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t* buf = malloc(sizeof(uint32_t) * 400 * 200); + * screen_print(TEXT_MEDIUM, 1, "Line Here"); + * // Copies area of the screen including text + * screen_copy_area(0, 0, 400, 200, (uint32_t*)buf, 400 + 1); + * // Equation for stride is x2 - x1 + 1 + * } + * \endcode + */ +uint32_t screen_copy_area(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t* buf, int32_t stride); + +/** + * Draw a single pixel on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the pixel + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * int i = 0; + * void opcontrol() { + * while(i < 200){ + * screen_draw_pixel(100,i++); + * // Draws a line at x = 100 gradually down the screen, pixel by pixel + * delay(200); + * } + * } + * \endcode + */ +uint32_t screen_draw_pixel(int16_t x, int16_t y); + +/** + * Erase a pixel from the screen (Sets the location) + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the erased + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * screen_set_pen(COLOR_RED); + * screen_fill_rect(0,0,400,200); + * int i = 0; + * while(i < 200){ + * screen_erase_pixel(100,i++); + * // Erases a line at x = 100 gradually down the screen, pixel by pixel + * delay(200); + * } + * } + * \endcode + */ +uint32_t screen_erase_pixel(int16_t x, int16_t y); + +/** + * Draw a line on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * // Draw line down the screen at x = 100 + * screen_draw_line(100,0,100,200); + * } + * \endcode + */ +uint32_t screen_draw_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Erase a line on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * screen_set_pen(COLOR_RED); + * screen_fill_rect(0,0,400,200); + * // Erase line down the screen at x = 100 + * screen_erase_line(100,0,100,200); + * } + * \endcode + */ +uint32_t screen_erase_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Draw a rectangle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * screen_draw_rect(1,1,480,200); + * } + * \endcode + */ +uint32_t screen_draw_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Erase a rectangle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw Box Around Half the Screen in Red + * screen_set_eraser(COLOR_RED); + * screen_erase_rect(5,5,240,200); + * } + * \endcode + */ +uint32_t screen_erase_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Fill a rectangular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Fill Around Half the Screen in Red + * screen_set_pen(COLOR_RED); + * screen_fill_rect(5,5,240,200); + * } + * \endcode + */ +uint32_t screen_fill_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1); + +/** + * Draw a circle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw a circle with radius of 100 in red + * screen_set_pen(COLOR_RED); + * screen_draw_circle(240, 200, 100); + * } + * \endcode + */ +uint32_t screen_draw_circle(int16_t x, int16_t y, int16_t radius); + +/** + * Erase a circle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * screen_fill_rect(5,5,240,200); + * // Erase a circle with radius of 100 in COLOR_BLUE + * screen_set_pen(COLOR_BLUE); + * screen_erase_circle(240, 200, 100); + * } + * \endcode + */ +uint32_t screen_erase_circle(int16_t x, int16_t y, int16_t radius); + +/** + * Fill a circular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * screen_set_pen(COLOR_RED); + * screen_fill_rect(5,5,240,200); + * // Fill a circlular area with radius of 100 in COLOR_BLUE + * screen_set_pen(COLOR_BLUE); + * screen_fill_circle(240, 200, 100); + * } + * \endcode + */ +uint32_t screen_fill_circle(int16_t x, int16_t y, int16_t radius); + +///@} + +/// \name Screen Text Display Functions +/// These functions allow programmers to display text on the v5 screen +///@{ + +/** + * Print a formatted string to the screen on the specified line + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES + * NOT SUPPORT SMALL) \param line The line number on which to print \param text Format string \param ... Optional list + * of arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * + * screen_set_pen(COLOR_BLUE); + * while(1){ + * // Will print seconds started since program started on line 3 + * screen_print(TEXT_MEDIUM, 3, "Seconds Passed: %3d", i++); + * delay(1000); + * } + * } + * \endcode + */ +uint32_t screen_print(text_format_e_t txt_fmt, const int16_t line, const char* text, ...); + +/** + * Print a formatted string to the screen at the specified point + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * Text formats medium_center and large_center will default to medium and large respectively. + * + * \param txt_fmt Text format enum that determines if the text is small, medium, or large. + * \param x The y coordinate of the top left corner of the string + * \param y The x coordinate of the top left corner of the string + * \param text Format string + * \param ... Optional list of arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * + * screen_set_pen(COLOR_BLUE); + * while(1){ + * // Will print seconds started since program started. + * screen_print_at(TEXT_SMALL, 3, "Seconds Passed: %3d", i++); + * delay(1000); + * } + * } + * \endcode + */ +uint32_t screen_print_at(text_format_e_t txt_fmt, const int16_t x, const int16_t y, const char* text, ...); + +/** + * Print a formatted string to the screen on the specified line + * + * Same as `display_printf` except that this uses a `va_list` instead of the + * ellipsis operator so this can be used by other functions. + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * Exposed mostly for writing libraries and custom functions. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES + * NOT SUPPORT SMALL) \param line The line number on which to print \param text Format string \param args List of + * arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + * + */ +uint32_t screen_vprintf(text_format_e_t txt_fmt, const int16_t line, const char* text, va_list args); + +/** + * Print a formatted string to the screen at the specified coordinates + * + * Same as `display_printf_at` except that this uses a `va_list` instead of the + * ellipsis operator so this can be used by other functions. + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * Text formats medium_center and large_center will default to medium and large respectively. + * Exposed mostly for writing libraries and custom functions. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param txt_fmt Text format enum that determines if the text is small, medium, or large. + * \param x, y The (x,y) coordinates of the top left corner of the string + * \param text Format string + * \param args List of arguments for the format string + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + */ +uint32_t screen_vprintf_at(text_format_e_t txt_fmt, const int16_t x, const int16_t y, const char* text, va_list args); + +///@} + +/// \name Screen Touch Functions +/// These functions allow programmers to access information about screen touches +///@{ + +/** + * Gets the touch status of the last touch of the screen. + * + * \return The last_touch_e_t enum specifier that indicates the last touch status of the screen (E_TOUCH_EVENT_RELEASE, + * E_TOUCH_EVENT_PRESS, or E_TOUCH_EVENT_PRESS_AND_HOLD). This will be released by default if no action was taken. If an + * error occured, the screen_touch_status_s_t will have its last_touch_e_t enum specifier set to E_TOUCH_ERR, and other + * values set to -1. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * screen_touch_status_s_t status; + * while(1){ + * status = screen_touch_status(); + * + * // Will print various information about the last touch + * screen_print(TEXT_MEDIUM, 1, "Touch Status (Type): %d", status.touch_status); + * screen_print(TEXT_MEDIUM, 2, "Last X: %d", status.x); + * screen_print(TEXT_MEDIUM, 3, "Last Y: %d", status.y); + * screen_print(TEXT_MEDIUM, 4, "Press Count: %d", status.press_count); + * screen_print(TEXT_MEDIUM, 5, "Release Count: %d", status.release_count); + * delay(20); + * } + * } + * \endcode + */ +screen_touch_status_s_t screen_touch_status(void); + +/** + * Assigns a callback function to be called when a certain touch event happens. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param cb Function pointer to callback when event type happens + * \param event_type Touch event that will trigger the callback. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + * \b Example + * \code + * touch_event_cb_fn_t changePixel(){ + * screen_touch_status_s_t status = screen_touch_status(); + * screen_draw_pixel(status.x,status.y); + * return NULL; + * } + * + * void opcontrol() { + * screen_touch_callback(changePixel(), TOUCH_PRESSED); + * while(1) delay(20); + * } + * \endcode + */ +uint32_t screen_touch_callback(touch_event_cb_fn_t cb, last_touch_e_t event_type); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif diff --git a/include/pros/screen.hpp b/include/pros/screen.hpp index 7f6ff80..c3980e1 100644 --- a/include/pros/screen.hpp +++ b/include/pros/screen.hpp @@ -1,717 +1,717 @@ -/** - * \file screen.hpp - * \ingroup cpp-screen - * - * Brain screen display and touch functions. - * - * Contains user calls to the v5 screen for touching and displaying graphics. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup cpp-screen Simplified Brain Screen C++ API - */ - -#ifndef _PROS_SCREEN_HPP_ -#define _PROS_SCREEN_HPP_ - -#include "pros/screen.h" -#include "pros/colors.hpp" -#include -#include - -namespace pros { -namespace screen { - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" - -namespace { -template -T convert_args(T arg) { - return arg; -} -const char* convert_args(const std::string& arg) { - return arg.c_str(); -} -} // namespace - -#pragma GCC diagnostic pop - -/** - * \ingroup cpp-screen - */ - -/** - * \addtogroup cpp-screen - * @{ - */ - - /******************************************************************************/ - /** Screen Graphical Display Functions **/ - /** **/ - /** These functions allow programmers to display shapes on the v5 screen **/ - /******************************************************************************/ - - /** - * Set the pen color for subsequent graphics operations - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param color The pen color to set (it is recommended to use values - * from the enum defined in colors.hpp) - * - * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if - * there was an error either taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * pros::screen::set_pen(red); - * } - * - * void opcontrol() { - * int iter = 0; - * while(1){ - * // This should print in red. - * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); - * } - * } - * - * \endcode - */ - std::uint32_t set_pen(pros::Color color); - - /** - * Set the pen color for subsequent graphics operations - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param color The pen color to set (in hex form) - * - * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if - * there was an error either taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * //set pen color to red - * pros::screen::set_pen(0x00FF0000); - * } - * - * void opcontrol() { - * int iter = 0; - * while(1){ - * // This should print in red. - * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); - * } - * } - * - * \endcode - */ - std::uint32_t set_pen(std::uint32_t color); - - /** - * Set the eraser color for erasing and the current background. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param color The background color to set (it is recommended to use values - * from the enum defined in colors.hpp) - * - * \return Returns 1 if the mutex was successfully returned, or PROS_ERR - * if there was an error either taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * //set eraser color to red - * set_eraser(red); - * } - * - * void opcontrol() { - * int iter = 0; - * while(1){ - * // This should print in red. - * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); - * } - * } - * - * \endcode - */ - std::uint32_t set_eraser(pros::Color color); - - /** - * Set the eraser color for erasing and the current background. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param color The background color to set to set (in hex form) - * - * \return Returns 1 if the mutex was successfully returned, or PROS_ERR - * if there was an error either taking or returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * //set eraser color to red - * pros::screen::set_eraser(0x00FF0000); - * } - * - * void opcontrol() { - * while(1){ - * // This should turn the screen red. - * pros::screen::erase(); - * } - * } - * \endcode - */ - std::uint32_t set_eraser(std::uint32_t color); - - /** - * Get the current pen color. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \return The current pen color in the form of a value from the enum - * defined in colors.h, or PROS_ERR if there was an error taking or - * returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * pros::screen::set_pen(red); - * } - * - * void opcontrol() { - * while(1){ - * // Should print number equivalent to red defined in colors.hpp. - * pros::screen::print(TEXT_MEDIUM, 1, "%d", get_pen()); - * } - * } - * \endcode - */ - std::uint32_t get_pen(); - - /** - * Get the current eraser color. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \return The current eraser color in the form of a value from the enum - * defined in colors.h, or PROS_ERR if there was an error taking or - * returning the screen mutex. - * - * \b Example - * \code - * void initialize() { - * pros::screen::set_eraser(red); - * } - * - * void opcontrol() { - * while(1){ - * // Should print number equivalent to red defined in colors.h. - * pros::screen::print(TEXT_MEDIUM, 1, "%d", get_eraser()); - * } - * } - * \endcode - */ - std::uint32_t get_eraser(); - - /** - * Clear display with eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * * \b Example - * \code - * void initialize() { - * pros::screen::set_eraser(red); - * } - * - * void opcontrol() { - * while(1){ - * // This should turn the screen red. - * pros::screen::erase(); - * } - * } - * \endcode - */ - std::uint32_t erase(); - - /** - * Scroll lines on the display upwards. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param start_line The line from which scrolling will start - * \param lines The number of lines to scroll up - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * pros::screen::print(TEXT_MEDIUM, 4, "Line Here"); - * // Scroll 3 lines - * pros::screen::scroll(4, 3); - * } - * \endcode - */ - std::uint32_t scroll(const std::int16_t start_line, const std::int16_t lines); - - /** - * Scroll lines within a region on the display - * - * This function behaves in the same way as `screen_scroll`, except that you - * specify a rectangular region within which to scroll lines instead of a start - * line. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first corner of the - * rectangular region - * \param x1, y1 The (x,y) coordinates of the second corner of the - * rectangular region - * \param lines The number of lines to scroll upwards - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * pros::screen::print(TEXT_MEDIUM, 1, "Line Here"); - * // Scrolls area of screen upwards slightly. including line of text - * pros::screen::scroll_area(0,0, 400, 200, 3); - * } - * \endcode - */ - std::uint32_t scroll_area(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1, std::int16_t lines); - - /** - * Copy a screen region (designated by a rectangle) from an off-screen buffer - * to the screen - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first corner of the - * rectangular region of the screen - * \param x1, y1 The (x,y) coordinates of the second corner of the - * rectangular region of the screen - * \param buf Off-screen buffer containing screen data - * \param stride Off-screen buffer width in pixels, such that image size - * is stride-padding - * - * \return 1 if there were no errors, or PROS_ERR if an error occured taking - * or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * uint32_t* buf = malloc(sizeof(uint32_t) * 400 * 200); - * pros::screen::print(TEXT_MEDIUM, 1, "Line Here"); - * // Copies area of the screen including text - * pros::screen::copy_area(0, 0, 400, 200, (uint32_t*)buf, 400 + 1); - * // Equation for stride is x2 - x1 + 1 - * } - * \endcode - */ - std::uint32_t copy_area(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1, uint32_t* buf, const std::int32_t stride); - - /** - * Draw a single pixel on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the pixel - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * int i = 0; - * void opcontrol() { - * while(i < 200){ - * pros::screen::draw_pixel(100,i++); - * // Draws a line at x = 100 gradually down the screen, pixel by pixel - * pros::delay(200); - * } - * } - * \endcode - */ - std::uint32_t draw_pixel(const std::int16_t x, const std::int16_t y); - - /** - * Erase a pixel from the screen (Sets the location) - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the erased - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Color the Screen in Red - * pros::screen::set_pen(red); - * pros::screen::fill_rect(0,0,400,200); - * int i = 0; - * while(i < 200){ - * pros::screen::erase_pixel(100,i++); - * // Erases a line at x = 100 gradually down the screen, pixel by pixel - * pros::delay(200); - * } - * } - * \endcode - */ - std::uint32_t erase_pixel(const std::int16_t x, const std::int16_t y); - - /** - * Draw a line on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x, y) coordinates of the first point of the line - * \param x1, y1 The (x, y) coordinates of the second point of the line - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * pros::screen::set_pen(red); - * // Draw line down the screen at x = 100 - * pros::screen::draw_line(100,0,100,200); - * } - * \endcode - */ - std::uint32_t draw_line(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); - - /** - * Erase a line on the screen using the current eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x, y) coordinates of the first point of the line - * \param x1, y1 The (x, y) coordinates of the second point of the line - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Color the Screen in Red - * pros::screen::set_pen(red); - * pros::screen::fill_rect(0,0,400,200); - * // Erase line down the screen at x = 100 - * pros::screen::erase_line(100,0,100,200); - * } - * \endcode - */ - std::uint32_t erase_line(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); - - /** - * Draw a rectangle on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first point of the rectangle - * \param x1, y1 The (x,y) coordinates of the second point of the rectangle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * pros::screen::set_pen(red); - * pros::screen::draw_rect(1,1,480,200); - * } - * \endcode - */ - std::uint32_t draw_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); - - /** - * Erase a rectangle on the screen using the current eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first point of the rectangle - * \param x1, y1 The (x,y) coordinates of the second point of the rectangle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Draw Box Around Half the Screen in Red - * pros::screen::set_eraser(red); - * pros::screen::erase_rect(5,5,240,200); - * } - * \endcode - */ - std::uint32_t erase_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); - - /** - * Fill a rectangular region of the screen using the current pen - * color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x0, y0 The (x,y) coordinates of the first point of the rectangle - * \param x1, y1 The (x,y) coordinates of the second point of the rectangle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Fill Around Half the Screen in Red - * pros::screen::set_pen(red); - * pros::screen::fill_rect(5,5,240,200); - * } - * \endcode - */ - std::uint32_t fill_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); - - /** - * Draw a circle on the screen using the current pen color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the center of the circle - * \param r The radius of the circle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * // Draw a circle with radius of 100 in red - * pros::screen::set_pen(red); - * pros::screen::draw_circle(240, 200, 100); - * } - * \endcode - */ - std::uint32_t draw_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); - - /** - * Erase a circle on the screen using the current eraser color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the center of the circle - * \param r The radius of the circle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * pros::screen::set_pen(red); - * pros::screen::fill_rect(5,5,240,200); - * // Erase a circle with radius of 100 in blue - * pros::screen::set_pen(blue); - * pros::screen::erase_circle(240, 200, 100); - * } - * \endcode - */ - std::uint32_t erase_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); - - /** - * Fill a circular region of the screen using the current pen - * color - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param x, y The (x,y) coordinates of the center of the circle - * \param r The radius of the circle - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * taking or returning the screen mutex. - * - * \b Example - * \code - * void opcontrol() { - * pros::screen::set_pen(red); - * pros::screen::fill_rect(5,5,240,200); - * // Fill a circlular area with radius of 100 in blue - * pros::screen::set_pen(blue); - * pros::screen::fill_circle(240, 200, 100); - * } - * \endcode - */ - std::uint32_t fill_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); - - /******************************************************************************/ - /** Screen Text Display Functions **/ - /** **/ - /** These functions allow programmers to display text on the v5 screen **/ - /******************************************************************************/ - - /** - * Print a formatted string to the screen, overwrite available for printing at location too. - * - * Will default to a medium sized font by default if invalid txt_fmt is given. - * - * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES NOT SUPPORT SMALL) - * \param line The line number on which to print - * \param x The (x,y) coordinates of the top left corner of the string - * \param y The (x,y) coordinates of the top left corner of the string - * \param fmt Format string - * \param ... Optional list of arguments for the format string - * - * \b Example - * \code - * void opcontrol() { - * int i = 0; - * pros::screen::set_pen(blue); - * while(1){ - * // Will print seconds started since program started on line 3 - * pros::screen::print(pros::TEXT_MEDIUM, 3, "Seconds Passed: %3d", i++); - * pros::delay(1000); - * } - * } - */ - template - void print(pros::text_format_e_t txt_fmt, const std::int16_t line, const char* text, Params... args){ - pros::c::screen_print(txt_fmt, line, text, convert_args(args)...); - } - - template - void print(pros::text_format_e_t txt_fmt, const std::int16_t x, const std::int16_t y, const char* text, Params... args){ - pros::c::screen_print_at(txt_fmt, x, y, text, convert_args(args)...); - } - - /******************************************************************************/ - /** Screen Touch Functions **/ - /** **/ - /** These functions allow programmers to access **/ - /** information about screen touches **/ - /******************************************************************************/ - - /** - * Gets the touch status of the last touch of the screen. - * - * \return The last_touch_e_t enum specifier that indicates the last touch status of the screen (E_TOUCH_EVENT_RELEASE, E_TOUCH_EVENT_PRESS, or E_TOUCH_EVENT_PRESS_AND_HOLD). - * This will be released by default if no action was taken. - * If an error occured, the screen_touch_status_s_t will have its - * last_touch_e_t enum specifier set to E_TOUCH_ERR, and other values set to -1. - * - * \b Example - * \code - * void opcontrol() { - * int i = 0; - * pros::screen_touch_status_s_t status; - * while(1){ - * status = pros::touch_status(); - * - * // Will print various information about the last touch - * pros::screen::print(TEXT_MEDIUM, 1, "Touch Status (Type): %d", status.touch_status); - * pros::screen::print(TEXT_MEDIUM, 2, "Last X: %d", status.x); - * pros::screen::print(TEXT_MEDIUM, 3, "Last Y: %d", status.y); - * pros::screen::print(TEXT_MEDIUM, 4, "Press Count: %d", status.press_count); - * pros::screen::print(TEXT_MEDIUM, 5, "Release Count: %d", status.release_count); - * pros::delay(20); - * } - * } - * \endcode - */ - screen_touch_status_s_t touch_status(); - - /** - * Assigns a callback function to be called when a certain touch event happens. - * - * This function uses the following values of errno when an error state is - * reached: - * EACCESS - Another resource is currently trying to access the screen mutex. - * - * \param cb Function pointer to callback when event type happens - * \param event_type Touch event that will trigger the callback. - * - * \return 1 if there were no errors, or PROS_ERR if an error occured - * while taking or returning the screen mutex. - * - * \b Example - * \code - * touch_event_cb_fn_t changePixel(){ - * pros::screen_touch_status_s_t status = pros::screen::touch_status(); - * pros::screen::draw_pixel(status.x,status.y); - * return NULL; - * } - * - * void opcontrol() { - * pros::screen::touch_callback(changePixel(), TOUCH_PRESSED); - * while(1) { - * pros::delay(20); - * } - * } - * \endcode - */ - std::uint32_t touch_callback(touch_event_cb_fn_t cb, last_touch_e_t event_type); - -} // namespace screen - - -} // namespace pros - -extern __attribute__((weak)) void lvgl_init() {} -///@} -#endif //header guard +/** + * \file screen.hpp + * \ingroup cpp-screen + * + * Brain screen display and touch functions. + * + * Contains user calls to the v5 screen for touching and displaying graphics. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-screen Simplified Brain Screen C++ API + */ + +#ifndef _PROS_SCREEN_HPP_ +#define _PROS_SCREEN_HPP_ + +#include "pros/screen.h" +#include "pros/colors.hpp" +#include +#include + +namespace pros { +namespace screen { + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" + +namespace { +template +T convert_args(T arg) { + return arg; +} +const char* convert_args(const std::string& arg) { + return arg.c_str(); +} +} // namespace + +#pragma GCC diagnostic pop + +/** + * \ingroup cpp-screen + */ + +/** + * \addtogroup cpp-screen + * @{ + */ + + /******************************************************************************/ + /** Screen Graphical Display Functions **/ + /** **/ + /** These functions allow programmers to display shapes on the v5 screen **/ + /******************************************************************************/ + + /** + * Set the pen color for subsequent graphics operations + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The pen color to set (it is recommended to use values + * from the enum defined in colors.hpp) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if + * there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * pros::screen::set_pen(red); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * + * \endcode + */ + std::uint32_t set_pen(pros::Color color); + + /** + * Set the pen color for subsequent graphics operations + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The pen color to set (in hex form) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR if + * there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * //set pen color to red + * pros::screen::set_pen(0x00FF0000); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * + * \endcode + */ + std::uint32_t set_pen(std::uint32_t color); + + /** + * Set the eraser color for erasing and the current background. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The background color to set (it is recommended to use values + * from the enum defined in colors.hpp) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR + * if there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * //set eraser color to red + * set_eraser(red); + * } + * + * void opcontrol() { + * int iter = 0; + * while(1){ + * // This should print in red. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", iter++); + * } + * } + * + * \endcode + */ + std::uint32_t set_eraser(pros::Color color); + + /** + * Set the eraser color for erasing and the current background. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param color The background color to set to set (in hex form) + * + * \return Returns 1 if the mutex was successfully returned, or PROS_ERR + * if there was an error either taking or returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * //set eraser color to red + * pros::screen::set_eraser(0x00FF0000); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * pros::screen::erase(); + * } + * } + * \endcode + */ + std::uint32_t set_eraser(std::uint32_t color); + + /** + * Get the current pen color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current pen color in the form of a value from the enum + * defined in colors.h, or PROS_ERR if there was an error taking or + * returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * pros::screen::set_pen(red); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to red defined in colors.hpp. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", get_pen()); + * } + * } + * \endcode + */ + std::uint32_t get_pen(); + + /** + * Get the current eraser color. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return The current eraser color in the form of a value from the enum + * defined in colors.h, or PROS_ERR if there was an error taking or + * returning the screen mutex. + * + * \b Example + * \code + * void initialize() { + * pros::screen::set_eraser(red); + * } + * + * void opcontrol() { + * while(1){ + * // Should print number equivalent to red defined in colors.h. + * pros::screen::print(TEXT_MEDIUM, 1, "%d", get_eraser()); + * } + * } + * \endcode + */ + std::uint32_t get_eraser(); + + /** + * Clear display with eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * * \b Example + * \code + * void initialize() { + * pros::screen::set_eraser(red); + * } + * + * void opcontrol() { + * while(1){ + * // This should turn the screen red. + * pros::screen::erase(); + * } + * } + * \endcode + */ + std::uint32_t erase(); + + /** + * Scroll lines on the display upwards. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param start_line The line from which scrolling will start + * \param lines The number of lines to scroll up + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::print(TEXT_MEDIUM, 4, "Line Here"); + * // Scroll 3 lines + * pros::screen::scroll(4, 3); + * } + * \endcode + */ + std::uint32_t scroll(const std::int16_t start_line, const std::int16_t lines); + + /** + * Scroll lines within a region on the display + * + * This function behaves in the same way as `screen_scroll`, except that you + * specify a rectangular region within which to scroll lines instead of a start + * line. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region + * \param lines The number of lines to scroll upwards + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::print(TEXT_MEDIUM, 1, "Line Here"); + * // Scrolls area of screen upwards slightly. including line of text + * pros::screen::scroll_area(0,0, 400, 200, 3); + * } + * \endcode + */ + std::uint32_t scroll_area(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1, std::int16_t lines); + + /** + * Copy a screen region (designated by a rectangle) from an off-screen buffer + * to the screen + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first corner of the + * rectangular region of the screen + * \param x1, y1 The (x,y) coordinates of the second corner of the + * rectangular region of the screen + * \param buf Off-screen buffer containing screen data + * \param stride Off-screen buffer width in pixels, such that image size + * is stride-padding + * + * \return 1 if there were no errors, or PROS_ERR if an error occured taking + * or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * uint32_t* buf = malloc(sizeof(uint32_t) * 400 * 200); + * pros::screen::print(TEXT_MEDIUM, 1, "Line Here"); + * // Copies area of the screen including text + * pros::screen::copy_area(0, 0, 400, 200, (uint32_t*)buf, 400 + 1); + * // Equation for stride is x2 - x1 + 1 + * } + * \endcode + */ + std::uint32_t copy_area(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1, uint32_t* buf, const std::int32_t stride); + + /** + * Draw a single pixel on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the pixel + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * int i = 0; + * void opcontrol() { + * while(i < 200){ + * pros::screen::draw_pixel(100,i++); + * // Draws a line at x = 100 gradually down the screen, pixel by pixel + * pros::delay(200); + * } + * } + * \endcode + */ + std::uint32_t draw_pixel(const std::int16_t x, const std::int16_t y); + + /** + * Erase a pixel from the screen (Sets the location) + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the erased + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * pros::screen::set_pen(red); + * pros::screen::fill_rect(0,0,400,200); + * int i = 0; + * while(i < 200){ + * pros::screen::erase_pixel(100,i++); + * // Erases a line at x = 100 gradually down the screen, pixel by pixel + * pros::delay(200); + * } + * } + * \endcode + */ + std::uint32_t erase_pixel(const std::int16_t x, const std::int16_t y); + + /** + * Draw a line on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * // Draw line down the screen at x = 100 + * pros::screen::draw_line(100,0,100,200); + * } + * \endcode + */ + std::uint32_t draw_line(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Erase a line on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x, y) coordinates of the first point of the line + * \param x1, y1 The (x, y) coordinates of the second point of the line + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Color the Screen in Red + * pros::screen::set_pen(red); + * pros::screen::fill_rect(0,0,400,200); + * // Erase line down the screen at x = 100 + * pros::screen::erase_line(100,0,100,200); + * } + * \endcode + */ + std::uint32_t erase_line(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Draw a rectangle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * pros::screen::draw_rect(1,1,480,200); + * } + * \endcode + */ + std::uint32_t draw_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Erase a rectangle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw Box Around Half the Screen in Red + * pros::screen::set_eraser(red); + * pros::screen::erase_rect(5,5,240,200); + * } + * \endcode + */ + std::uint32_t erase_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Fill a rectangular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x0, y0 The (x,y) coordinates of the first point of the rectangle + * \param x1, y1 The (x,y) coordinates of the second point of the rectangle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Fill Around Half the Screen in Red + * pros::screen::set_pen(red); + * pros::screen::fill_rect(5,5,240,200); + * } + * \endcode + */ + std::uint32_t fill_rect(const std::int16_t x0, const std::int16_t y0, const std::int16_t x1, const std::int16_t y1); + + /** + * Draw a circle on the screen using the current pen color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * // Draw a circle with radius of 100 in red + * pros::screen::set_pen(red); + * pros::screen::draw_circle(240, 200, 100); + * } + * \endcode + */ + std::uint32_t draw_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); + + /** + * Erase a circle on the screen using the current eraser color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * pros::screen::fill_rect(5,5,240,200); + * // Erase a circle with radius of 100 in blue + * pros::screen::set_pen(blue); + * pros::screen::erase_circle(240, 200, 100); + * } + * \endcode + */ + std::uint32_t erase_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); + + /** + * Fill a circular region of the screen using the current pen + * color + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param x, y The (x,y) coordinates of the center of the circle + * \param r The radius of the circle + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * taking or returning the screen mutex. + * + * \b Example + * \code + * void opcontrol() { + * pros::screen::set_pen(red); + * pros::screen::fill_rect(5,5,240,200); + * // Fill a circlular area with radius of 100 in blue + * pros::screen::set_pen(blue); + * pros::screen::fill_circle(240, 200, 100); + * } + * \endcode + */ + std::uint32_t fill_circle(const std::int16_t x, const std::int16_t y, const std::int16_t radius); + + /******************************************************************************/ + /** Screen Text Display Functions **/ + /** **/ + /** These functions allow programmers to display text on the v5 screen **/ + /******************************************************************************/ + + /** + * Print a formatted string to the screen, overwrite available for printing at location too. + * + * Will default to a medium sized font by default if invalid txt_fmt is given. + * + * \param txt_fmt Text format enum that determines if the text is medium, large, medium_center, or large_center. (DOES NOT SUPPORT SMALL) + * \param line The line number on which to print + * \param x The (x,y) coordinates of the top left corner of the string + * \param y The (x,y) coordinates of the top left corner of the string + * \param fmt Format string + * \param ... Optional list of arguments for the format string + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * pros::screen::set_pen(blue); + * while(1){ + * // Will print seconds started since program started on line 3 + * pros::screen::print(pros::TEXT_MEDIUM, 3, "Seconds Passed: %3d", i++); + * pros::delay(1000); + * } + * } + */ + template + void print(pros::text_format_e_t txt_fmt, const std::int16_t line, const char* text, Params... args){ + pros::c::screen_print(txt_fmt, line, text, convert_args(args)...); + } + + template + void print(pros::text_format_e_t txt_fmt, const std::int16_t x, const std::int16_t y, const char* text, Params... args){ + pros::c::screen_print_at(txt_fmt, x, y, text, convert_args(args)...); + } + + /******************************************************************************/ + /** Screen Touch Functions **/ + /** **/ + /** These functions allow programmers to access **/ + /** information about screen touches **/ + /******************************************************************************/ + + /** + * Gets the touch status of the last touch of the screen. + * + * \return The last_touch_e_t enum specifier that indicates the last touch status of the screen (E_TOUCH_EVENT_RELEASE, E_TOUCH_EVENT_PRESS, or E_TOUCH_EVENT_PRESS_AND_HOLD). + * This will be released by default if no action was taken. + * If an error occured, the screen_touch_status_s_t will have its + * last_touch_e_t enum specifier set to E_TOUCH_ERR, and other values set to -1. + * + * \b Example + * \code + * void opcontrol() { + * int i = 0; + * pros::screen_touch_status_s_t status; + * while(1){ + * status = pros::touch_status(); + * + * // Will print various information about the last touch + * pros::screen::print(TEXT_MEDIUM, 1, "Touch Status (Type): %d", status.touch_status); + * pros::screen::print(TEXT_MEDIUM, 2, "Last X: %d", status.x); + * pros::screen::print(TEXT_MEDIUM, 3, "Last Y: %d", status.y); + * pros::screen::print(TEXT_MEDIUM, 4, "Press Count: %d", status.press_count); + * pros::screen::print(TEXT_MEDIUM, 5, "Release Count: %d", status.release_count); + * pros::delay(20); + * } + * } + * \endcode + */ + screen_touch_status_s_t touch_status(); + + /** + * Assigns a callback function to be called when a certain touch event happens. + * + * This function uses the following values of errno when an error state is + * reached: + * EACCESS - Another resource is currently trying to access the screen mutex. + * + * \param cb Function pointer to callback when event type happens + * \param event_type Touch event that will trigger the callback. + * + * \return 1 if there were no errors, or PROS_ERR if an error occured + * while taking or returning the screen mutex. + * + * \b Example + * \code + * touch_event_cb_fn_t changePixel(){ + * pros::screen_touch_status_s_t status = pros::screen::touch_status(); + * pros::screen::draw_pixel(status.x,status.y); + * return NULL; + * } + * + * void opcontrol() { + * pros::screen::touch_callback(changePixel(), TOUCH_PRESSED); + * while(1) { + * pros::delay(20); + * } + * } + * \endcode + */ + std::uint32_t touch_callback(touch_event_cb_fn_t cb, last_touch_e_t event_type); + +} // namespace screen + + +} // namespace pros + +extern __attribute__((weak)) void lvgl_init() {} +///@} +#endif //header guard diff --git a/include/pros/serial.h b/include/pros/serial.h index 01b12aa..dc9ead5 100644 --- a/include/pros/serial.h +++ b/include/pros/serial.h @@ -1,410 +1,410 @@ -/** - * \file pros/serial.h - * \ingroup c-serial - * - * Contains prototypes for the V5 Generic Serial related functions. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-serial Generic Serial C API - */ - -#ifndef _PROS_SERIAL_H_ -#define _PROS_SERIAL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -namespace c { -#endif - -/** - * \ingroup c-serial - */ - -/** - * \addtogroup c-serial - * @{ - */ - -/// \name Serial communication functions -/// These functions allow programmers to communicate using UART over RS485 -///@{ - -/** - * Enables generic serial on the given port. - * - * \note This function must be called before any of the generic serial - * functions will work. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * } - * \endcode - */ -int32_t serial_enable(uint8_t port); - -/** - * Sets the baudrate for the serial port to operate at. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * \param baudrate - * The baudrate to operate at - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * serial_write(1, "Hello World!", 12); - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_set_baudrate(uint8_t port, int32_t baudrate); - -/** - * Clears the internal input and output FIFO buffers. - * - * This can be useful to reset state and remove old, potentially unneeded data - * from the input FIFO buffer or to cancel sending any data in the output FIFO - * buffer. - * - * \note This function does not cause the data in the output buffer to be - * written, it simply clears the internal buffers. Unlike stdout, generic - * serial does not use buffered IO (the FIFO buffers are written as soon - * as possible). - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * serial_flush(1); - * serial_write(1, "Hello World!", 12); - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_flush(uint8_t port); - -/** - * Returns the number of bytes available to be read in the the port's FIFO - * input buffer. - * - * \note This function does not actually read any bytes, is simply returns the - * number of bytes available to be read. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * - * \return The number of bytes avaliable to be read or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_get_read_avail(1) >= 12) { - * char buffer[12]; - * serial_read(1, buffer, 12); - * printf("%s", buffer); - * } - * delay(100); - * } - * } - * \endcode - - */ -int32_t serial_get_read_avail(uint8_t port); - -/** - * Returns the number of bytes free in the port's FIFO output buffer. - * - * \note This function does not actually write any bytes, is simply returns the - * number of bytes free in the port's buffer. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * - * \return The number of bytes free or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_get_write_free(1) >= 12) { - * serial_write(1, "Hello World!", 12); - * } - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_get_write_free(uint8_t port); - -/** - * Reads the next byte avaliable in the port's input buffer without removing it. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * - * \return The next byte avaliable to be read, -1 if none are available, or - * PROS_ERR if the operation failed, setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_peek_byte(1) == 'H') { - * char buffer[12]; - * serial_read(1, buffer, 12); - * printf("%s", buffer); - * } - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_peek_byte(uint8_t port); - -/** - * Reads the next byte avaliable in the port's input buffer. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * - * \return The next byte avaliable to be read, -1 if none are available, or - * PROS_ERR if the operation failed, setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_read_byte(1) == 'H') { - * char buffer[12]; - * serial_read(1, buffer, 12); - * printf("%s", buffer); - * } - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_read_byte(uint8_t port); - -/** - * Reads up to the next length bytes from the port's input buffer and places - * them in the user supplied buffer. - * - * \note This function will only return bytes that are currently avaliable to be - * read and will not block waiting for any to arrive. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * - * \param port - * The V5 port number from 1-21 - * \param buffer - * The location to place the data read - * \param length - * The maximum number of bytes to read - * - * \return The number of bytes read or PROS_ERR if the operation failed, setting - * errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_get_read_avail(1) >= 12) { - * char buffer[12]; - * serial_read(1, buffer, 12); - * printf("%s", buffer); - * } - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_read(uint8_t port, uint8_t* buffer, int32_t length); - -/** - * Write the given byte to the port's output buffer. - * - * \note Data in the port's output buffer is written to the serial port as soon - * as possible on a FIFO basis and can not be done manually by the user. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * EIO - Serious internal write error. - * - * \param port - * The V5 port number from 1-21 - * \param buffer - * The byte to write - * - * \return The number of bytes written or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_get_write_free(1) >= 12) { - * serial_write_byte(1, 'H'); - * serial_write_byte(1, 'e'); - * serial_write_byte(1, 'l'); - * serial_write_byte(1, 'l'); - * serial_write_byte(1, 'o'); - * serial_write_byte(1, ' '); - * serial_write_byte(1, 'W'); - * serial_write_byte(1, 'o'); - * serial_write_byte(1, 'r'); - * serial_write_byte(1, 'l'); - * serial_write_byte(1, 'd'); - * serial_write_byte(1, '!'); - * serial_write_byte(1, '\n'); - * } - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_write_byte(uint8_t port, uint8_t buffer); - -/** - * Writes up to length bytes from the user supplied buffer to the port's output - * buffer. - * - * \note Data in the port's output buffer is written to the serial port as soon - * as possible on a FIFO basis and can not be done manually by the user. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - The given value is not within the range of V5 ports (1-21). - * EACCES - Another resource is currently trying to access the port. - * EIO - Serious internal write error. - * - * \param port - * The V5 port number from 1-21 - * \param buffer - * The data to write - * \param length - * The maximum number of bytes to write - * - * \return The number of bytes written or PROS_ERR if the operation failed, - * setting errno. - * - * \b Example: - * \code{.c} - * void opcontrol() { - * serial_enable(1); - * serial_set_baudrate(1, 9600); - * while (true) { - * if (serial_get_write_free(1) >= 12) { - * serial_write(1, "Hello World!\n", 12); - * } - * delay(100); - * } - * } - * \endcode - */ -int32_t serial_write(uint8_t port, uint8_t* buffer, int32_t length); - -///@} - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - +/** + * \file pros/serial.h + * \ingroup c-serial + * + * Contains prototypes for the V5 Generic Serial related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-serial Generic Serial C API + */ + +#ifndef _PROS_SERIAL_H_ +#define _PROS_SERIAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +namespace c { +#endif + +/** + * \ingroup c-serial + */ + +/** + * \addtogroup c-serial + * @{ + */ + +/// \name Serial communication functions +/// These functions allow programmers to communicate using UART over RS485 +///@{ + +/** + * Enables generic serial on the given port. + * + * \note This function must be called before any of the generic serial + * functions will work. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * } + * \endcode + */ +int32_t serial_enable(uint8_t port); + +/** + * Sets the baudrate for the serial port to operate at. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * \param baudrate + * The baudrate to operate at + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * serial_write(1, "Hello World!", 12); + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_set_baudrate(uint8_t port, int32_t baudrate); + +/** + * Clears the internal input and output FIFO buffers. + * + * This can be useful to reset state and remove old, potentially unneeded data + * from the input FIFO buffer or to cancel sending any data in the output FIFO + * buffer. + * + * \note This function does not cause the data in the output buffer to be + * written, it simply clears the internal buffers. Unlike stdout, generic + * serial does not use buffered IO (the FIFO buffers are written as soon + * as possible). + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * serial_flush(1); + * serial_write(1, "Hello World!", 12); + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_flush(uint8_t port); + +/** + * Returns the number of bytes available to be read in the the port's FIFO + * input buffer. + * + * \note This function does not actually read any bytes, is simply returns the + * number of bytes available to be read. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The number of bytes avaliable to be read or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_read_avail(1) >= 12) { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + + */ +int32_t serial_get_read_avail(uint8_t port); + +/** + * Returns the number of bytes free in the port's FIFO output buffer. + * + * \note This function does not actually write any bytes, is simply returns the + * number of bytes free in the port's buffer. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The number of bytes free or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_write_free(1) >= 12) { + * serial_write(1, "Hello World!", 12); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_get_write_free(uint8_t port); + +/** + * Reads the next byte avaliable in the port's input buffer without removing it. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The next byte avaliable to be read, -1 if none are available, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_peek_byte(1) == 'H') { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_peek_byte(uint8_t port); + +/** + * Reads the next byte avaliable in the port's input buffer. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * + * \return The next byte avaliable to be read, -1 if none are available, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_read_byte(1) == 'H') { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_read_byte(uint8_t port); + +/** + * Reads up to the next length bytes from the port's input buffer and places + * them in the user supplied buffer. + * + * \note This function will only return bytes that are currently avaliable to be + * read and will not block waiting for any to arrive. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * + * \param port + * The V5 port number from 1-21 + * \param buffer + * The location to place the data read + * \param length + * The maximum number of bytes to read + * + * \return The number of bytes read or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_read_avail(1) >= 12) { + * char buffer[12]; + * serial_read(1, buffer, 12); + * printf("%s", buffer); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_read(uint8_t port, uint8_t* buffer, int32_t length); + +/** + * Write the given byte to the port's output buffer. + * + * \note Data in the port's output buffer is written to the serial port as soon + * as possible on a FIFO basis and can not be done manually by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * EIO - Serious internal write error. + * + * \param port + * The V5 port number from 1-21 + * \param buffer + * The byte to write + * + * \return The number of bytes written or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_write_free(1) >= 12) { + * serial_write_byte(1, 'H'); + * serial_write_byte(1, 'e'); + * serial_write_byte(1, 'l'); + * serial_write_byte(1, 'l'); + * serial_write_byte(1, 'o'); + * serial_write_byte(1, ' '); + * serial_write_byte(1, 'W'); + * serial_write_byte(1, 'o'); + * serial_write_byte(1, 'r'); + * serial_write_byte(1, 'l'); + * serial_write_byte(1, 'd'); + * serial_write_byte(1, '!'); + * serial_write_byte(1, '\n'); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_write_byte(uint8_t port, uint8_t buffer); + +/** + * Writes up to length bytes from the user supplied buffer to the port's output + * buffer. + * + * \note Data in the port's output buffer is written to the serial port as soon + * as possible on a FIFO basis and can not be done manually by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - The given value is not within the range of V5 ports (1-21). + * EACCES - Another resource is currently trying to access the port. + * EIO - Serious internal write error. + * + * \param port + * The V5 port number from 1-21 + * \param buffer + * The data to write + * \param length + * The maximum number of bytes to write + * + * \return The number of bytes written or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example: + * \code{.c} + * void opcontrol() { + * serial_enable(1); + * serial_set_baudrate(1, 9600); + * while (true) { + * if (serial_get_write_free(1) >= 12) { + * serial_write(1, "Hello World!\n", 12); + * } + * delay(100); + * } + * } + * \endcode + */ +int32_t serial_write(uint8_t port, uint8_t* buffer, int32_t length); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + #endif // _PROS_SERIAL_H_ \ No newline at end of file diff --git a/include/pros/vision.h b/include/pros/vision.h index 73351e5..dbda3fc 100644 --- a/include/pros/vision.h +++ b/include/pros/vision.h @@ -1,851 +1,851 @@ -/** - * \file pros/vision.h - * \ingroup c-vision - * - * Contains prototypes for the VEX Vision Sensor-related functions. - * - * This file should not be modified by users, since it gets replaced whenever - * a kernel upgrade occurs. - * - * \copyright (c) 2017-2023, Purdue University ACM SIGBots. - * All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * \defgroup c-vision Vision Sensor C API - * \note Additional example code for this module can be found in its [Tutorial.](@ref vision) - */ - -#ifndef _PROS_VISION_H_ -#define _PROS_VISION_H_ - -/** - * \ingroup c-vision - */ - -/** - * \addtogroup c-vision - * @{ - */ - -/// \name Macros -///Parameters given by VEX -///@{ - -#define VISION_OBJECT_ERR_SIG 255 - -/** - * The width of the Vision Sensor’s field of view. - */ -#define VISION_FOV_WIDTH 316 - -/** - * The height of the Vision Sensor’s field of view. - */ -#define VISION_FOV_HEIGHT 212 - -///@} - -#include - -#ifdef __cplusplus -extern "C" { -namespace pros { -#endif - -/** - * \enum vision_object_type_e_t - * This enumeration defines the different types of objects that can be detected by the Vision Sensor - */ -typedef enum vision_object_type { - E_VISION_OBJECT_NORMAL = 0, - E_VISION_OBJECT_COLOR_CODE = 1, - E_VISION_OBJECT_LINE = 2 -} vision_object_type_e_t; - -/** - * \struct vision_signature_s_t - * This structure contains the parameters used by the Vision Sensor to detect objects. - */ -typedef struct __attribute__((__packed__)) vision_signature { - uint8_t id; - uint8_t _pad[3]; - float range; - int32_t u_min; - int32_t u_max; - int32_t u_mean; - int32_t v_min; - int32_t v_max; - int32_t v_mean; - uint32_t rgb; - uint32_t type; -} vision_signature_s_t; - -/** - * \typedef vision_color_code_t - * Color codes are just signatures with multiple IDs and a different type. - */ -typedef uint16_t vision_color_code_t; - -/** - * \struct vision_object_s_t - * This structure contains a descriptor of an object detected by the Vision Sensor - */ -typedef struct __attribute__((__packed__)) vision_object { - /// Object signature - uint16_t signature; - /// Object type, e.g. normal, color code, or line detection - vision_object_type_e_t type; - /// Left boundary coordinate of the object - int16_t left_coord; - /// Top boundary coordinate of the object - int16_t top_coord; - /// Width of the object - int16_t width; - /// Height of the object - int16_t height; - /// Angle of a color code object in 0.1 degree units (e.g. 10 -> 1 degree, 155 -> 15.5 degrees) - uint16_t angle; - /// Coordinates of the middle of the object (computed from the values above) - int16_t x_middle_coord; - /// Coordinates of the middle of the object (computed from the values above) - int16_t y_middle_coord; -} vision_object_s_t; - -/** - * \enum vision_zero - * This enumeration defines different zero points for returned vision objects. - */ -typedef enum vision_zero { - /// (0,0) coordinate is the top left of the FOV - E_VISION_ZERO_TOPLEFT = 0, - /// (0,0) coordinate is the center of the FOV - E_VISION_ZERO_CENTER = 1 -} vision_zero_e_t; - -#ifdef PROS_USE_SIMPLE_NAMES -#ifdef __cplusplus -#define VISION_OBJECT_NORMAL pros::E_VISION_OBJECT_NORMAL -#define VISION_OBJECT_COLOR_CODE pros::E_VISION_OBJECT_COLOR_CODE -#define VISION_OBJECT_LINE pros::E_VISION_OBJECT_LINE -#define VISION_ZERO_TOPLEFT pros::E_VISION_ZERO_TOPLEFT -#define VISION_ZERO_CENTER pros::E_VISION_ZERO_CENTER -#else -#define VISION_OBJECT_NORMAL E_VISION_OBJECT_NORMAL -#define VISION_OBJECT_COLOR_CODE E_VISION_OBJECT_COLOR_CODE -#define VISION_OBJECT_LINE E_VISION_OBJECT_LINE -#define VISION_ZERO_TOPLEFT E_VISION_ZERO_TOPLEFT -#define VISION_ZERO_CENTER E_VISION_ZERO_CENTER -#endif -#endif - -#ifdef __cplusplus -namespace c { -#endif - -/// \name Functions -///@{ - -/** - * Clears the vision sensor LED color, reseting it back to its default behavior, - * displaying the most prominent object signature color. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * void initialize() { - * vision_clear_led(VISION_PORT); - * } - * \endcode - */ -int32_t vision_clear_led(uint8_t port); - -/** - * Creates a signature from the vision sensor utility - * - * \param id - * The signature ID - * \param u_min - * Minimum value on U axis - * \param u_max - * Maximum value on U axis - * \param u_mean - * Mean value on U axis - * \param v_min - * Minimum value on V axis - * \param v_max - * Maximum value on V axis - * \param v_mean - * Mean value on V axis - * \param range - * Scale factor - * \param type - * Signature type - * - * \return A vision_signature_s_t that can be set using vision_set_signature - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * - * void opcontrol() { - * // values acquired from the vision utility - * vision_signature_s_t RED_SIG = - * vision_signature_from_utility(EXAMPLE_SIG, 8973, 11143, 10058, -2119, -1053, -1586, 5.4, 0); - * vision_set_signature(VISION_PORT, EXAMPLE_SIG, &RED_SIG); - * while (true) { - * vision_signature_s_t rtn = vision_get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); - * // Gets the largest object of the EXAMPLE_SIG signature - * printf("sig: %d", rtn.signature); - * // Prints "sig: 1" - * delay(2); - * } - * } - * \endcode - */ -vision_signature_s_t vision_signature_from_utility(const int32_t id, const int32_t u_min, const int32_t u_max, - const int32_t u_mean, const int32_t v_min, const int32_t v_max, - const int32_t v_mean, const float range, const int32_t type); - -/** - * Creates a color code that represents a combination of the given signature - * IDs. If fewer than 5 signatures are to be a part of the color code, pass 0 - * for the additional function parameters. - * - * This function uses the following values of errno when an error state is - * reached: - * EINVAL - Fewer than two signatures have been provided or one of the - * signatures is out of its [1-7] range (or 0 when omitted). - * - * \param port - * The V5 port number from 1-21 - * \param sig_id1 - * The first signature id [1-7] to add to the color code - * \param sig_id2 - * The second signature id [1-7] to add to the color code - * \param sig_id3 - * The third signature id [1-7] to add to the color code - * \param sig_id4 - * The fourth signature id [1-7] to add to the color code - * \param sig_id5 - * The fifth signature id [1-7] to add to the color code - * - * \return A vision_color_code_t object containing the color code information. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * #define OTHER_SIG 2 - * - * void opcontrol() { - * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG); - * } - * \endcode - */ -vision_color_code_t vision_create_color_code(uint8_t port, const uint32_t sig_id1, const uint32_t sig_id2, - const uint32_t sig_id3, const uint32_t sig_id4, const uint32_t sig_id5); - -/** - * Gets the nth largest object according to size_id. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * EDOM - size_id is greater than the number of available objects. - * EHOSTDOWN - Reading the vision sensor failed for an unknown reason. - * - * \param port - * The V5 port number from 1-21 - * \param size_id - * The object to read from a list roughly ordered by object size - * (0 is the largest item, 1 is the second largest, etc.) - * - * \return The vision_object_s_t object corresponding to the given size id, or - * PROS_ERR if an error occurred. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void opcontrol() { - * while (true) { - * vision_object_s_t rtn = vision_get_by_size(VISION_PORT, 0); - * // Gets the largest object - * printf("sig: %d", rtn.signature); - * delay(2); - * } - * } - * \endcode - */ -vision_object_s_t vision_get_by_size(uint8_t port, const uint32_t size_id); - -/** - * Gets the nth largest object of the given signature according to size_id. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * EINVAL - sig_id is outside the range [1-8] - * EDOM - size_id is greater than the number of available objects. - * EAGAIN - Reading the vision sensor failed for an unknown reason. - * - * \param port - * The V5 port number from 1-21 - * \param size_id - * The object to read from a list roughly ordered by object size - * (0 is the largest item, 1 is the second largest, etc.) - * \param signature - * The signature ID [1-7] for which an object will be returned. - * - * \return The vision_object_s_t object corresponding to the given signature and - * size_id, or PROS_ERR if an error occurred. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * - * void opcontrol() { - * while (true) { - * vision_object_s_t rtn = vision_get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); - * // Gets the largest object of the EXAMPLE_SIG signature - * printf("sig: %d", rtn.signature); - * // Prints "sig: 1" - * delay(2); - * } - * } - * \endcode - */ -vision_object_s_t vision_get_by_sig(uint8_t port, const uint32_t size_id, const uint32_t sig_id); - -/** - * Gets the nth largest object of the given color code according to size_id. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * EAGAIN - Reading the vision sensor failed for an unknown reason. - * - * \param port - * The V5 port number from 1-21 - * \param size_id - * The object to read from a list roughly ordered by object size - * (0 is the largest item, 1 is the second largest, etc.) - * \param color_code - * The vision_color_code_t for which an object will be returned - * - * \return The vision_object_s_t object corresponding to the given color code - * and size_id, or PROS_ERR if an error occurred. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * #define OTHER_SIG 2 - * - * void opcontrol() { - * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG); - * while (true) { - * vision_object_s_t rtn = vision_get_by_code(VISION_PORT, 0, code1); - * // Gets the largest object - * printf("sig: %d", rtn.signature); - * delay(2); - * } - * } - * \endcode - */ -vision_object_s_t vision_get_by_code(uint8_t port, const uint32_t size_id, const vision_color_code_t color_code); - -/** - * Gets the exposure parameter of the Vision Sensor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * - * \return The current exposure setting from [0,150], PROS_ERR if an error - * occurred - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void initialize() { - * if (vision_get_exposure(VISION_PORT) < 50) - * vision_set_exposure(VISION_PORT, 50); - * } - * \endcode - */ -int32_t vision_get_exposure(uint8_t port); - -/** - * Gets the number of objects currently detected by the Vision Sensor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * - * \return The number of objects detected on the specified vision sensor. - * Returns PROS_ERR if the port was invalid or an error occurred. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void opcontrol() { - * while (true) { - * printf("Number of Objects Detected: %d\n", vision_get_object_count(VISION_PORT)); - * delay(2); - * } - * } - * \endcode - */ -int32_t vision_get_object_count(uint8_t port); - -/** - * Get the white balance parameter of the Vision Sensor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * - * \return The current RGB white balance setting of the sensor - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define VISION_WHITE 0xff - * - * void initialize() { - * if (vision_get_white_balance(VISION_PORT) != VISION_WHITE) - * vision_set_white_balance(VISION_PORT, VISION_WHITE); - * } - * \endcode - */ -int32_t vision_get_white_balance(uint8_t port); - -/** - * Prints the contents of the signature as an initializer list to the terminal. - * - * \param sig - * The signature for which the contents will be printed - * - * \return 1 if no errors occured, PROS_ERR otherwise - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * - * void opcontrol() { - * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); - * vision_print_signature(sig); - * } - * \endcode - */ -int32_t vision_print_signature(const vision_signature_s_t sig); - -/** - * Reads up to object_count object descriptors into object_arr. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21), or - * fewer than object_count number of objects were found. - * ENODEV - The port cannot be configured as a vision sensor - * EDOM - size_id is greater than the number of available objects. - * - * \param port - * The V5 port number from 1-21 - * \param size_id - * The object to read from a list roughly ordered by object size - * (0 is the largest item, 1 is the second largest, etc.) - * \param object_count - * The number of objects to read - * \param[out] object_arr - * A pointer to copy the objects into - * - * \return The number of object signatures copied. This number will be less than - * object_count if there are fewer objects detected by the vision sensor. - * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects - * than size_id were found. All objects in object_arr that were not found are - * given VISION_OBJECT_ERR_SIG as their signature. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define NUM_VISION_OBJECTS 4 - * - * void opcontrol() { - * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; - * while (true) { - * vision_read_by_size(VISION_PORT, 0, NUM_VISION_OBJECTS, object_arr); - * printf("sig: %d", object_arr[0].signature); - * // Prints the signature of the largest object found - * delay(2); - * } - * } - * \endcode - */ -int32_t vision_read_by_size(uint8_t port, const uint32_t size_id, const uint32_t object_count, - vision_object_s_t* const object_arr); - -/** - * Reads up to object_count object descriptors into object_arr. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21), or - * fewer than object_count number of objects were found. - * ENODEV - The port cannot be configured as a vision sensor - * EDOM - size_id is greater than the number of available objects. - * - * \param port - * The V5 port number from 1-21 - * \param object_count - * The number of objects to read - * \param size_id - * The object to read from a list roughly ordered by object size - * (0 is the largest item, 1 is the second largest, etc.) - * \param signature - * The signature ID [1-7] for which objects will be returned. - * \param[out] object_arr - * A pointer to copy the objects into - * - * \return The number of object signatures copied. This number will be less than - * object_count if there are fewer objects detected by the vision sensor. - * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects - * than size_id were found. All objects in object_arr that were not found are - * given VISION_OBJECT_ERR_SIG as their signature. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * #define NUM_VISION_OBJECTS 4 - * - * void opcontrol() { - * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; - * while (true) { - * vision_read_by_sig(VISION_PORT, 0, EXAMPLE_SIG, NUM_VISION_OBJECTS, object_arr); - * printf("sig: %d", object_arr[0].signature); - * // Prints "sig: 1" - * delay(2); - * } - * } - * \endcode - */ -int32_t vision_read_by_sig(uint8_t port, const uint32_t size_id, const uint32_t sig_id, const uint32_t object_count, - vision_object_s_t* const object_arr); - -/** - * Reads up to object_count object descriptors into object_arr. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21), or - * fewer than object_count number of objects were found. - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * \param object_count - * The number of objects to read - * \param size_id - * The object to read from a list roughly ordered by object size - * (0 is the largest item, 1 is the second largest, etc.) - * \param color_code - * The vision_color_code_t for which objects will be returned - * \param[out] object_arr - * A pointer to copy the objects into - * - * \return The number of object signatures copied. This number will be less than - * object_count if there are fewer objects detected by the vision sensor. - * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects - * than size_id were found. All objects in object_arr that were not found are - * given VISION_OBJECT_ERR_SIG as their signature. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * #define OTHER_SIG 2 - * #define NUM_VISION_OBJECTS 4 - * - * void opcontrol() { - * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; - * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG, 0, 0, 0); - * while (true) { - * vision_read_by_code(VISION_PORT, 0, code1, NUM_VISION_OBJECTS, object_arr); - * printf("sig: %d", object_arr[0].signature); - * // Prints the signature of the largest object found - * delay(2); - * } - * } - * \endcode - */ -int32_t vision_read_by_code(uint8_t port, const uint32_t size_id, const vision_color_code_t color_code, - const uint32_t object_count, vision_object_s_t* const object_arr); - -/** - * Gets the object detection signature with the given id number. - * - * \param port - * The V5 port number from 1-21 - * \param signature_id - * The signature id to read - * - * \return A vision_signature_s_t containing information about the signature. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * - * void opcontrol() { - * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); - * vision_print_signature(sig); - * } - * \endcode - */ -vision_signature_s_t vision_get_signature(uint8_t port, const uint8_t signature_id); - -/** - * Stores the supplied object detection signature onto the vision sensor. - * - * \note This saves the signature in volatile memory, and the signature will be - * lost as soon as the sensor is powered down. - * - * \param port - * The V5 port number from 1-21 - * \param signature_id - * The signature id to store into - * \param[in] signature_ptr - * A pointer to the signature to save - * - * \return 1 if no errors occured, PROS_ERR otherwise - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define EXAMPLE_SIG 1 - * - * void opcontrol() { - * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); - * sig.range = 10.0; - * vision_set_signature(VISION_PORT, EXAMPLE_SIG, &sig); - * } - * \endcode - */ -int32_t vision_set_signature(uint8_t port, const uint8_t signature_id, vision_signature_s_t* const signature_ptr); - -/** - * Enables/disables auto white-balancing on the Vision Sensor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * EINVAL - enable was not 0 or 1 - * - * \param port - * The V5 port number from 1-21 - * \param enabled - * Pass 0 to disable, 1 to enable - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void initialize() { - * vision_set_auto_white_balance(VISION_PORT, true); - * } - * \endcode - */ -int32_t vision_set_auto_white_balance(uint8_t port, const uint8_t enable); - -/** - * Sets the exposure parameter of the Vision Sensor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * \param percent - * The new exposure setting from [0,150] - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void initialize() { - * if (vision_get_exposure(VISION_PORT) < 50) - * vision_set_exposure(VISION_PORT, 50); - * } - * \endcode - */ -int32_t vision_set_exposure(uint8_t port, const uint8_t exposure); - -/** - * Sets the vision sensor LED color, overriding the automatic behavior. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * \param rgb - * An RGB code to set the LED to - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void initialize() { - * vision_set_led(VISION_PORT, COLOR_BLANCHED_ALMOND); - * } - * \endcode - */ -int32_t vision_set_led(uint8_t port, const int32_t rgb); - -/** - * Sets the white balance parameter of the Vision Sensor. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * \param rgb - * The new RGB white balance setting of the sensor - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * #define VISION_WHITE 0xff - * - * void initialize() { - * vision_set_white_balance(VISION_PORT, VISION_WHITE); - * } - * \endcode - */ -int32_t vision_set_white_balance(uint8_t port, const int32_t rgb); - -/** - * Sets the (0,0) coordinate for the Field of View. - * - * This will affect the coordinates returned for each request for a - * vision_object_s_t from the sensor, so it is recommended that this function - * only be used to configure the sensor at the beginning of its use. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a vision sensor - * - * \param port - * The V5 port number from 1-21 - * \param zero_point - * One of vision_zero_e_t to set the (0,0) coordinate for the FOV - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void initialize() { - * vision_set_zero_point(VISION_PORT, E_VISION_ZERO_CENTER); - * } - * \endcode - */ -int32_t vision_set_zero_point(uint8_t port, vision_zero_e_t zero_point); - -/** - * Sets the Wi-Fi mode of the Vision sensor - * - * This functions uses the following values of errno when an error state is - * reached: - * ENXIO - The given port is not within the range of V5 ports (1-21) - * EACCESS - Anothe resources is currently trying to access the port - * - * \param port - * The V5 port number from 1-21 - * \param enable - * Disable Wi-Fi on the Vision sensor if 0, enable otherwise (e.g. 1) - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * #define VISION_PORT 1 - * - * void initialize() { - * vision_set_wifi_mode(VISION_PORT, 0); - * } - * \endcode - */ -int32_t vision_set_wifi_mode(uint8_t port, const uint8_t enable); - -///@} - -///@} - -#ifdef __cplusplus -} // namespace c -} // namespace pros -} -#endif - -#endif // _PROS_VISION_H_ +/** + * \file pros/vision.h + * \ingroup c-vision + * + * Contains prototypes for the VEX Vision Sensor-related functions. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup c-vision Vision Sensor C API + * \note Additional example code for this module can be found in its [Tutorial.](@ref vision) + */ + +#ifndef _PROS_VISION_H_ +#define _PROS_VISION_H_ + +/** + * \ingroup c-vision + */ + +/** + * \addtogroup c-vision + * @{ + */ + +/// \name Macros +///Parameters given by VEX +///@{ + +#define VISION_OBJECT_ERR_SIG 255 + +/** + * The width of the Vision Sensor’s field of view. + */ +#define VISION_FOV_WIDTH 316 + +/** + * The height of the Vision Sensor’s field of view. + */ +#define VISION_FOV_HEIGHT 212 + +///@} + +#include + +#ifdef __cplusplus +extern "C" { +namespace pros { +#endif + +/** + * \enum vision_object_type_e_t + * This enumeration defines the different types of objects that can be detected by the Vision Sensor + */ +typedef enum vision_object_type { + E_VISION_OBJECT_NORMAL = 0, + E_VISION_OBJECT_COLOR_CODE = 1, + E_VISION_OBJECT_LINE = 2 +} vision_object_type_e_t; + +/** + * \struct vision_signature_s_t + * This structure contains the parameters used by the Vision Sensor to detect objects. + */ +typedef struct __attribute__((__packed__)) vision_signature { + uint8_t id; + uint8_t _pad[3]; + float range; + int32_t u_min; + int32_t u_max; + int32_t u_mean; + int32_t v_min; + int32_t v_max; + int32_t v_mean; + uint32_t rgb; + uint32_t type; +} vision_signature_s_t; + +/** + * \typedef vision_color_code_t + * Color codes are just signatures with multiple IDs and a different type. + */ +typedef uint16_t vision_color_code_t; + +/** + * \struct vision_object_s_t + * This structure contains a descriptor of an object detected by the Vision Sensor + */ +typedef struct __attribute__((__packed__)) vision_object { + /// Object signature + uint16_t signature; + /// Object type, e.g. normal, color code, or line detection + vision_object_type_e_t type; + /// Left boundary coordinate of the object + int16_t left_coord; + /// Top boundary coordinate of the object + int16_t top_coord; + /// Width of the object + int16_t width; + /// Height of the object + int16_t height; + /// Angle of a color code object in 0.1 degree units (e.g. 10 -> 1 degree, 155 -> 15.5 degrees) + uint16_t angle; + /// Coordinates of the middle of the object (computed from the values above) + int16_t x_middle_coord; + /// Coordinates of the middle of the object (computed from the values above) + int16_t y_middle_coord; +} vision_object_s_t; + +/** + * \enum vision_zero + * This enumeration defines different zero points for returned vision objects. + */ +typedef enum vision_zero { + /// (0,0) coordinate is the top left of the FOV + E_VISION_ZERO_TOPLEFT = 0, + /// (0,0) coordinate is the center of the FOV + E_VISION_ZERO_CENTER = 1 +} vision_zero_e_t; + +#ifdef PROS_USE_SIMPLE_NAMES +#ifdef __cplusplus +#define VISION_OBJECT_NORMAL pros::E_VISION_OBJECT_NORMAL +#define VISION_OBJECT_COLOR_CODE pros::E_VISION_OBJECT_COLOR_CODE +#define VISION_OBJECT_LINE pros::E_VISION_OBJECT_LINE +#define VISION_ZERO_TOPLEFT pros::E_VISION_ZERO_TOPLEFT +#define VISION_ZERO_CENTER pros::E_VISION_ZERO_CENTER +#else +#define VISION_OBJECT_NORMAL E_VISION_OBJECT_NORMAL +#define VISION_OBJECT_COLOR_CODE E_VISION_OBJECT_COLOR_CODE +#define VISION_OBJECT_LINE E_VISION_OBJECT_LINE +#define VISION_ZERO_TOPLEFT E_VISION_ZERO_TOPLEFT +#define VISION_ZERO_CENTER E_VISION_ZERO_CENTER +#endif +#endif + +#ifdef __cplusplus +namespace c { +#endif + +/// \name Functions +///@{ + +/** + * Clears the vision sensor LED color, reseting it back to its default behavior, + * displaying the most prominent object signature color. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * void initialize() { + * vision_clear_led(VISION_PORT); + * } + * \endcode + */ +int32_t vision_clear_led(uint8_t port); + +/** + * Creates a signature from the vision sensor utility + * + * \param id + * The signature ID + * \param u_min + * Minimum value on U axis + * \param u_max + * Maximum value on U axis + * \param u_mean + * Mean value on U axis + * \param v_min + * Minimum value on V axis + * \param v_max + * Maximum value on V axis + * \param v_mean + * Mean value on V axis + * \param range + * Scale factor + * \param type + * Signature type + * + * \return A vision_signature_s_t that can be set using vision_set_signature + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * // values acquired from the vision utility + * vision_signature_s_t RED_SIG = + * vision_signature_from_utility(EXAMPLE_SIG, 8973, 11143, 10058, -2119, -1053, -1586, 5.4, 0); + * vision_set_signature(VISION_PORT, EXAMPLE_SIG, &RED_SIG); + * while (true) { + * vision_signature_s_t rtn = vision_get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); + * // Gets the largest object of the EXAMPLE_SIG signature + * printf("sig: %d", rtn.signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ +vision_signature_s_t vision_signature_from_utility(const int32_t id, const int32_t u_min, const int32_t u_max, + const int32_t u_mean, const int32_t v_min, const int32_t v_max, + const int32_t v_mean, const float range, const int32_t type); + +/** + * Creates a color code that represents a combination of the given signature + * IDs. If fewer than 5 signatures are to be a part of the color code, pass 0 + * for the additional function parameters. + * + * This function uses the following values of errno when an error state is + * reached: + * EINVAL - Fewer than two signatures have been provided or one of the + * signatures is out of its [1-7] range (or 0 when omitted). + * + * \param port + * The V5 port number from 1-21 + * \param sig_id1 + * The first signature id [1-7] to add to the color code + * \param sig_id2 + * The second signature id [1-7] to add to the color code + * \param sig_id3 + * The third signature id [1-7] to add to the color code + * \param sig_id4 + * The fourth signature id [1-7] to add to the color code + * \param sig_id5 + * The fifth signature id [1-7] to add to the color code + * + * \return A vision_color_code_t object containing the color code information. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * + * void opcontrol() { + * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG); + * } + * \endcode + */ +vision_color_code_t vision_create_color_code(uint8_t port, const uint32_t sig_id1, const uint32_t sig_id2, + const uint32_t sig_id3, const uint32_t sig_id4, const uint32_t sig_id5); + +/** + * Gets the nth largest object according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * EHOSTDOWN - Reading the vision sensor failed for an unknown reason. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * + * \return The vision_object_s_t object corresponding to the given size id, or + * PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void opcontrol() { + * while (true) { + * vision_object_s_t rtn = vision_get_by_size(VISION_PORT, 0); + * // Gets the largest object + * printf("sig: %d", rtn.signature); + * delay(2); + * } + * } + * \endcode + */ +vision_object_s_t vision_get_by_size(uint8_t port, const uint32_t size_id); + +/** + * Gets the nth largest object of the given signature according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EINVAL - sig_id is outside the range [1-8] + * EDOM - size_id is greater than the number of available objects. + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param signature + * The signature ID [1-7] for which an object will be returned. + * + * \return The vision_object_s_t object corresponding to the given signature and + * size_id, or PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * while (true) { + * vision_object_s_t rtn = vision_get_by_sig(VISION_PORT, 0, EXAMPLE_SIG); + * // Gets the largest object of the EXAMPLE_SIG signature + * printf("sig: %d", rtn.signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ +vision_object_s_t vision_get_by_sig(uint8_t port, const uint32_t size_id, const uint32_t sig_id); + +/** + * Gets the nth largest object of the given color code according to size_id. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EAGAIN - Reading the vision sensor failed for an unknown reason. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param color_code + * The vision_color_code_t for which an object will be returned + * + * \return The vision_object_s_t object corresponding to the given color code + * and size_id, or PROS_ERR if an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * + * void opcontrol() { + * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG); + * while (true) { + * vision_object_s_t rtn = vision_get_by_code(VISION_PORT, 0, code1); + * // Gets the largest object + * printf("sig: %d", rtn.signature); + * delay(2); + * } + * } + * \endcode + */ +vision_object_s_t vision_get_by_code(uint8_t port, const uint32_t size_id, const vision_color_code_t color_code); + +/** + * Gets the exposure parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return The current exposure setting from [0,150], PROS_ERR if an error + * occurred + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * if (vision_get_exposure(VISION_PORT) < 50) + * vision_set_exposure(VISION_PORT, 50); + * } + * \endcode + */ +int32_t vision_get_exposure(uint8_t port); + +/** + * Gets the number of objects currently detected by the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return The number of objects detected on the specified vision sensor. + * Returns PROS_ERR if the port was invalid or an error occurred. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void opcontrol() { + * while (true) { + * printf("Number of Objects Detected: %d\n", vision_get_object_count(VISION_PORT)); + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_get_object_count(uint8_t port); + +/** + * Get the white balance parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * + * \return The current RGB white balance setting of the sensor + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define VISION_WHITE 0xff + * + * void initialize() { + * if (vision_get_white_balance(VISION_PORT) != VISION_WHITE) + * vision_set_white_balance(VISION_PORT, VISION_WHITE); + * } + * \endcode + */ +int32_t vision_get_white_balance(uint8_t port); + +/** + * Prints the contents of the signature as an initializer list to the terminal. + * + * \param sig + * The signature for which the contents will be printed + * + * \return 1 if no errors occured, PROS_ERR otherwise + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); + * vision_print_signature(sig); + * } + * \endcode + */ +int32_t vision_print_signature(const vision_signature_s_t sig); + +/** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21), or + * fewer than object_count number of objects were found. + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * + * \param port + * The V5 port number from 1-21 + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param object_count + * The number of objects to read + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * while (true) { + * vision_read_by_size(VISION_PORT, 0, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints the signature of the largest object found + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_read_by_size(uint8_t port, const uint32_t size_id, const uint32_t object_count, + vision_object_s_t* const object_arr); + +/** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21), or + * fewer than object_count number of objects were found. + * ENODEV - The port cannot be configured as a vision sensor + * EDOM - size_id is greater than the number of available objects. + * + * \param port + * The V5 port number from 1-21 + * \param object_count + * The number of objects to read + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param signature + * The signature ID [1-7] for which objects will be returned. + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * while (true) { + * vision_read_by_sig(VISION_PORT, 0, EXAMPLE_SIG, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints "sig: 1" + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_read_by_sig(uint8_t port, const uint32_t size_id, const uint32_t sig_id, const uint32_t object_count, + vision_object_s_t* const object_arr); + +/** + * Reads up to object_count object descriptors into object_arr. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21), or + * fewer than object_count number of objects were found. + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param object_count + * The number of objects to read + * \param size_id + * The object to read from a list roughly ordered by object size + * (0 is the largest item, 1 is the second largest, etc.) + * \param color_code + * The vision_color_code_t for which objects will be returned + * \param[out] object_arr + * A pointer to copy the objects into + * + * \return The number of object signatures copied. This number will be less than + * object_count if there are fewer objects detected by the vision sensor. + * Returns PROS_ERR if the port was invalid, an error occurred, or fewer objects + * than size_id were found. All objects in object_arr that were not found are + * given VISION_OBJECT_ERR_SIG as their signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * #define OTHER_SIG 2 + * #define NUM_VISION_OBJECTS 4 + * + * void opcontrol() { + * vision_object_s_t object_arr[NUM_VISION_OBJECTS]; + * vision_color_code_t code1 = vision_create_color_code(VISION_PORT, EXAMPLE_SIG, OTHER_SIG, 0, 0, 0); + * while (true) { + * vision_read_by_code(VISION_PORT, 0, code1, NUM_VISION_OBJECTS, object_arr); + * printf("sig: %d", object_arr[0].signature); + * // Prints the signature of the largest object found + * delay(2); + * } + * } + * \endcode + */ +int32_t vision_read_by_code(uint8_t port, const uint32_t size_id, const vision_color_code_t color_code, + const uint32_t object_count, vision_object_s_t* const object_arr); + +/** + * Gets the object detection signature with the given id number. + * + * \param port + * The V5 port number from 1-21 + * \param signature_id + * The signature id to read + * + * \return A vision_signature_s_t containing information about the signature. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); + * vision_print_signature(sig); + * } + * \endcode + */ +vision_signature_s_t vision_get_signature(uint8_t port, const uint8_t signature_id); + +/** + * Stores the supplied object detection signature onto the vision sensor. + * + * \note This saves the signature in volatile memory, and the signature will be + * lost as soon as the sensor is powered down. + * + * \param port + * The V5 port number from 1-21 + * \param signature_id + * The signature id to store into + * \param[in] signature_ptr + * A pointer to the signature to save + * + * \return 1 if no errors occured, PROS_ERR otherwise + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define EXAMPLE_SIG 1 + * + * void opcontrol() { + * vision_signature_s_t sig = vision_get_signature(VISION_PORT, EXAMPLE_SIG); + * sig.range = 10.0; + * vision_set_signature(VISION_PORT, EXAMPLE_SIG, &sig); + * } + * \endcode + */ +int32_t vision_set_signature(uint8_t port, const uint8_t signature_id, vision_signature_s_t* const signature_ptr); + +/** + * Enables/disables auto white-balancing on the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * EINVAL - enable was not 0 or 1 + * + * \param port + * The V5 port number from 1-21 + * \param enabled + * Pass 0 to disable, 1 to enable + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_auto_white_balance(VISION_PORT, true); + * } + * \endcode + */ +int32_t vision_set_auto_white_balance(uint8_t port, const uint8_t enable); + +/** + * Sets the exposure parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param percent + * The new exposure setting from [0,150] + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * if (vision_get_exposure(VISION_PORT) < 50) + * vision_set_exposure(VISION_PORT, 50); + * } + * \endcode + */ +int32_t vision_set_exposure(uint8_t port, const uint8_t exposure); + +/** + * Sets the vision sensor LED color, overriding the automatic behavior. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param rgb + * An RGB code to set the LED to + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_led(VISION_PORT, COLOR_BLANCHED_ALMOND); + * } + * \endcode + */ +int32_t vision_set_led(uint8_t port, const int32_t rgb); + +/** + * Sets the white balance parameter of the Vision Sensor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param rgb + * The new RGB white balance setting of the sensor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * #define VISION_WHITE 0xff + * + * void initialize() { + * vision_set_white_balance(VISION_PORT, VISION_WHITE); + * } + * \endcode + */ +int32_t vision_set_white_balance(uint8_t port, const int32_t rgb); + +/** + * Sets the (0,0) coordinate for the Field of View. + * + * This will affect the coordinates returned for each request for a + * vision_object_s_t from the sensor, so it is recommended that this function + * only be used to configure the sensor at the beginning of its use. + * + * This function uses the following values of errno when an error state is + * reached: + * ENXIO - The given value is not within the range of V5 ports (1-21). + * ENODEV - The port cannot be configured as a vision sensor + * + * \param port + * The V5 port number from 1-21 + * \param zero_point + * One of vision_zero_e_t to set the (0,0) coordinate for the FOV + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_zero_point(VISION_PORT, E_VISION_ZERO_CENTER); + * } + * \endcode + */ +int32_t vision_set_zero_point(uint8_t port, vision_zero_e_t zero_point); + +/** + * Sets the Wi-Fi mode of the Vision sensor + * + * This functions uses the following values of errno when an error state is + * reached: + * ENXIO - The given port is not within the range of V5 ports (1-21) + * EACCESS - Anothe resources is currently trying to access the port + * + * \param port + * The V5 port number from 1-21 + * \param enable + * Disable Wi-Fi on the Vision sensor if 0, enable otherwise (e.g. 1) + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * #define VISION_PORT 1 + * + * void initialize() { + * vision_set_wifi_mode(VISION_PORT, 0); + * } + * \endcode + */ +int32_t vision_set_wifi_mode(uint8_t port, const uint8_t enable); + +///@} + +///@} + +#ifdef __cplusplus +} // namespace c +} // namespace pros +} +#endif + +#endif // _PROS_VISION_H_ diff --git a/include/robodash/api.h b/include/robodash/api.h index 698bb54..66c880d 100644 --- a/include/robodash/api.h +++ b/include/robodash/api.h @@ -7,16 +7,33 @@ #pragma once +#define ROBODASH #define RD_VERSION_MAJOR 2 #define RD_VERSION_MINOR 0 #define RD_VERSION_PATCH 0 #include "liblvgl/lvgl.h" +// ========================== Check Compatibility ========================== // + #if (LV_VERSION_CHECK(8, 3, 0) == 0) #error "LVGL version incompatible with robodash (Requires >= 8.3.X)" #endif +#ifndef LV_FONT_MONTSERRAT_12 +#error "LVGL install incompatible with robodash, missing font: Montserrat 12" +#endif + +#ifndef LV_FONT_MONTSERRAT_14 +#error "LVGL install incompatible with robodash, missing font: Montserrat 14" +#endif + +#ifndef LV_FONT_MONTSERRAT_16 +#error "LVGL install incompatible with robodash, missing font: Montserrat 16" +#endif + +// ============================ Include Library ============================ // + #include "core.h" #ifdef __cplusplus diff --git a/include/robodash/core.h b/include/robodash/core.h index b04a183..0a1f3f1 100644 --- a/include/robodash/core.h +++ b/include/robodash/core.h @@ -16,26 +16,33 @@ extern "C" { * @defgroup core Core * @brief The view management system. * - * Knowledge of LVGL is required if you wish to create a view. + * The LVGL view management system to enable compatibility between templates that provide LVGL GUIs. + * Knowledge of LVGL is required to use this API. */ /// @addtogroup core /// @{ +/** + * @brief Animation state + */ +typedef enum rd_anim_state { RD_ANIM_ON, RD_ANIM_OFF } rd_anim_state_t; + /** * @brief Robodash view structure */ typedef struct rd_view { const char *name; lv_obj_t *obj; - lv_obj_t *_btn; + lv_obj_t *_list_btn; + rd_anim_state_t anims; } rd_view_t; /** * @brief Create a view * * @param name Name of the view - * @return rd_view_t + * @return A pointer to a view object */ rd_view_t *rd_view_create(const char *name); @@ -58,10 +65,36 @@ void rd_view_del(rd_view_t *view); /** * @brief Get the view's lvgl object * - * @param view View + * @param view View to query */ lv_obj_t *rd_view_obj(rd_view_t *view); +/** + * @brief Push an alert + * + * Pushes an alert to the screen, regardless of which view is active. + * + * @param view View to link back to + * @param msg Message to display + */ +void rd_view_alert(rd_view_t *view, const char *msg); + +/** + * @brief Enable or disable animations for a view + * + * @param view View to modify + * @param state Animation state + */ +void rd_view_set_anims(rd_view_t *view, rd_anim_state_t state); + +/** + * @brief Get the animation state for a view + * + * @param view View to query + * @return The animation state + */ +rd_anim_state_t rd_view_get_anims(rd_view_t *view); + /// @} #ifdef __cplusplus diff --git a/include/robodash/impl/assets.h b/include/robodash/impl/assets.h index 64c4d78..ebbd48c 100644 --- a/include/robodash/impl/assets.h +++ b/include/robodash/impl/assets.h @@ -7,7 +7,13 @@ #pragma once #include "robodash/apix.h" +#ifdef __cplusplus +extern "C" { +#endif + extern lv_font_t source_code_pro_16; -extern lv_font_t montserrat_12; -extern lv_font_t montserrat_16; extern lv_img_t stack; + +#ifdef __cplusplus +} +#endif diff --git a/include/robodash/impl/filesystem.h b/include/robodash/impl/filesystem.h index 6a2e596..d93651b 100644 --- a/include/robodash/impl/filesystem.h +++ b/include/robodash/impl/filesystem.h @@ -6,4 +6,12 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + void _init_fs(); + +#ifdef __cplusplus +} +#endif diff --git a/include/robodash/impl/styles.h b/include/robodash/impl/styles.h index 662c0c3..ebc3ad5 100644 --- a/include/robodash/impl/styles.h +++ b/include/robodash/impl/styles.h @@ -28,6 +28,7 @@ extern lv_color_t color_shade; extern lv_color_t color_primary; extern lv_color_t color_primary_dark; extern lv_color_t color_text; +extern lv_color_t color_red; extern lv_color_t color_bar; extern lv_color_t color_bar_dark; @@ -39,6 +40,7 @@ extern void _init_colors(); extern lv_style_t style_bg; extern lv_style_t style_transp; +extern lv_style_t style_alert; extern void _init_style_misc(); @@ -70,16 +72,16 @@ extern lv_style_t style_text_centered; extern void _init_style_text(); -// ================================ Sidebar ================================ // +// ================================== Core ================================== // -extern lv_style_t style_bar_button; -extern lv_style_t style_bar_button_pr; -extern lv_style_t style_bar_list; -extern lv_style_t style_bar_list_btn; -extern lv_style_t style_bar_bg; -extern lv_style_t style_bar_modal; +extern lv_style_t style_core_button; +extern lv_style_t style_core_button_pr; +extern lv_style_t style_core_list; +extern lv_style_t style_core_list_btn; +extern lv_style_t style_core_bg; +extern lv_style_t style_core_shade; -extern void _init_style_bar(); +extern void _init_style_core(); #ifdef __cplusplus } diff --git a/include/robodash/views/console.hpp b/include/robodash/views/console.hpp index f2578f2..b5f9469 100644 --- a/include/robodash/views/console.hpp +++ b/include/robodash/views/console.hpp @@ -6,6 +6,7 @@ #pragma once #include "robodash/api.h" +#include #include namespace rd { @@ -30,6 +31,10 @@ class Console { private: rd_view_t *view; + lv_obj_t *output; + lv_obj_t *output_cont; + std::ostringstream stream; + public: /** * @brief Create a new Console diff --git a/include/robodash/views/image.hpp b/include/robodash/views/image.hpp index c3f973d..f9d2708 100644 --- a/include/robodash/views/image.hpp +++ b/include/robodash/views/image.hpp @@ -20,10 +20,8 @@ namespace rd { * color images. * * @image html image.png - * @bug The sidebar animations are very choppy when viewing an image. A fix for this will be - * implemented for release. * - * Displays still images from an SD card or a C array. + * Displays still images from an SD card or C array. */ /** diff --git a/include/robodash/views/selector.hpp b/include/robodash/views/selector.hpp index 242bd51..885ad67 100644 --- a/include/robodash/views/selector.hpp +++ b/include/robodash/views/selector.hpp @@ -39,20 +39,16 @@ class Selector { /// @name Selector Functions /** - * @brief Create a new Selector + * @brief Create autonomous selector + * @param autons Vector of autonomous rotuines + * @bug Multiple selectors cannot be active at the same time. */ - Selector(); - - /** - * @brief Initialize autonomous manager - * @param autons Vector of Routines - */ - void add_autons(std::vector autons); + Selector(std::vector autons); /** * @brief Run selected auton */ - void do_auton(); + void run_auton(); /** * @brief Set this view to the active view diff --git a/project.pros b/project.pros index 58b11a7..03391d7 100644 --- a/project.pros +++ b/project.pros @@ -5,280 +5,254 @@ "target": "v5", "templates": { "kernel": { + "location": "/Users/alex/Library/Application Support/PROS/templates/kernel@4.0.6", + "metadata": { + "cold_addr": "58720256", + "cold_output": "bin/cold.package.bin", + "hot_addr": "125829120", + "hot_output": "bin/hot.package.bin", + "origin": "kernel-beta-mainline", + "output": "bin/monolith.bin" + }, + "name": "kernel", "py/object": "pros.conductor.templates.local_template.LocalTemplate", - "py/state": { - "location": "/Users/alex/Library/Application Support/PROS/templates/kernel@4.0.4", - "metadata": { - "cold_addr": "58720256", - "cold_output": "bin/cold.package.bin", - "hot_addr": "125829120", - "hot_output": "bin/hot.package.bin", - "origin": "kernel-beta-mainline", - "output": "bin/monolith.bin" - }, - "name": "kernel", - "supported_kernels": null, - "system_files": [ - "firmware\\v5-hot.ld", - "include\\pros\\imu.hpp", - "include\\pros\\link.hpp", - "include\\pros\\vision.h", - "include\\pros\\optical.h", - "include\\pros\\colors.h", - "include\\pros\\abstract_motor.hpp", - "include\\pros\\adi.h", - "include\\pros\\device.h", - "include\\pros\\error.h", - "include\\pros\\imu.h", - "include\\pros\\distance.hpp", - "include\\pros\\motors.hpp", - "include\\pros\\ext_adi.h", - "include\\pros\\llemu.h", - "include\\pros\\vision.hpp", - "include\\pros\\screen.h", - "include\\pros\\gps.h", - "include\\pros\\optical.hpp", - "firmware\\v5.ld", - "include\\pros\\misc.hpp", - "include\\pros\\rtos.h", - "include\\pros\\screen.hpp", - "include\\pros\\device.hpp", - "firmware\\libpros.a", - "include\\pros\\distance.h", - "include\\pros\\motors.h", - "include\\pros\\serial.h", - "common.mk", - "include\\pros\\gps.hpp", - "include\\pros\\link.h", - "include\\pros\\rtos.hpp", - "include\\pros\\serial.hpp", - "include\\pros\\rotation.hpp", - "firmware\\v5-common.ld", - "include\\pros\\colors.hpp", - "include\\pros\\motor_group.hpp", - "include\\pros\\apix.h", - "include\\api.h", - "firmware\\libc.a", - "firmware\\libm.a", - "include\\pros\\misc.h", - "include\\pros\\adi.hpp", - "include\\pros\\rotation.h", - "include\\pros\\llemu.hpp" - ], - "target": "v5", - "user_files": [ - ".gitignore", - "src\\main.cc", - "Makefile", - "include\\main.hh", - "include\\main.h", - "include\\main.hpp", - "src\\main.c", - "src\\main.cpp" - ], - "version": "4.0.4" - } + "supported_kernels": null, + "system_files": [ + "firmware\\v5.ld", + "include\\pros\\colors.h", + "include\\pros\\distance.hpp", + "include\\pros\\llemu.hpp", + "firmware\\libm.a", + "include\\pros\\motor_group.hpp", + "include\\pros\\serial.hpp", + "common.mk", + "include\\pros\\device.hpp", + "include\\pros\\screen.hpp", + "include\\pros\\abstract_motor.hpp", + "include\\pros\\gps.h", + "include\\pros\\colors.hpp", + "include\\pros\\adi.h", + "include\\pros\\screen.h", + "include\\pros\\rotation.hpp", + "firmware\\v5-hot.ld", + "include\\pros\\link.h", + "include\\pros\\rotation.h", + "include\\api.h", + "include\\pros\\ext_adi.h", + "include\\pros\\device.h", + "include\\pros\\motors.hpp", + "firmware\\v5-common.ld", + "include\\pros\\apix.h", + "include\\pros\\rtos.hpp", + "include\\pros\\vision.hpp", + "include\\pros\\vision.h", + "include\\pros\\gps.hpp", + "include\\pros\\motors.h", + "include\\pros\\rtos.h", + "include\\pros\\imu.hpp", + "include\\pros\\llemu.h", + "include\\pros\\distance.h", + "firmware\\libc.a", + "include\\pros\\misc.hpp", + "include\\pros\\error.h", + "include\\pros\\serial.h", + "firmware\\libpros.a", + "include\\pros\\optical.h", + "include\\pros\\optical.hpp", + "include\\pros\\misc.h", + "include\\pros\\imu.h", + "include\\pros\\adi.hpp", + "include\\pros\\link.hpp" + ], + "target": "v5", + "user_files": [ + "include\\main.hpp", + ".gitignore", + "include\\main.h", + "src\\main.cpp", + "Makefile", + "include\\main.hh", + "src\\main.c", + "src\\main.cc" + ], + "version": "4.0.6" }, "liblvgl": { + "location": "/Users/alex/Library/Application Support/PROS/templates/liblvgl@8.3.7", + "metadata": { + "origin": "kernel-beta-mainline" + }, + "name": "liblvgl", "py/object": "pros.conductor.templates.local_template.LocalTemplate", - "py/state": { - "location": "/Users/alex/Library/Application Support/PROS/templates/liblvgl@8.3.6", - "metadata": { - "origin": "kernel-beta-mainline" - }, - "name": "liblvgl", - "supported_kernels": ">=4.0.0", - "system_files": [ - "include\\liblvgl\\draw\\nxp\\vglite\\lv_gpu_nxp_vglite.h", - "include\\liblvgl\\extra\\lv_extra.h", - "include\\liblvgl\\draw\\lv_draw_mask.h", - "include\\liblvgl\\misc\\lv_types.h", - "include\\liblvgl\\widgets\\lv_objx_templ.h", - "include\\liblvgl\\extra\\widgets\\calendar\\lv_calendar.h", - "include\\liblvgl\\extra\\widgets\\tabview\\lv_tabview.h", - "include\\liblvgl\\draw\\stm32_dma2d\\lv_gpu_stm32_dma2d.h", - "include\\liblvgl\\font\\lv_symbol_def.h", - "include\\liblvgl\\misc\\lv_misc.mk", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_rect.h", - "include\\liblvgl\\extra\\themes\\default\\lv_theme_default.h", - "include\\liblvgl\\extra\\widgets\\animimg\\lv_animimg.h", - "include\\liblvgl\\widgets\\lv_btn.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl.mk", - "include\\liblvgl\\extra\\libs\\png\\lv_png.h", - "include\\liblvgl\\extra\\widgets\\imgbtn\\lv_imgbtn.h", - "include\\liblvgl\\misc\\lv_mem.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_mask.h", - "include\\liblvgl\\draw\\sdl\\README.md", - "include\\liblvgl\\core\\lv_obj.h", - "include\\liblvgl\\draw\\sw\\lv_draw_sw_blend.h", - "include\\liblvgl\\extra\\libs\\sjpg\\tjpgd.h", - "include\\liblvgl\\misc\\lv_color.h", - "include\\liblvgl\\draw\\nxp\\lv_draw_nxp.mk", - "include\\liblvgl\\extra\\widgets\\led\\lv_led.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_utils.h", - "include\\liblvgl\\lv_api_map.h", - "include\\liblvgl\\widgets\\lv_slider.h", - "include\\liblvgl\\draw\\nxp\\pxp\\lv_draw_nxp_pxp.mk", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_rect.h", - "include\\liblvgl\\extra\\layouts\\grid\\lv_grid.h", - "include\\liblvgl\\misc\\lv_ll.h", - "include\\liblvgl\\extra\\widgets\\menu\\lv_menu.h", - "include\\liblvgl\\extra\\libs\\rlottie\\lv_rlottie.h", - "include\\liblvgl\\extra\\others\\gridnav\\lv_gridnav.h", - "include\\liblvgl\\widgets\\lv_widgets.mk", - "include\\liblvgl\\extra\\widgets\\calendar\\lv_calendar_header_dropdown.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_layer.h", - "include\\liblvgl\\extra\\widgets\\win\\lv_win.h", - "include\\liblvgl\\extra\\libs\\fsdrv\\lv_fsdrv.h", - "include\\liblvgl\\misc\\lv_utils.h", - "include\\liblvgl\\extra\\widgets\\spinbox\\lv_spinbox.h", - "include\\liblvgl\\draw\\lv_draw_rect.h", - "firmware\\liblvgl.a", - "include\\liblvgl\\draw\\lv_draw_line.h", - "include\\liblvgl\\misc\\lv_math.h", - "include\\liblvgl\\widgets\\lv_bar.h", - "include\\liblvgl\\draw\\swm341_dma2d\\lv_draw_swm341_dma2d.mk", - "include\\liblvgl\\extra\\widgets\\span\\lv_span.h", - "include\\liblvgl\\extra\\lv_extra.mk", - "include\\liblvgl\\widgets\\lv_dropdown.h", - "include\\liblvgl\\lvgl.h", - "include\\liblvgl\\extra\\widgets\\lv_widgets.h", - "include\\liblvgl\\draw\\lv_img_buf.h", - "include\\liblvgl\\widgets\\lv_textarea.h", - "include\\liblvgl\\hal\\lv_hal_tick.h", - "include\\liblvgl\\hal\\lv_hal.mk", - "include\\liblvgl\\hal\\lv_hal_disp.h", - "include\\liblvgl\\draw\\nxp\\pxp\\lv_gpu_nxp_pxp.h", - "include\\liblvgl\\core\\lv_indev_scroll.h", - "include\\liblvgl\\draw\\nxp\\lv_gpu_nxp.h", - "include\\liblvgl\\extra\\layouts\\lv_layouts.h", - "include\\liblvgl\\draw\\lv_img_cache.h", - "include\\liblvgl\\extra\\libs\\qrcode\\lv_qrcode.h", - "include\\liblvgl\\widgets\\lv_roller.h", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_vglite_buf.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl.h", - "include\\liblvgl\\misc\\lv_bidi.h", - "include\\liblvgl\\extra\\widgets\\chart\\lv_chart.h", - "include\\liblvgl\\misc\\lv_log.h", - "include\\liblvgl\\lv_conf_internal.h", - "include\\liblvgl\\extra\\libs\\bmp\\lv_bmp.h", - "include\\liblvgl\\draw\\sw\\lv_draw_sw.mk", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite.h", - "include\\liblvgl\\widgets\\lv_btnmatrix.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_stack_blur.h", - "include\\liblvgl\\draw\\lv_draw_layer.h", - "include\\liblvgl\\core\\lv_refr.h", - "include\\liblvgl\\llemu.hpp", - "include\\liblvgl\\font\\lv_font_loader.h", - "include\\liblvgl\\extra\\themes\\mono\\lv_theme_mono.h", - "include\\liblvgl\\draw\\lv_draw_arc.h", - "include\\liblvgl\\misc\\lv_gc.h", - "include\\liblvgl\\widgets\\lv_img.h", - "include\\liblvgl\\extra\\widgets\\list\\lv_list.h", - "include\\liblvgl\\extra\\layouts\\flex\\lv_flex.h", - "include\\liblvgl\\misc\\lv_tlsf.h", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_blend.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_img.h", - "include\\liblvgl\\misc\\lv_assert.h", - "include\\liblvgl\\misc\\lv_printf.h", - "include\\liblvgl\\draw\\nxp\\pxp\\lv_draw_pxp.h", - "include\\liblvgl\\extra\\README.md", - "include\\liblvgl\\extra\\others\\snapshot\\lv_snapshot.h", - "include\\liblvgl\\misc\\lv_timer.h", - "include\\liblvgl\\misc\\lv_async.h", - "include\\liblvgl\\misc\\lv_anim_timeline.h", - "include\\liblvgl\\extra\\libs\\freetype\\arial.ttf", - "include\\liblvgl\\extra\\libs\\png\\lodepng.h", - "include\\liblvgl\\draw\\arm2d\\lv_draw_arm2d.mk", - "include\\liblvgl\\extra\\themes\\lv_themes.h", - "include\\liblvgl\\extra\\themes\\basic\\lv_theme_basic.h", - "include\\liblvgl\\extra\\widgets\\colorwheel\\lv_colorwheel.h", - "include\\liblvgl\\core\\lv_obj_style_gen.h", - "include\\liblvgl\\font\\lv_font_fmt_txt.h", - "include\\liblvgl\\hal\\lv_hal.h", - "include\\liblvgl\\widgets\\lv_canvas.h", - "include\\liblvgl\\lv_conf.h", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_vglite_utils.h", - "include\\liblvgl\\misc\\lv_area.h", - "include\\liblvgl\\draw\\lv_img_decoder.h", - "include\\liblvgl\\core\\lv_group.h", - "include\\liblvgl\\draw\\lv_draw_triangle.h", - "include\\liblvgl\\extra\\others\\fragment\\README.md", - "include\\liblvgl\\lv_conf_kconfig.h", - "include\\liblvgl\\extra\\widgets\\spinner\\lv_spinner.h", - "include\\liblvgl\\widgets\\lv_checkbox.h", - "include\\liblvgl\\draw\\lv_draw.h", - "include\\liblvgl\\misc\\lv_lru.h", - "include\\liblvgl\\draw\\lv_draw_transform.h", - "include\\liblvgl\\extra\\others\\monkey\\lv_monkey.h", - "include\\liblvgl\\widgets\\lv_table.h", - "include\\liblvgl\\draw\\nxp\\pxp\\lv_gpu_nxp_pxp_osa.h", - "include\\liblvgl\\extra\\others\\imgfont\\lv_imgfont.h", - "include\\liblvgl\\widgets\\lv_label.h", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_arc.h", - "include\\liblvgl\\draw\\stm32_dma2d\\lv_draw_stm32_dma2d.mk", - "include\\liblvgl\\extra\\libs\\ffmpeg\\lv_ffmpeg.h", - "include\\liblvgl\\extra\\others\\ime\\lv_ime_pinyin.h", - "include\\liblvgl\\misc\\lv_txt.h", - "include\\liblvgl\\widgets\\lv_arc.h", - "include\\liblvgl\\extra\\widgets\\meter\\lv_meter.h", - "include\\liblvgl\\font\\lv_font.mk", - "include\\liblvgl\\core\\lv_indev.h", - "include\\liblvgl\\extra\\widgets\\tileview\\lv_tileview.h", - "include\\liblvgl\\draw\\lv_draw_img.h", - "include\\liblvgl\\extra\\others\\lv_others.h", - "include\\liblvgl\\draw\\lv_draw_label.h", - "include\\liblvgl\\draw\\nxp\\pxp\\lv_draw_pxp_blend.h", - "include\\liblvgl\\core\\lv_theme.h", - "include\\liblvgl\\extra\\libs\\gif\\lv_gif.h", - "include\\liblvgl\\extra\\others\\fragment\\lv_fragment.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_texture_cache.h", - "include\\liblvgl\\extra\\libs\\sjpg\\tjpgdcnf.h", - "include\\liblvgl\\extra\\widgets\\msgbox\\lv_msgbox.h", - "include\\liblvgl\\draw\\arm2d\\lv_gpu_arm2d.h", - "include\\liblvgl\\extra\\others\\msg\\lv_msg.h", - "include\\liblvgl\\core\\lv_disp.h", - "include\\liblvgl\\widgets\\lv_line.h", - "include\\liblvgl\\extra\\libs\\gif\\gifdec.h", - "include\\liblvgl\\extra\\libs\\sjpg\\lv_sjpg.h", - "include\\liblvgl\\extra\\libs\\qrcode\\qrcodegen.h", - "include\\liblvgl\\core\\lv_obj_class.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_priv.h", - "include\\liblvgl\\extra\\widgets\\calendar\\lv_calendar_header_arrow.h", - "include\\liblvgl\\misc\\lv_templ.h", - "include\\liblvgl\\core\\lv_obj_draw.h", - "include\\liblvgl\\extra\\libs\\lv_libs.h", - "include\\liblvgl\\widgets\\lv_switch.h", - "include\\liblvgl\\draw\\lv_draw.mk", - "include\\liblvgl\\hal\\lv_hal_indev.h", - "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_composite.h", - "include\\liblvgl\\draw\\sw\\lv_draw_sw_gradient.h", - "include\\liblvgl\\core\\lv_core.mk", - "include\\liblvgl\\draw\\sw\\lv_draw_sw.h", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_nxp_vglite.mk", - "include\\liblvgl\\misc\\lv_style_gen.h", - "include\\liblvgl\\misc\\lv_anim.h", - "include\\liblvgl\\core\\lv_obj_style.h", - "include\\liblvgl\\core\\lv_obj_tree.h", - "include\\liblvgl\\misc\\lv_txt_ap.h", - "include\\liblvgl\\draw\\sw\\lv_draw_sw_dither.h", - "include\\liblvgl\\core\\lv_obj_pos.h", - "include\\liblvgl\\core\\lv_obj_scroll.h", - "include\\liblvgl\\llemu.h", - "include\\liblvgl\\font\\korean.ttf", - "include\\liblvgl\\misc\\lv_style.h", - "include\\liblvgl\\draw\\swm341_dma2d\\lv_gpu_swm341_dma2d.h", - "include\\liblvgl\\font\\lv_font.h", - "include\\liblvgl\\extra\\widgets\\keyboard\\lv_keyboard.h", - "include\\liblvgl\\misc\\lv_fs.h", - "include\\liblvgl\\core\\lv_event.h", - "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_line.h", - "include\\liblvgl\\extra\\libs\\freetype\\lv_freetype.h" - ], - "target": "v5", - "user_files": [], - "version": "8.3.6" - } + "supported_kernels": ">=4.0.0", + "system_files": [ + "include\\liblvgl\\draw\\lv_draw_line.h", + "include\\liblvgl\\draw\\lv_draw_triangle.h", + "include\\liblvgl\\extra\\others\\gridnav\\lv_gridnav.h", + "include\\liblvgl\\extra\\others\\ime\\lv_ime_pinyin.h", + "include\\liblvgl\\widgets\\lv_slider.h", + "include\\liblvgl\\extra\\libs\\freetype\\lv_freetype.h", + "include\\liblvgl\\extra\\widgets\\span\\lv_span.h", + "include\\liblvgl\\misc\\lv_assert.h", + "include\\liblvgl\\misc\\lv_async.h", + "include\\liblvgl\\widgets\\lv_line.h", + "include\\liblvgl\\core\\lv_indev_scroll.h", + "include\\liblvgl\\draw\\sw\\lv_draw_sw_dither.h", + "include\\liblvgl\\extra\\widgets\\spinner\\lv_spinner.h", + "include\\liblvgl\\extra\\others\\monkey\\lv_monkey.h", + "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_blend.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl.h", + "include\\liblvgl\\extra\\libs\\png\\lv_png.h", + "include\\liblvgl\\widgets\\lv_label.h", + "include\\liblvgl\\widgets\\lv_btnmatrix.h", + "include\\liblvgl\\extra\\layouts\\lv_layouts.h", + "include\\liblvgl\\extra\\libs\\gif\\gifdec.h", + "include\\liblvgl\\extra\\widgets\\list\\lv_list.h", + "include\\liblvgl\\draw\\lv_draw_label.h", + "include\\liblvgl\\extra\\others\\snapshot\\lv_snapshot.h", + "include\\liblvgl\\draw\\lv_draw_arc.h", + "include\\liblvgl\\extra\\themes\\lv_themes.h", + "include\\liblvgl\\extra\\widgets\\msgbox\\lv_msgbox.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_layer.h", + "include\\liblvgl\\lv_version.h", + "include\\liblvgl\\font\\lv_font_fmt_txt.h", + "include\\liblvgl\\core\\lv_disp.h", + "include\\liblvgl\\draw\\sw\\lv_draw_sw.h", + "include\\liblvgl\\core\\lv_obj_class.h", + "include\\liblvgl\\extra\\others\\imgfont\\lv_imgfont.h", + "include\\liblvgl\\extra\\themes\\basic\\lv_theme_basic.h", + "include\\liblvgl\\extra\\widgets\\calendar\\lv_calendar.h", + "include\\liblvgl\\misc\\lv_anim.h", + "include\\liblvgl\\misc\\lv_utils.h", + "include\\liblvgl\\misc\\lv_style.h", + "include\\liblvgl\\draw\\nxp\\pxp\\lv_gpu_nxp_pxp.h", + "include\\liblvgl\\widgets\\lv_objx_templ.h", + "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_rect.h", + "include\\liblvgl\\extra\\layouts\\grid\\lv_grid.h", + "include\\liblvgl\\lv_conf_kconfig.h", + "include\\liblvgl\\draw\\lv_img_decoder.h", + "include\\liblvgl\\hal\\lv_hal_disp.h", + "include\\liblvgl\\llemu.hpp", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_priv.h", + "include\\liblvgl\\draw\\sw\\lv_draw_sw_gradient.h", + "include\\liblvgl\\extra\\widgets\\calendar\\lv_calendar_header_arrow.h", + "include\\liblvgl\\extra\\widgets\\calendar\\lv_calendar_header_dropdown.h", + "include\\liblvgl\\core\\lv_obj.h", + "include\\liblvgl\\extra\\libs\\sjpg\\lv_sjpg.h", + "include\\liblvgl\\extra\\widgets\\lv_widgets.h", + "include\\liblvgl\\lvgl.h", + "include\\liblvgl\\draw\\lv_img_buf.h", + "include\\liblvgl\\extra\\widgets\\spinbox\\lv_spinbox.h", + "include\\liblvgl\\draw\\nxp\\vglite\\lv_gpu_nxp_vglite.h", + "include\\liblvgl\\draw\\lv_draw_rect.h", + "include\\liblvgl\\draw\\lv_img_cache.h", + "include\\liblvgl\\extra\\libs\\sjpg\\tjpgd.h", + "include\\liblvgl\\draw\\sw\\lv_draw_sw_blend.h", + "include\\liblvgl\\extra\\others\\fragment\\lv_fragment.h", + "include\\liblvgl\\widgets\\lv_dropdown.h", + "include\\liblvgl\\draw\\lv_draw_layer.h", + "include\\liblvgl\\extra\\libs\\qrcode\\qrcodegen.h", + "include\\liblvgl\\core\\lv_obj_style_gen.h", + "include\\liblvgl\\core\\lv_theme.h", + "include\\liblvgl\\widgets\\lv_arc.h", + "include\\liblvgl\\extra\\widgets\\tileview\\lv_tileview.h", + "include\\liblvgl\\llemu.h", + "include\\liblvgl\\misc\\lv_tlsf.h", + "include\\liblvgl\\misc\\lv_log.h", + "include\\liblvgl\\extra\\libs\\fsdrv\\lv_fsdrv.h", + "include\\liblvgl\\misc\\lv_ll.h", + "include\\liblvgl\\widgets\\lv_btn.h", + "include\\liblvgl\\misc\\lv_area.h", + "include\\liblvgl\\misc\\lv_fs.h", + "include\\liblvgl\\extra\\libs\\gif\\lv_gif.h", + "include\\liblvgl\\misc\\lv_txt_ap.h", + "include\\liblvgl\\draw\\stm32_dma2d\\lv_gpu_stm32_dma2d.h", + "include\\liblvgl\\misc\\lv_style_gen.h", + "include\\liblvgl\\widgets\\lv_canvas.h", + "include\\liblvgl\\font\\lv_font_loader.h", + "firmware\\liblvgl.a", + "include\\liblvgl\\core\\lv_obj_scroll.h", + "include\\liblvgl\\core\\lv_indev.h", + "include\\liblvgl\\extra\\libs\\ffmpeg\\lv_ffmpeg.h", + "include\\liblvgl\\extra\\widgets\\imgbtn\\lv_imgbtn.h", + "include\\liblvgl\\core\\lv_obj_pos.h", + "include\\liblvgl\\core\\lv_obj_style.h", + "include\\liblvgl\\widgets\\lv_table.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_stack_blur.h", + "include\\liblvgl\\lv_conf_internal.h", + "include\\liblvgl\\misc\\lv_timer.h", + "include\\liblvgl\\core\\lv_obj_draw.h", + "include\\liblvgl\\draw\\nxp\\lv_gpu_nxp.h", + "include\\liblvgl\\extra\\widgets\\win\\lv_win.h", + "include\\liblvgl\\extra\\others\\msg\\lv_msg.h", + "include\\liblvgl\\extra\\libs\\lv_libs.h", + "include\\liblvgl\\widgets\\lv_bar.h", + "include\\liblvgl\\extra\\others\\lv_others.h", + "include\\liblvgl\\misc\\lv_math.h", + "include\\liblvgl\\widgets\\lv_img.h", + "include\\liblvgl\\lv_conf_checker.h", + "include\\liblvgl\\misc\\lv_mem.h", + "include\\liblvgl\\widgets\\lv_textarea.h", + "include\\liblvgl\\lv_conf.h", + "include\\liblvgl\\extra\\widgets\\keyboard\\lv_keyboard.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_mask.h", + "include\\liblvgl\\draw\\lv_draw_mask.h", + "include\\liblvgl\\core\\lv_obj_tree.h", + "include\\liblvgl\\extra\\themes\\default\\lv_theme_default.h", + "include\\liblvgl\\extra\\lv_extra.h", + "include\\liblvgl\\extra\\widgets\\colorwheel\\lv_colorwheel.h", + "include\\liblvgl\\core\\lv_group.h", + "include\\liblvgl\\hal\\lv_hal_indev.h", + "include\\liblvgl\\draw\\nxp\\vglite\\lv_draw_vglite_arc.h", + "include\\liblvgl\\draw\\arm2d\\lv_gpu_arm2d.h", + "include\\liblvgl\\widgets\\lv_checkbox.h", + "include\\liblvgl\\draw\\swm341_dma2d\\lv_gpu_swm341_dma2d.h", + "include\\liblvgl\\extra\\themes\\mono\\lv_theme_mono.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_img.h", + "include\\liblvgl\\misc\\lv_bidi.h", + "include\\liblvgl\\misc\\lv_txt.h", + "include\\liblvgl\\extra\\widgets\\led\\lv_led.h", + "include\\liblvgl\\extra\\libs\\rlottie\\lv_rlottie.h", + "include\\liblvgl\\misc\\lv_printf.h", + "include\\liblvgl\\font\\lv_font.h", + "include\\liblvgl\\core\\lv_refr.h", + "include\\liblvgl\\lv_api_map.h", + "include\\liblvgl\\misc\\lv_color.h", + "include\\liblvgl\\misc\\lv_gc.h", + "include\\liblvgl\\misc\\lv_templ.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_composite.h", + "include\\liblvgl\\hal\\lv_hal_tick.h", + "include\\liblvgl\\misc\\lv_types.h", + "include\\liblvgl\\draw\\nxp\\pxp\\lv_draw_pxp_blend.h", + "include\\liblvgl\\draw\\lv_draw.h", + "include\\liblvgl\\extra\\libs\\bmp\\lv_bmp.h", + "include\\liblvgl\\extra\\libs\\qrcode\\lv_qrcode.h", + "include\\liblvgl\\extra\\widgets\\meter\\lv_meter.h", + "include\\liblvgl\\font\\lv_symbol_def.h", + "include\\liblvgl\\extra\\layouts\\flex\\lv_flex.h", + "include\\liblvgl\\widgets\\lv_roller.h", + "include\\liblvgl\\draw\\lv_draw_transform.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_utils.h", + "include\\liblvgl\\lv_conf.old.h", + "include\\liblvgl\\misc\\lv_anim_timeline.h", + "include\\liblvgl\\misc\\lv_lru.h", + "include\\liblvgl\\hal\\lv_hal.h", + "include\\liblvgl\\extra\\libs\\sjpg\\tjpgdcnf.h", + "include\\liblvgl\\extra\\widgets\\tabview\\lv_tabview.h", + "include\\liblvgl\\extra\\widgets\\menu\\lv_menu.h", + "include\\liblvgl\\extra\\widgets\\animimg\\lv_animimg.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_texture_cache.h", + "include\\liblvgl\\draw\\sdl\\lv_draw_sdl_rect.h", + "include\\liblvgl\\extra\\widgets\\chart\\lv_chart.h", + "include\\liblvgl\\core\\lv_event.h", + "include\\liblvgl\\draw\\lv_draw_img.h", + "include\\liblvgl\\widgets\\lv_switch.h", + "include\\liblvgl\\draw\\nxp\\pxp\\lv_gpu_nxp_pxp_osa.h", + "include\\liblvgl\\extra\\libs\\png\\lodepng.h" + ], + "target": "v5", + "user_files": [], + "version": "8.3.7" } }, "upload_options": { diff --git a/src/main.cpp b/src/main.cpp index f9118ad..baeff1b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include "main.h" +#include "robodash/api.h" // ============================= Example autons ============================= // @@ -8,35 +9,36 @@ void good_auton() { std::cout << "Running good auton" << std::endl; } // ================================= Views ================================= // -rd::Selector selector; +// Create robodash selector +rd::Selector selector({ + {"Best auton", &best_auton }, + {"Simple auton", &simple_auton}, + {"Good auton", &good_auton } +}); + +// Create robodash console rd::Console console; // ========================= Competition Functions ========================= // -void initialize() { - selector.add_autons({ - {"Best auton", &best_auton }, - {"Simple auton", &simple_auton}, - {"Good auton", &good_auton } - }); -} +void initialize() {} void disabled() {} void competition_initialize() { - // Focus auton selector + // Focus auton selector on screen selector.focus(); } void autonomous() { - // Run selected autonomous function - selector.do_auton(); + // Run the selected autonomous function + selector.run_auton(); } void opcontrol() { + // Print hello 0-99 to the robodash console for (int i = 0; i < 100; i++) { - console.clear(); - console.printf("Hello %d", i); - pros::delay(500); + console.printf("Hello %d\n", i); + pros::delay(200); } } diff --git a/src/robodash/assets/montserrat_12.c b/src/robodash/assets/montserrat_12.c deleted file mode 100644 index c608e71..0000000 --- a/src/robodash/assets/montserrat_12.c +++ /dev/null @@ -1,792 +0,0 @@ -/******************************************************************************* - * Size: 12 px - * Bpp: 4 - * Opts: - ******************************************************************************/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "liblvgl/lvgl.h" -#endif - -#ifndef MONTSERRAT_12 -#define MONTSERRAT_12 1 -#endif - -#if MONTSERRAT_12 - -/*----------------- - * BITMAPS - *----------------*/ - -/*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { - /* U+0020 " " */ - - /* U+0021 "!" */ - 0xf, 0x40, 0xf3, 0xf, 0x30, 0xf2, 0xe, 0x20, - 0xd1, 0x3, 0x0, 0x92, 0x1e, 0x40, - - /* U+0022 "\"" */ - 0x3c, 0x1e, 0x3b, 0xe, 0x3b, 0xe, 0x15, 0x7, - - /* U+0023 "#" */ - 0x0, 0x48, 0x2, 0xa0, 0x0, 0x6, 0x70, 0x48, - 0x0, 0x4f, 0xff, 0xff, 0xff, 0x10, 0xa, 0x30, - 0x85, 0x0, 0x0, 0xc1, 0xa, 0x30, 0x0, 0xd, - 0x0, 0xc1, 0x0, 0xaf, 0xff, 0xff, 0xfb, 0x0, - 0x1b, 0x0, 0xd0, 0x0, 0x3, 0xa0, 0x1b, 0x0, - 0x0, - - /* U+0024 "$" */ - 0x0, 0x9, 0x20, 0x0, 0x0, 0x92, 0x0, 0x4, - 0xcf, 0xfb, 0x31, 0xf7, 0xa5, 0x74, 0x4e, 0x9, - 0x20, 0x1, 0xf8, 0xb2, 0x0, 0x3, 0xbf, 0xd8, - 0x0, 0x0, 0x97, 0xcb, 0x0, 0x9, 0x24, 0xf5, - 0xb4, 0xa5, 0xbb, 0x8, 0xdf, 0xfa, 0x10, 0x0, - 0x92, 0x0, 0x0, 0x4, 0x10, 0x0, - - /* U+0025 "%" */ - 0xa, 0xb9, 0x0, 0xc, 0x10, 0x66, 0x9, 0x30, - 0x76, 0x0, 0x83, 0x7, 0x52, 0xc0, 0x0, 0x57, - 0xa, 0x2b, 0x20, 0x0, 0x9, 0xc7, 0x68, 0x5c, - 0xa0, 0x0, 0x1, 0xc1, 0xc0, 0x67, 0x0, 0xa, - 0x43, 0x90, 0x2a, 0x0, 0x59, 0x1, 0xb0, 0x48, - 0x0, 0xc1, 0x0, 0x7b, 0xb1, - - /* U+0026 "&" */ - 0x0, 0x9e, 0xe5, 0x0, 0x0, 0x5c, 0x3, 0xe0, - 0x0, 0x5, 0xc0, 0x4c, 0x0, 0x0, 0xc, 0xbd, - 0x20, 0x0, 0x3, 0xde, 0x70, 0x10, 0x2, 0xe2, - 0x1d, 0x67, 0x80, 0x6b, 0x0, 0x2e, 0xf3, 0x4, - 0xf4, 0x13, 0xcf, 0x50, 0x6, 0xef, 0xd7, 0x2b, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+0027 "'" */ - 0x3c, 0x3b, 0x3b, 0x15, - - /* U+0028 "(" */ - 0xa, 0x71, 0xf1, 0x6c, 0x9, 0x80, 0xb6, 0xd, - 0x40, 0xd4, 0xd, 0x40, 0xb6, 0x9, 0x80, 0x6b, - 0x1, 0xf1, 0xa, 0x70, - - /* U+0029 ")" */ - 0x6b, 0x0, 0xf2, 0xb, 0x70, 0x7a, 0x5, 0xc0, - 0x4e, 0x3, 0xe0, 0x4e, 0x5, 0xc0, 0x7a, 0xb, - 0x70, 0xf2, 0x6b, 0x0, - - /* U+002A "*" */ - 0x0, 0xb0, 0x8, 0x9c, 0xb5, 0xb, 0xf9, 0x8, - 0x7c, 0x95, 0x0, 0xa0, 0x0, - - /* U+002B "+" */ - 0x0, 0x6, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, - 0xf, 0x0, 0x3, 0xee, 0xfe, 0xe2, 0x1, 0x2f, - 0x11, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x9, 0x0, - 0x0, - - /* U+002C "," */ - 0x2a, 0x4, 0xf1, 0xd, 0x4, 0x80, - - /* U+002D "-" */ - 0x4f, 0xfd, 0x2, 0x22, - - /* U+002E "." */ - 0x3b, 0x4, 0xe1, - - /* U+002F "/" */ - 0x0, 0x0, 0x34, 0x0, 0x0, 0xb5, 0x0, 0x0, - 0xf1, 0x0, 0x5, 0xb0, 0x0, 0xa, 0x60, 0x0, - 0xe, 0x10, 0x0, 0x4c, 0x0, 0x0, 0x97, 0x0, - 0x0, 0xe2, 0x0, 0x3, 0xd0, 0x0, 0x8, 0x70, - 0x0, 0xd, 0x20, 0x0, 0x2d, 0x0, 0x0, - - /* U+0030 "0" */ - 0x0, 0x9f, 0xf9, 0x0, 0xa, 0xc4, 0x4c, 0xa0, - 0x2f, 0x20, 0x2, 0xf2, 0x5d, 0x0, 0x0, 0xd5, - 0x6c, 0x0, 0x0, 0xc6, 0x5d, 0x0, 0x0, 0xd5, - 0x2f, 0x20, 0x2, 0xf2, 0xa, 0xc4, 0x4c, 0xa0, - 0x0, 0x9f, 0xf9, 0x0, - - /* U+0031 "1" */ - 0xef, 0xf3, 0x22, 0xf3, 0x0, 0xf3, 0x0, 0xf3, - 0x0, 0xf3, 0x0, 0xf3, 0x0, 0xf3, 0x0, 0xf3, - 0x0, 0xf3, - - /* U+0032 "2" */ - 0x1a, 0xef, 0xc3, 0x9, 0xa4, 0x3a, 0xe0, 0x0, - 0x0, 0x1f, 0x10, 0x0, 0x4, 0xe0, 0x0, 0x2, - 0xe6, 0x0, 0x1, 0xd8, 0x0, 0x1, 0xd8, 0x0, - 0x1, 0xda, 0x22, 0x21, 0x8f, 0xff, 0xff, 0x70, - - /* U+0033 "3" */ - 0x9f, 0xff, 0xff, 0x1, 0x22, 0x4e, 0x60, 0x0, - 0x1d, 0x60, 0x0, 0x9, 0xfb, 0x30, 0x0, 0x12, - 0x9e, 0x0, 0x0, 0x0, 0xe4, 0x10, 0x0, 0xf, - 0x4c, 0x94, 0x3a, 0xe0, 0x3b, 0xff, 0xc3, 0x0, - - /* U+0034 "4" */ - 0x0, 0x0, 0x9b, 0x0, 0x0, 0x4, 0xe1, 0x0, - 0x0, 0x1e, 0x50, 0x0, 0x0, 0xaa, 0x0, 0x0, - 0x5, 0xe1, 0xd, 0x40, 0x1e, 0x40, 0xd, 0x40, - 0x8f, 0xff, 0xff, 0xfd, 0x12, 0x22, 0x2e, 0x62, - 0x0, 0x0, 0xe, 0x40, - - /* U+0035 "5" */ - 0xc, 0xff, 0xff, 0x0, 0xe5, 0x22, 0x20, 0xf, - 0x10, 0x0, 0x1, 0xff, 0xfc, 0x40, 0x2, 0x23, - 0x8f, 0x20, 0x0, 0x0, 0xd6, 0x0, 0x0, 0xd, - 0x69, 0xa4, 0x38, 0xf1, 0x2a, 0xef, 0xd4, 0x0, - - /* U+0036 "6" */ - 0x0, 0x7d, 0xfe, 0x50, 0x8, 0xd5, 0x23, 0x20, - 0x1f, 0x20, 0x0, 0x0, 0x5d, 0x6d, 0xea, 0x10, - 0x6f, 0xc3, 0x3b, 0xb0, 0x5f, 0x20, 0x2, 0xf0, - 0x2f, 0x20, 0x2, 0xf0, 0xb, 0xb2, 0x2b, 0xb0, - 0x1, 0xaf, 0xfa, 0x10, - - /* U+0037 "7" */ - 0xaf, 0xff, 0xff, 0xba, 0x92, 0x22, 0xd7, 0x76, - 0x0, 0x3f, 0x10, 0x0, 0xa, 0x90, 0x0, 0x1, - 0xf3, 0x0, 0x0, 0x7c, 0x0, 0x0, 0xe, 0x50, - 0x0, 0x5, 0xe0, 0x0, 0x0, 0xc8, 0x0, 0x0, - - /* U+0038 "8" */ - 0x3, 0xcf, 0xfa, 0x10, 0xe, 0x81, 0x2c, 0xa0, - 0x2f, 0x0, 0x5, 0xe0, 0xe, 0x60, 0xa, 0xa0, - 0x8, 0xff, 0xff, 0x40, 0x3f, 0x30, 0x7, 0xe0, - 0x7c, 0x0, 0x0, 0xf2, 0x3f, 0x61, 0x29, 0xe0, - 0x5, 0xdf, 0xfb, 0x20, - - /* U+0039 "9" */ - 0x7, 0xef, 0xc4, 0x6, 0xe4, 0x15, 0xe2, 0xa8, - 0x0, 0xa, 0x97, 0xd1, 0x3, 0xec, 0xa, 0xff, - 0xd9, 0xd0, 0x0, 0x10, 0x7b, 0x0, 0x0, 0xd, - 0x70, 0x52, 0x3b, 0xe0, 0x1c, 0xff, 0xa1, 0x0, - - /* U+003A ":" */ - 0x4e, 0x13, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0xb0, 0x4e, 0x10, - - /* U+003B ";" */ - 0x4e, 0x13, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xa0, 0x4f, 0x10, 0xd0, 0x48, 0x0, - - /* U+003C "<" */ - 0x0, 0x0, 0x2, 0x10, 0x0, 0x4b, 0xe2, 0x7, - 0xdc, 0x50, 0x3, 0xf8, 0x0, 0x0, 0x4, 0xbe, - 0x71, 0x0, 0x0, 0x29, 0xe2, 0x0, 0x0, 0x0, - 0x0, - - /* U+003D "=" */ - 0x3f, 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xee, 0xee, 0xe2, 0x1, 0x11, - 0x11, 0x0, - - /* U+003E ">" */ - 0x12, 0x0, 0x0, 0x2, 0xeb, 0x40, 0x0, 0x0, - 0x5c, 0xd7, 0x0, 0x0, 0x8, 0xf3, 0x1, 0x7e, - 0xb4, 0x2, 0xe9, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+003F "?" */ - 0x1a, 0xff, 0xc3, 0x9, 0xa3, 0x2a, 0xe0, 0x0, - 0x0, 0x3f, 0x0, 0x0, 0xa, 0xa0, 0x0, 0x9, - 0xc0, 0x0, 0x2, 0xf1, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x2, 0x90, 0x0, 0x0, 0x4e, 0x0, 0x0, - - /* U+0040 "@" */ - 0x0, 0x5, 0xbd, 0xdd, 0x91, 0x0, 0x0, 0xab, - 0x20, 0x0, 0x5d, 0x30, 0x7, 0x90, 0x0, 0x0, - 0x1, 0xd1, 0xe, 0x0, 0x9e, 0xe8, 0xd3, 0x67, - 0x4a, 0x9, 0xb1, 0x7, 0xf3, 0x1b, 0x67, 0xe, - 0x20, 0x0, 0xe3, 0xd, 0x67, 0xe, 0x30, 0x0, - 0xe3, 0xc, 0x4a, 0x9, 0xc1, 0x8, 0xf5, 0x68, - 0xd, 0x0, 0x9f, 0xf9, 0x6f, 0xc1, 0x7, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xab, 0x20, 0x1, - 0x40, 0x0, 0x0, 0x5, 0xce, 0xed, 0x60, 0x0, - - /* U+0041 "A" */ - 0x0, 0x0, 0x6f, 0x30, 0x0, 0x0, 0x0, 0xdd, - 0x90, 0x0, 0x0, 0x4, 0xe2, 0xf1, 0x0, 0x0, - 0xb, 0x70, 0xb7, 0x0, 0x0, 0x2f, 0x10, 0x5e, - 0x0, 0x0, 0x8a, 0x0, 0xe, 0x40, 0x0, 0xef, - 0xee, 0xef, 0xb0, 0x6, 0xd1, 0x11, 0x13, 0xf2, - 0xc, 0x60, 0x0, 0x0, 0xa9, - - /* U+0042 "B" */ - 0xbf, 0xff, 0xfc, 0x20, 0xb7, 0x11, 0x2a, 0xd0, - 0xb7, 0x0, 0x2, 0xf0, 0xb7, 0x0, 0x8, 0xc0, - 0xbf, 0xff, 0xff, 0x50, 0xb8, 0x22, 0x26, 0xf3, - 0xb7, 0x0, 0x0, 0xc7, 0xb7, 0x11, 0x15, 0xf4, - 0xbf, 0xff, 0xfd, 0x70, - - /* U+0043 "C" */ - 0x0, 0x3b, 0xff, 0xc4, 0x0, 0x5f, 0x93, 0x38, - 0xe0, 0xe, 0x60, 0x0, 0x0, 0x5, 0xe0, 0x0, - 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x5, 0xe0, - 0x0, 0x0, 0x0, 0xe, 0x60, 0x0, 0x0, 0x0, - 0x5f, 0x83, 0x38, 0xe0, 0x0, 0x4b, 0xff, 0xb3, - 0x0, - - /* U+0044 "D" */ - 0xbf, 0xff, 0xfb, 0x30, 0xb, 0x82, 0x23, 0x9f, - 0x40, 0xb7, 0x0, 0x0, 0x7e, 0xb, 0x70, 0x0, - 0x0, 0xf3, 0xb7, 0x0, 0x0, 0xd, 0x5b, 0x70, - 0x0, 0x0, 0xf3, 0xb7, 0x0, 0x0, 0x7e, 0xb, - 0x82, 0x23, 0x9f, 0x40, 0xbf, 0xff, 0xfb, 0x30, - 0x0, - - /* U+0045 "E" */ - 0xbf, 0xff, 0xff, 0x3b, 0x82, 0x22, 0x20, 0xb7, - 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0xbf, 0xff, - 0xfa, 0xb, 0x82, 0x22, 0x10, 0xb7, 0x0, 0x0, - 0xb, 0x82, 0x22, 0x20, 0xbf, 0xff, 0xff, 0x50, - - /* U+0046 "F" */ - 0xbf, 0xff, 0xff, 0x3b, 0x82, 0x22, 0x20, 0xb7, - 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0xbf, 0xff, - 0xfa, 0xb, 0x82, 0x22, 0x10, 0xb7, 0x0, 0x0, - 0xb, 0x70, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, - - /* U+0047 "G" */ - 0x0, 0x3b, 0xff, 0xc4, 0x0, 0x5f, 0x93, 0x37, - 0xe1, 0xe, 0x60, 0x0, 0x0, 0x5, 0xe0, 0x0, - 0x0, 0x0, 0x6c, 0x0, 0x0, 0x8, 0x25, 0xe0, - 0x0, 0x0, 0xe3, 0xe, 0x60, 0x0, 0xe, 0x30, - 0x5f, 0x93, 0x37, 0xf3, 0x0, 0x3b, 0xff, 0xc5, - 0x0, - - /* U+0048 "H" */ - 0xb7, 0x0, 0x0, 0xb7, 0xb7, 0x0, 0x0, 0xb7, - 0xb7, 0x0, 0x0, 0xb7, 0xb7, 0x0, 0x0, 0xb7, - 0xbf, 0xff, 0xff, 0xf7, 0xb8, 0x22, 0x22, 0xc7, - 0xb7, 0x0, 0x0, 0xb7, 0xb7, 0x0, 0x0, 0xb7, - 0xb7, 0x0, 0x0, 0xb7, - - /* U+0049 "I" */ - 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, - 0xb7, - - /* U+004A "J" */ - 0x4, 0xff, 0xff, 0x0, 0x22, 0x5f, 0x0, 0x0, - 0x3f, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x3f, 0x0, - 0x0, 0x3f, 0x0, 0x0, 0x4f, 0xd, 0x52, 0xbb, - 0x5, 0xdf, 0xc2, - - /* U+004B "K" */ - 0xb7, 0x0, 0x7, 0xd1, 0xb7, 0x0, 0x5e, 0x20, - 0xb7, 0x4, 0xf3, 0x0, 0xb7, 0x3e, 0x40, 0x0, - 0xb9, 0xef, 0x30, 0x0, 0xbf, 0x89, 0xd1, 0x0, - 0xba, 0x0, 0xcb, 0x0, 0xb7, 0x0, 0x1e, 0x70, - 0xb7, 0x0, 0x3, 0xf3, - - /* U+004C "L" */ - 0xb7, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0xb7, - 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0xb7, 0x0, - 0x0, 0xb, 0x70, 0x0, 0x0, 0xb7, 0x0, 0x0, - 0xb, 0x82, 0x22, 0x20, 0xbf, 0xff, 0xff, 0x0, - - /* U+004D "M" */ - 0xb8, 0x0, 0x0, 0x1, 0xf3, 0xbf, 0x10, 0x0, - 0x9, 0xf3, 0xbf, 0xa0, 0x0, 0x2e, 0xf3, 0xb7, - 0xf3, 0x0, 0xb7, 0xf3, 0xb6, 0x7b, 0x4, 0xe0, - 0xf3, 0xb6, 0xe, 0x4c, 0x50, 0xf3, 0xb6, 0x5, - 0xfc, 0x0, 0xf3, 0xb6, 0x0, 0xb3, 0x0, 0xf3, - 0xb6, 0x0, 0x0, 0x0, 0xf3, - - /* U+004E "N" */ - 0xb9, 0x0, 0x0, 0xb7, 0xbf, 0x50, 0x0, 0xb7, - 0xbc, 0xf2, 0x0, 0xb7, 0xb7, 0x9c, 0x0, 0xb7, - 0xb7, 0xc, 0x90, 0xb7, 0xb7, 0x2, 0xf5, 0xb7, - 0xb7, 0x0, 0x5e, 0xd7, 0xb7, 0x0, 0x9, 0xf7, - 0xb7, 0x0, 0x0, 0xd7, - - /* U+004F "O" */ - 0x0, 0x3b, 0xff, 0xc4, 0x0, 0x5, 0xf8, 0x33, - 0x8f, 0x60, 0xe, 0x60, 0x0, 0x5, 0xf1, 0x4e, - 0x0, 0x0, 0x0, 0xd6, 0x6c, 0x0, 0x0, 0x0, - 0xb7, 0x4e, 0x0, 0x0, 0x0, 0xd6, 0xe, 0x60, - 0x0, 0x5, 0xf1, 0x5, 0xf8, 0x33, 0x8f, 0x60, - 0x0, 0x3b, 0xff, 0xc4, 0x0, - - /* U+0050 "P" */ - 0xbf, 0xff, 0xe9, 0x0, 0xb8, 0x22, 0x4d, 0xa0, - 0xb7, 0x0, 0x4, 0xf0, 0xb7, 0x0, 0x3, 0xf0, - 0xb7, 0x0, 0x1b, 0xb0, 0xbf, 0xff, 0xfb, 0x10, - 0xb8, 0x22, 0x10, 0x0, 0xb7, 0x0, 0x0, 0x0, - 0xb7, 0x0, 0x0, 0x0, - - /* U+0051 "Q" */ - 0x0, 0x3b, 0xff, 0xc4, 0x0, 0x5, 0xf8, 0x33, - 0x8f, 0x60, 0xe, 0x60, 0x0, 0x5, 0xf1, 0x4e, - 0x0, 0x0, 0x0, 0xd6, 0x6c, 0x0, 0x0, 0x0, - 0xb7, 0x4e, 0x0, 0x0, 0x0, 0xd6, 0xe, 0x60, - 0x0, 0x5, 0xf1, 0x5, 0xf8, 0x33, 0x8f, 0x60, - 0x0, 0x3b, 0xff, 0xc4, 0x0, 0x0, 0x0, 0xd, - 0xa0, 0x28, 0x0, 0x0, 0x1, 0xbf, 0xf6, 0x0, - 0x0, 0x0, 0x1, 0x0, - - /* U+0052 "R" */ - 0xbf, 0xff, 0xe9, 0x0, 0xb8, 0x22, 0x4d, 0xa0, - 0xb7, 0x0, 0x4, 0xf0, 0xb7, 0x0, 0x3, 0xf0, - 0xb7, 0x0, 0x1b, 0xb0, 0xbf, 0xff, 0xfb, 0x10, - 0xb8, 0x22, 0xb9, 0x0, 0xb7, 0x0, 0x1f, 0x30, - 0xb7, 0x0, 0x7, 0xd0, - - /* U+0053 "S" */ - 0x4, 0xcf, 0xfb, 0x31, 0xf7, 0x22, 0x74, 0x4e, - 0x0, 0x0, 0x1, 0xf8, 0x20, 0x0, 0x3, 0xbf, - 0xd8, 0x0, 0x0, 0x4, 0xcb, 0x0, 0x0, 0x4, - 0xf5, 0xb4, 0x23, 0xbb, 0x8, 0xdf, 0xea, 0x10, - - /* U+0054 "T" */ - 0xff, 0xff, 0xff, 0xf2, 0x23, 0xf3, 0x22, 0x0, - 0x1f, 0x10, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1f, - 0x10, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1f, 0x10, - 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1f, 0x10, 0x0, - - /* U+0055 "U" */ - 0xd6, 0x0, 0x0, 0xe4, 0xd6, 0x0, 0x0, 0xe4, - 0xd6, 0x0, 0x0, 0xe4, 0xd6, 0x0, 0x0, 0xe4, - 0xd6, 0x0, 0x0, 0xe4, 0xc6, 0x0, 0x0, 0xe4, - 0xaa, 0x0, 0x2, 0xf1, 0x3f, 0x83, 0x4d, 0xb0, - 0x4, 0xcf, 0xe9, 0x0, - - /* U+0056 "V" */ - 0xc, 0x70, 0x0, 0x0, 0xd5, 0x6, 0xe0, 0x0, - 0x4, 0xe0, 0x0, 0xf4, 0x0, 0xa, 0x80, 0x0, - 0x9b, 0x0, 0x1f, 0x20, 0x0, 0x2f, 0x20, 0x7b, - 0x0, 0x0, 0xc, 0x80, 0xe4, 0x0, 0x0, 0x5, - 0xe5, 0xe0, 0x0, 0x0, 0x0, 0xef, 0x70, 0x0, - 0x0, 0x0, 0x8f, 0x10, 0x0, - - /* U+0057 "W" */ - 0x7c, 0x0, 0x0, 0xe8, 0x0, 0x2, 0xf0, 0x2f, - 0x10, 0x3, 0xfd, 0x0, 0x7, 0xa0, 0xd, 0x60, - 0x8, 0x9f, 0x20, 0xc, 0x50, 0x8, 0xb0, 0xe, - 0x3b, 0x70, 0x1f, 0x0, 0x3, 0xf0, 0x3e, 0x6, - 0xc0, 0x6b, 0x0, 0x0, 0xe5, 0x89, 0x1, 0xf1, - 0xb6, 0x0, 0x0, 0x9a, 0xd4, 0x0, 0xb7, 0xf1, - 0x0, 0x0, 0x4f, 0xe0, 0x0, 0x6f, 0xc0, 0x0, - 0x0, 0xf, 0xa0, 0x0, 0x1f, 0x70, 0x0, - - /* U+0058 "X" */ - 0x5f, 0x10, 0x0, 0xe5, 0xa, 0xb0, 0x9, 0xa0, - 0x1, 0xe6, 0x4e, 0x10, 0x0, 0x4f, 0xe5, 0x0, - 0x0, 0xd, 0xe0, 0x0, 0x0, 0x7d, 0xd8, 0x0, - 0x2, 0xf3, 0x3f, 0x30, 0xc, 0x80, 0x7, 0xd0, - 0x8d, 0x0, 0x0, 0xc9, - - /* U+0059 "Y" */ - 0xc, 0x80, 0x0, 0xa, 0x80, 0x3f, 0x10, 0x3, - 0xe0, 0x0, 0xaa, 0x0, 0xc6, 0x0, 0x1, 0xf3, - 0x5d, 0x0, 0x0, 0x7, 0xce, 0x40, 0x0, 0x0, - 0xe, 0xb0, 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, - 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, 0xb7, 0x0, - 0x0, - - /* U+005A "Z" */ - 0x6f, 0xff, 0xff, 0xf5, 0x2, 0x22, 0x29, 0xd0, - 0x0, 0x0, 0x4f, 0x30, 0x0, 0x1, 0xe6, 0x0, - 0x0, 0xc, 0xa0, 0x0, 0x0, 0x8d, 0x0, 0x0, - 0x4, 0xf3, 0x0, 0x0, 0x1e, 0x82, 0x22, 0x21, - 0x7f, 0xff, 0xff, 0xf8, - - /* U+005B "[" */ - 0xbf, 0xcb, 0x60, 0xb6, 0xb, 0x60, 0xb6, 0xb, - 0x60, 0xb6, 0xb, 0x60, 0xb6, 0xb, 0x60, 0xb6, - 0xb, 0x60, 0xbf, 0xc0, - - /* U+005C "\\" */ - 0x35, 0x0, 0x0, 0x2e, 0x0, 0x0, 0xd, 0x30, - 0x0, 0x8, 0x80, 0x0, 0x3, 0xd0, 0x0, 0x0, - 0xd2, 0x0, 0x0, 0x87, 0x0, 0x0, 0x3c, 0x0, - 0x0, 0xe, 0x10, 0x0, 0x9, 0x70, 0x0, 0x4, - 0xc0, 0x0, 0x0, 0xf1, 0x0, 0x0, 0xa6, - - /* U+005D "]" */ - 0xcf, 0xb0, 0x7b, 0x6, 0xb0, 0x6b, 0x6, 0xb0, - 0x6b, 0x6, 0xb0, 0x6b, 0x6, 0xb0, 0x6b, 0x6, - 0xb0, 0x7b, 0xcf, 0xb0, - - /* U+005E "^" */ - 0x0, 0x8, 0x0, 0x0, 0x5, 0xf5, 0x0, 0x0, - 0xb5, 0xc0, 0x0, 0x2c, 0xc, 0x20, 0x8, 0x60, - 0x68, 0x0, 0xd0, 0x0, 0xd0, - - /* U+005F "_" */ - 0xdd, 0xdd, 0xdd, - - /* U+0060 "`" */ - 0x27, 0x10, 0x5, 0xc1, - - /* U+0061 "a" */ - 0x8, 0xef, 0xd3, 0x0, 0x93, 0x28, 0xe0, 0x0, - 0x0, 0xf, 0x10, 0x9d, 0xee, 0xf2, 0x4e, 0x10, - 0xf, 0x25, 0xd0, 0x7, 0xf2, 0x9, 0xee, 0x9f, - 0x20, - - /* U+0062 "b" */ - 0xe4, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0xe4, - 0x0, 0x0, 0xe, 0x7d, 0xfd, 0x40, 0xee, 0x41, - 0x7f, 0x2e, 0x60, 0x0, 0xa9, 0xe4, 0x0, 0x7, - 0xae, 0x60, 0x0, 0xa9, 0xee, 0x41, 0x7f, 0x2e, - 0x6d, 0xfd, 0x40, - - /* U+0063 "c" */ - 0x2, 0xbf, 0xe8, 0x0, 0xe9, 0x23, 0xd3, 0x5d, - 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x5d, 0x0, - 0x0, 0x0, 0xe9, 0x23, 0xc3, 0x2, 0xbf, 0xe8, - 0x0, - - /* U+0064 "d" */ - 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1, 0xf1, - 0x0, 0x0, 0x1, 0xf1, 0x2, 0xcf, 0xe6, 0xf1, - 0xe, 0x92, 0x3d, 0xf1, 0x6d, 0x0, 0x3, 0xf1, - 0x7a, 0x0, 0x0, 0xf1, 0x6d, 0x0, 0x3, 0xf1, - 0xe, 0x92, 0x3d, 0xf1, 0x2, 0xcf, 0xe6, 0xf1, - - /* U+0065 "e" */ - 0x2, 0xcf, 0xe6, 0x0, 0xe7, 0x14, 0xe4, 0x6c, - 0x0, 0x6, 0xb7, 0xfd, 0xdd, 0xdc, 0x5d, 0x0, - 0x0, 0x0, 0xe9, 0x22, 0x92, 0x2, 0xbf, 0xf9, - 0x0, - - /* U+0066 "f" */ - 0x2, 0xdf, 0x70, 0x99, 0x11, 0xb, 0x60, 0xd, - 0xff, 0xf3, 0xb, 0x60, 0x0, 0xb6, 0x0, 0xb, - 0x60, 0x0, 0xb6, 0x0, 0xb, 0x60, 0x0, 0xb6, - 0x0, - - /* U+0067 "g" */ - 0x2, 0xbf, 0xe6, 0xe2, 0xe, 0x91, 0x2c, 0xf2, - 0x6d, 0x0, 0x2, 0xf2, 0x7b, 0x0, 0x0, 0xf2, - 0x5d, 0x0, 0x2, 0xf2, 0xe, 0xa2, 0x3d, 0xf2, - 0x2, 0xbf, 0xe6, 0xf2, 0x0, 0x0, 0x1, 0xf1, - 0xc, 0x52, 0x2b, 0xb0, 0x6, 0xdf, 0xfa, 0x10, - - /* U+0068 "h" */ - 0xe4, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0xe4, - 0x0, 0x0, 0xe, 0x8d, 0xfd, 0x30, 0xee, 0x42, - 0xad, 0xe, 0x60, 0x1, 0xf1, 0xe4, 0x0, 0xf, - 0x2e, 0x40, 0x0, 0xf2, 0xe4, 0x0, 0xf, 0x2e, - 0x40, 0x0, 0xf2, - - /* U+0069 "i" */ - 0xe, 0x50, 0x82, 0x0, 0x0, 0xe4, 0xe, 0x40, - 0xe4, 0xe, 0x40, 0xe4, 0xe, 0x40, 0xe4, - - /* U+006A "j" */ - 0x0, 0xe, 0x50, 0x0, 0x83, 0x0, 0x0, 0x0, - 0x0, 0xd4, 0x0, 0xd, 0x40, 0x0, 0xd4, 0x0, - 0xd, 0x40, 0x0, 0xd4, 0x0, 0xd, 0x40, 0x0, - 0xd4, 0x0, 0xd, 0x40, 0x22, 0xf2, 0xd, 0xf9, - 0x0, - - /* U+006B "k" */ - 0xe4, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0xe4, - 0x0, 0x0, 0xe, 0x40, 0xb, 0xa0, 0xe4, 0xb, - 0xb0, 0xe, 0x4b, 0xc0, 0x0, 0xee, 0xfd, 0x0, - 0xe, 0xc1, 0xd9, 0x0, 0xe4, 0x2, 0xf4, 0xe, - 0x40, 0x6, 0xe1, - - /* U+006C "l" */ - 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, - 0xe4, 0xe4, - - /* U+006D "m" */ - 0xe7, 0xdf, 0xb2, 0x9e, 0xf9, 0xe, 0xe4, 0x2c, - 0xfb, 0x24, 0xe6, 0xe6, 0x0, 0x4f, 0x10, 0x9, - 0x9e, 0x40, 0x3, 0xf0, 0x0, 0x8a, 0xe4, 0x0, - 0x3f, 0x0, 0x8, 0xae, 0x40, 0x3, 0xf0, 0x0, - 0x8a, 0xe4, 0x0, 0x3f, 0x0, 0x8, 0xa0, - - /* U+006E "n" */ - 0xe7, 0xdf, 0xd3, 0xe, 0xe4, 0x2a, 0xd0, 0xe6, - 0x0, 0x1f, 0x1e, 0x40, 0x0, 0xf2, 0xe4, 0x0, - 0xf, 0x2e, 0x40, 0x0, 0xf2, 0xe4, 0x0, 0xf, - 0x20, - - /* U+006F "o" */ - 0x2, 0xbf, 0xe8, 0x0, 0xe, 0x92, 0x3d, 0x90, - 0x5d, 0x0, 0x3, 0xf0, 0x7a, 0x0, 0x0, 0xf1, - 0x5d, 0x0, 0x3, 0xf0, 0xe, 0x92, 0x3d, 0x80, - 0x2, 0xbf, 0xe8, 0x0, - - /* U+0070 "p" */ - 0xe7, 0xdf, 0xd4, 0xe, 0xe4, 0x17, 0xf2, 0xe6, - 0x0, 0xa, 0x9e, 0x40, 0x0, 0x7a, 0xe6, 0x0, - 0xa, 0x9e, 0xe4, 0x17, 0xf2, 0xe7, 0xdf, 0xd4, - 0xe, 0x40, 0x0, 0x0, 0xe4, 0x0, 0x0, 0xe, - 0x40, 0x0, 0x0, - - /* U+0071 "q" */ - 0x2, 0xcf, 0xe6, 0xf1, 0xe, 0x92, 0x3d, 0xf1, - 0x6d, 0x0, 0x3, 0xf1, 0x7a, 0x0, 0x0, 0xf1, - 0x6d, 0x0, 0x3, 0xf1, 0xe, 0x92, 0x3d, 0xf1, - 0x2, 0xcf, 0xe6, 0xf1, 0x0, 0x0, 0x1, 0xf1, - 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1, 0xf1, - - /* U+0072 "r" */ - 0xe7, 0xd8, 0xee, 0x51, 0xe6, 0x0, 0xe4, 0x0, - 0xe4, 0x0, 0xe4, 0x0, 0xe4, 0x0, - - /* U+0073 "s" */ - 0x9, 0xff, 0xc3, 0x6d, 0x21, 0x61, 0x7d, 0x20, - 0x0, 0xa, 0xfe, 0xa1, 0x0, 0x2, 0xb9, 0x56, - 0x22, 0xb8, 0x4c, 0xff, 0xa1, - - /* U+0074 "t" */ - 0x5, 0x30, 0x0, 0xb6, 0x0, 0xdf, 0xff, 0x30, - 0xb6, 0x0, 0xb, 0x60, 0x0, 0xb6, 0x0, 0xb, - 0x60, 0x0, 0xaa, 0x11, 0x2, 0xdf, 0x70, - - /* U+0075 "u" */ - 0xf3, 0x0, 0x2f, 0xf, 0x30, 0x2, 0xf0, 0xf3, - 0x0, 0x2f, 0xf, 0x30, 0x2, 0xf0, 0xe4, 0x0, - 0x4f, 0xa, 0xc3, 0x3d, 0xf0, 0x1b, 0xfe, 0x6f, - 0x0, - - /* U+0076 "v" */ - 0xd, 0x50, 0x0, 0x98, 0x6, 0xc0, 0x0, 0xf2, - 0x1, 0xf2, 0x6, 0xb0, 0x0, 0xa8, 0xc, 0x50, - 0x0, 0x3e, 0x3e, 0x0, 0x0, 0xd, 0xd8, 0x0, - 0x0, 0x6, 0xf2, 0x0, - - /* U+0077 "w" */ - 0xc5, 0x0, 0x3f, 0x10, 0x7, 0x86, 0xa0, 0x9, - 0xf6, 0x0, 0xd3, 0x1f, 0x0, 0xe7, 0xc0, 0x2d, - 0x0, 0xb5, 0x4c, 0xe, 0x18, 0x80, 0x6, 0xa9, - 0x60, 0xa6, 0xd3, 0x0, 0x1e, 0xe1, 0x4, 0xed, - 0x0, 0x0, 0xbb, 0x0, 0xe, 0x80, 0x0, - - /* U+0078 "x" */ - 0x5d, 0x0, 0x4e, 0x10, 0xa9, 0x1e, 0x40, 0x1, - 0xec, 0x90, 0x0, 0x8, 0xf1, 0x0, 0x2, 0xeb, - 0xb0, 0x0, 0xc7, 0xd, 0x60, 0x7c, 0x0, 0x3f, - 0x20, - - /* U+0079 "y" */ - 0xd, 0x50, 0x0, 0x98, 0x7, 0xb0, 0x0, 0xe2, - 0x1, 0xf2, 0x5, 0xc0, 0x0, 0xa8, 0xb, 0x50, - 0x0, 0x4d, 0x1e, 0x0, 0x0, 0xe, 0xb9, 0x0, - 0x0, 0x8, 0xf3, 0x0, 0x0, 0x5, 0xd0, 0x0, - 0x5, 0x1c, 0x60, 0x0, 0x1d, 0xfa, 0x0, 0x0, - - /* U+007A "z" */ - 0x7f, 0xff, 0xfb, 0x0, 0x2, 0xf3, 0x0, 0xc, - 0x70, 0x0, 0x8b, 0x0, 0x4, 0xe1, 0x0, 0x1e, - 0x50, 0x0, 0x8f, 0xff, 0xfd, - - /* U+007B "{" */ - 0x0, 0xbf, 0x4, 0xe1, 0x5, 0xc0, 0x5, 0xc0, - 0x5, 0xc0, 0x6, 0xc0, 0x4f, 0x70, 0x7, 0xc0, - 0x5, 0xc0, 0x5, 0xc0, 0x5, 0xc0, 0x4, 0xe1, - 0x0, 0xbf, - - /* U+007C "|" */ - 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, - 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, - - /* U+007D "}" */ - 0xcd, 0x20, 0xb, 0x80, 0x9, 0x90, 0x9, 0x90, - 0x9, 0x90, 0x8, 0x90, 0x4, 0xf7, 0x8, 0xb0, - 0x9, 0x90, 0x9, 0x90, 0x9, 0x90, 0xb, 0x80, - 0xcd, 0x20, - - /* U+007E "~" */ - 0xb, 0xf8, 0xa, 0x33, 0x90, 0x9f, 0xb0, - - /* U+00B0 "°" */ - 0x7, 0xb7, 0x4, 0x80, 0x84, 0x73, 0x3, 0x74, - 0x80, 0x84, 0x7, 0xb7, 0x0, - - /* U+2022 "•" */ - 0x4, 0x22, 0xfe, 0xd, 0xb0 -}; - - -/*--------------------- - * GLYPH DESCRIPTION - *--------------------*/ - -static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { - {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 52, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 0, .adv_w = 51, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 14, .adv_w = 75, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 22, .adv_w = 135, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 63, .adv_w = 119, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109, .adv_w = 162, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 154, .adv_w = 132, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 199, .adv_w = 40, .box_w = 2, .box_h = 4, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 203, .adv_w = 65, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 223, .adv_w = 65, .box_w = 3, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 243, .adv_w = 77, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 256, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 281, .adv_w = 44, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 287, .adv_w = 74, .box_w = 4, .box_h = 2, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 291, .adv_w = 44, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 294, .adv_w = 68, .box_w = 6, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 333, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 369, .adv_w = 71, .box_w = 4, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 387, .adv_w = 110, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 419, .adv_w = 110, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 451, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 487, .adv_w = 110, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 519, .adv_w = 118, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 555, .adv_w = 115, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 587, .adv_w = 124, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 623, .adv_w = 118, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 655, .adv_w = 44, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 666, .adv_w = 44, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 680, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 705, .adv_w = 112, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 723, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 748, .adv_w = 110, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 780, .adv_w = 199, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 852, .adv_w = 141, .box_w = 10, .box_h = 9, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 897, .adv_w = 145, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 933, .adv_w = 139, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 974, .adv_w = 159, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1015, .adv_w = 129, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1047, .adv_w = 122, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1079, .adv_w = 148, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1120, .adv_w = 156, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1156, .adv_w = 60, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1165, .adv_w = 98, .box_w = 6, .box_h = 9, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 1192, .adv_w = 138, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1228, .adv_w = 114, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1260, .adv_w = 183, .box_w = 10, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1305, .adv_w = 156, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1341, .adv_w = 161, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1386, .adv_w = 139, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1422, .adv_w = 161, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1482, .adv_w = 140, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1518, .adv_w = 119, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1550, .adv_w = 113, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1582, .adv_w = 152, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1618, .adv_w = 137, .box_w = 10, .box_h = 9, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 1663, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1726, .adv_w = 129, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1762, .adv_w = 124, .box_w = 9, .box_h = 9, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 1803, .adv_w = 126, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1839, .adv_w = 64, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 1859, .adv_w = 68, .box_w = 6, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 1898, .adv_w = 64, .box_w = 3, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1918, .adv_w = 112, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 1939, .adv_w = 96, .box_w = 6, .box_h = 1, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1942, .adv_w = 115, .box_w = 4, .box_h = 2, .ofs_x = 1, .ofs_y = 8}, - {.bitmap_index = 1946, .adv_w = 115, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1971, .adv_w = 131, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2006, .adv_w = 110, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2031, .adv_w = 131, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2071, .adv_w = 118, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2096, .adv_w = 68, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2121, .adv_w = 132, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2161, .adv_w = 131, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2196, .adv_w = 54, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2211, .adv_w = 55, .box_w = 5, .box_h = 13, .ofs_x = -2, .ofs_y = -3}, - {.bitmap_index = 2244, .adv_w = 118, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2279, .adv_w = 54, .box_w = 2, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2289, .adv_w = 203, .box_w = 11, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2328, .adv_w = 131, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2353, .adv_w = 122, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2381, .adv_w = 131, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 2416, .adv_w = 131, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2456, .adv_w = 79, .box_w = 4, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2470, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2491, .adv_w = 79, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2514, .adv_w = 130, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2539, .adv_w = 107, .box_w = 8, .box_h = 7, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 2567, .adv_w = 173, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2606, .adv_w = 106, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2631, .adv_w = 107, .box_w = 8, .box_h = 10, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 2671, .adv_w = 100, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2692, .adv_w = 67, .box_w = 4, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2718, .adv_w = 57, .box_w = 2, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 2731, .adv_w = 67, .box_w = 4, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2757, .adv_w = 112, .box_w = 7, .box_h = 2, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 2764, .adv_w = 80, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 2777, .adv_w = 60, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 2} -}; - -/*--------------------- - * CHARACTER MAPPING - *--------------------*/ - -static const uint16_t unicode_list_1[] = { - 0x0, 0x1f72 -}; - -/*Collect the unicode lists and glyph_id offsets*/ -static const lv_font_fmt_txt_cmap_t cmaps[] = -{ - { - .range_start = 32, .range_length = 95, .glyph_id_start = 1, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 176, .range_length = 8051, .glyph_id_start = 96, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 2, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - } -}; - - - -/*-------------------- - * ALL CUSTOM DATA - *--------------------*/ - -#if LV_VERSION_CHECK(8, 0, 0) -/*Store all the custom data of the font*/ -static lv_font_fmt_txt_glyph_cache_t cache; -static const lv_font_fmt_txt_dsc_t font_dsc = { -#else -static lv_font_fmt_txt_dsc_t font_dsc = { -#endif - .glyph_bitmap = glyph_bitmap, - .glyph_dsc = glyph_dsc, - .cmaps = cmaps, - .kern_dsc = NULL, - .kern_scale = 0, - .cmap_num = 2, - .bpp = 4, - .kern_classes = 0, - .bitmap_format = 0, -#if LV_VERSION_CHECK(8, 0, 0) - .cache = &cache -#endif -}; - - -/*----------------- - * PUBLIC FONT - *----------------*/ - -/*Initialize a public general font descriptor*/ -#if LV_VERSION_CHECK(8, 0, 0) -const lv_font_t montserrat_12 = { -#else -lv_font_t montserrat_12 = { -#endif - .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ - .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 15, /*The maximum line height required by the font*/ - .base_line = 3, /*Baseline measured from the bottom of the line*/ -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) - .subpx = LV_FONT_SUBPX_NONE, -#endif -#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 - .underline_position = -1, - .underline_thickness = 1, -#endif - .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ -}; - - - -#endif /*#if MONTSERRAT_12*/ - diff --git a/src/robodash/assets/montserrat_16.c b/src/robodash/assets/montserrat_16.c deleted file mode 100644 index 0f68729..0000000 --- a/src/robodash/assets/montserrat_16.c +++ /dev/null @@ -1,1024 +0,0 @@ -/******************************************************************************* - * Size: 16 px - * Bpp: 4 - * Opts: - ******************************************************************************/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "liblvgl/lvgl.h" -#endif - -#ifndef MONTSERRAT_16 -#define MONTSERRAT_16 1 -#endif - -#if MONTSERRAT_16 - -/*----------------- - * BITMAPS - *----------------*/ - -/*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { - /* U+0020 " " */ - - /* U+0021 "!" */ - 0xbf, 0xb, 0xf0, 0xaf, 0xa, 0xe0, 0x9e, 0x8, - 0xd0, 0x8d, 0x7, 0xc0, 0x0, 0x0, 0x10, 0xcf, - 0x1a, 0xe1, - - /* U+0022 "\"" */ - 0xf5, 0x1f, 0x3f, 0x51, 0xf3, 0xe4, 0xf, 0x3e, - 0x40, 0xf2, 0x72, 0x8, 0x10, - - /* U+0023 "#" */ - 0x0, 0x6, 0xc0, 0x3, 0xe0, 0x0, 0x0, 0x7a, - 0x0, 0x5c, 0x0, 0x0, 0x9, 0x80, 0x7, 0xa0, - 0x1, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x3, 0x3e, - 0x73, 0x3c, 0x83, 0x30, 0x0, 0xf2, 0x0, 0xc5, - 0x0, 0x0, 0x1f, 0x10, 0xe, 0x30, 0x0, 0x3, - 0xf0, 0x0, 0xf1, 0x0, 0x9f, 0xff, 0xff, 0xff, - 0xff, 0x41, 0x38, 0xc3, 0x36, 0xe3, 0x30, 0x0, - 0x89, 0x0, 0x6c, 0x0, 0x0, 0xa, 0x70, 0x7, - 0xa0, 0x0, - - /* U+0024 "$" */ - 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, 0x79, - 0x0, 0x0, 0x0, 0x5c, 0xff, 0xea, 0x20, 0x7, - 0xfc, 0xbc, 0x9e, 0xa0, 0xf, 0xb0, 0x79, 0x0, - 0x10, 0x1f, 0x80, 0x79, 0x0, 0x0, 0xd, 0xe5, - 0x79, 0x0, 0x0, 0x3, 0xef, 0xfd, 0x50, 0x0, - 0x0, 0x5, 0xcf, 0xff, 0x50, 0x0, 0x0, 0x79, - 0x4d, 0xf1, 0x0, 0x0, 0x79, 0x5, 0xf4, 0x8, - 0x0, 0x79, 0x8, 0xf2, 0x2f, 0xfa, 0xbc, 0xaf, - 0xa0, 0x2, 0x9d, 0xff, 0xd7, 0x0, 0x0, 0x0, - 0x79, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, 0x0, - - /* U+0025 "%" */ - 0x4, 0xdd, 0x90, 0x0, 0x5, 0xd0, 0x0, 0xe2, - 0xb, 0x60, 0x1, 0xe3, 0x0, 0x5b, 0x0, 0x5b, - 0x0, 0xa9, 0x0, 0x6, 0xa0, 0x3, 0xc0, 0x4e, - 0x0, 0x0, 0x5b, 0x0, 0x5b, 0xe, 0x50, 0x0, - 0x0, 0xe4, 0xc, 0x68, 0xa0, 0x0, 0x0, 0x4, - 0xde, 0x83, 0xe1, 0x4d, 0xfa, 0x0, 0x0, 0x0, - 0xd6, 0xe, 0x40, 0xa8, 0x0, 0x0, 0x7c, 0x4, - 0xc0, 0x3, 0xd0, 0x0, 0x2f, 0x20, 0x4c, 0x0, - 0x2d, 0x0, 0xb, 0x70, 0x0, 0xe2, 0x8, 0x90, - 0x6, 0xd0, 0x0, 0x4, 0xde, 0xb1, - - /* U+0026 "&" */ - 0x0, 0xa, 0xff, 0xb1, 0x0, 0x0, 0xa, 0xe4, - 0x3c, 0xb0, 0x0, 0x0, 0xe8, 0x0, 0x6e, 0x0, - 0x0, 0xb, 0xc0, 0xc, 0xa0, 0x0, 0x0, 0x3f, - 0xad, 0xd1, 0x0, 0x0, 0x1, 0xdf, 0xc0, 0x0, - 0x0, 0x3, 0xeb, 0x8f, 0x70, 0x18, 0x0, 0xeb, - 0x0, 0x7f, 0x65, 0xf0, 0x3f, 0x40, 0x0, 0x8f, - 0xea, 0x3, 0xf6, 0x0, 0x0, 0xcf, 0x70, 0xb, - 0xf9, 0x56, 0xcf, 0xbf, 0x40, 0x8, 0xef, 0xea, - 0x30, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+0027 "'" */ - 0xf5, 0xf5, 0xe4, 0xe4, 0x72, - - /* U+0028 "(" */ - 0x0, 0xd9, 0x5, 0xf2, 0xb, 0xc0, 0xf, 0x80, - 0x3f, 0x40, 0x5f, 0x20, 0x7f, 0x10, 0x7f, 0x0, - 0x7f, 0x10, 0x5f, 0x20, 0x3f, 0x40, 0xf, 0x80, - 0xb, 0xc0, 0x5, 0xf2, 0x0, 0xd9, - - /* U+0029 ")" */ - 0x3f, 0x40, 0xc, 0xc0, 0x6, 0xf2, 0x1, 0xf6, - 0x0, 0xda, 0x0, 0xbc, 0x0, 0xad, 0x0, 0x9e, - 0x0, 0xad, 0x0, 0xbc, 0x0, 0xda, 0x1, 0xf6, - 0x6, 0xf2, 0xc, 0xc0, 0x3f, 0x40, - - /* U+002A "*" */ - 0x0, 0x4a, 0x0, 0x6, 0x74, 0xa3, 0xa0, 0x2b, - 0xff, 0xe6, 0x0, 0x6f, 0xfb, 0x20, 0x7b, 0x6b, - 0x8d, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x13, 0x0, - 0x0, - - /* U+002B "+" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0xf, 0x50, 0x0, - 0x0, 0xf, 0x50, 0x0, 0x11, 0x1f, 0x61, 0x10, - 0xef, 0xff, 0xff, 0xf3, 0x34, 0x4f, 0x74, 0x40, - 0x0, 0xf, 0x50, 0x0, 0x0, 0xf, 0x50, 0x0, - 0x0, 0x4, 0x10, 0x0, - - /* U+002C "," */ - 0x2, 0x12, 0xfc, 0x1e, 0xc0, 0xb7, 0xe, 0x20, - 0x70, - - /* U+002D "-" */ - 0x1, 0x11, 0x10, 0x1f, 0xff, 0xf3, 0x4, 0x44, - 0x41, - - /* U+002E "." */ - 0x3, 0x12, 0xfc, 0x1e, 0x90, - - /* U+002F "/" */ - 0x0, 0x0, 0x5, 0xf1, 0x0, 0x0, 0xa, 0xb0, - 0x0, 0x0, 0xf, 0x60, 0x0, 0x0, 0x5f, 0x10, - 0x0, 0x0, 0xab, 0x0, 0x0, 0x0, 0xf6, 0x0, - 0x0, 0x5, 0xf1, 0x0, 0x0, 0xa, 0xb0, 0x0, - 0x0, 0xf, 0x60, 0x0, 0x0, 0x4f, 0x10, 0x0, - 0x0, 0xac, 0x0, 0x0, 0x0, 0xf6, 0x0, 0x0, - 0x4, 0xf1, 0x0, 0x0, 0xa, 0xc0, 0x0, 0x0, - 0xe, 0x60, 0x0, 0x0, 0x4f, 0x10, 0x0, 0x0, - - /* U+0030 "0" */ - 0x0, 0x9, 0xef, 0xd6, 0x0, 0x0, 0xcf, 0xa8, - 0xcf, 0x80, 0x8, 0xf5, 0x0, 0xa, 0xf3, 0xe, - 0xc0, 0x0, 0x1, 0xf9, 0x1f, 0x70, 0x0, 0x0, - 0xdc, 0x3f, 0x60, 0x0, 0x0, 0xbe, 0x3f, 0x60, - 0x0, 0x0, 0xbe, 0x1f, 0x80, 0x0, 0x0, 0xdc, - 0xe, 0xc0, 0x0, 0x1, 0xf9, 0x7, 0xf5, 0x0, - 0xa, 0xf2, 0x0, 0xcf, 0xa8, 0xcf, 0x80, 0x0, - 0x8, 0xef, 0xd6, 0x0, - - /* U+0031 "1" */ - 0xef, 0xff, 0x36, 0x7a, 0xf3, 0x0, 0x5f, 0x30, - 0x5, 0xf3, 0x0, 0x5f, 0x30, 0x5, 0xf3, 0x0, - 0x5f, 0x30, 0x5, 0xf3, 0x0, 0x5f, 0x30, 0x5, - 0xf3, 0x0, 0x5f, 0x30, 0x5, 0xf3, - - /* U+0032 "2" */ - 0x4, 0xbf, 0xfd, 0x80, 0x7, 0xfd, 0x98, 0xcf, - 0xa0, 0x28, 0x0, 0x0, 0xbf, 0x10, 0x0, 0x0, - 0x7, 0xf2, 0x0, 0x0, 0x0, 0xaf, 0x0, 0x0, - 0x0, 0x4f, 0x80, 0x0, 0x0, 0x3f, 0xc0, 0x0, - 0x0, 0x3e, 0xc1, 0x0, 0x0, 0x2e, 0xd1, 0x0, - 0x0, 0x2e, 0xd1, 0x0, 0x0, 0x2e, 0xf8, 0x77, - 0x77, 0x46, 0xff, 0xff, 0xff, 0xfa, - - /* U+0033 "3" */ - 0x6f, 0xff, 0xff, 0xff, 0x2, 0x77, 0x77, 0x9f, - 0xb0, 0x0, 0x0, 0xc, 0xd1, 0x0, 0x0, 0x9, - 0xf3, 0x0, 0x0, 0x5, 0xf6, 0x0, 0x0, 0x0, - 0xdf, 0xfb, 0x10, 0x0, 0x3, 0x48, 0xfd, 0x0, - 0x0, 0x0, 0x6, 0xf5, 0x0, 0x0, 0x0, 0x3f, - 0x64, 0x40, 0x0, 0x8, 0xf4, 0xbf, 0xc8, 0x8b, - 0xfb, 0x0, 0x7c, 0xff, 0xd8, 0x0, - - /* U+0034 "4" */ - 0x0, 0x0, 0x1, 0xeb, 0x0, 0x0, 0x0, 0x0, - 0xbe, 0x10, 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, - 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x0, 0xc, - 0xe0, 0x0, 0x0, 0x0, 0x8, 0xf3, 0x1, 0xd5, - 0x0, 0x3, 0xf8, 0x0, 0x2f, 0x60, 0x0, 0xee, - 0x22, 0x24, 0xf7, 0x21, 0x6f, 0xff, 0xff, 0xff, - 0xff, 0x81, 0x55, 0x55, 0x57, 0xf9, 0x52, 0x0, - 0x0, 0x0, 0x2f, 0x60, 0x0, 0x0, 0x0, 0x2, - 0xf6, 0x0, - - /* U+0035 "5" */ - 0x5, 0xff, 0xff, 0xff, 0x0, 0x7f, 0x77, 0x77, - 0x70, 0x8, 0xf0, 0x0, 0x0, 0x0, 0xad, 0x0, - 0x0, 0x0, 0xb, 0xc2, 0x10, 0x0, 0x0, 0xdf, - 0xff, 0xfb, 0x30, 0x4, 0x55, 0x58, 0xef, 0x20, - 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x0, 0xf, - 0x92, 0x50, 0x0, 0x5, 0xf7, 0x8f, 0xd9, 0x8a, - 0xfe, 0x10, 0x5b, 0xef, 0xe9, 0x10, - - /* U+0036 "6" */ - 0x0, 0x6, 0xcf, 0xfd, 0x60, 0x0, 0xaf, 0xc8, - 0x7a, 0x70, 0x6, 0xf8, 0x0, 0x0, 0x0, 0xd, - 0xd0, 0x0, 0x0, 0x0, 0x1f, 0x80, 0x1, 0x0, - 0x0, 0x3f, 0x69, 0xff, 0xfa, 0x10, 0x3f, 0xed, - 0x64, 0x7f, 0xd0, 0x2f, 0xf1, 0x0, 0x5, 0xf5, - 0xf, 0xc0, 0x0, 0x2, 0xf6, 0x9, 0xf1, 0x0, - 0x6, 0xf4, 0x1, 0xde, 0x76, 0x9f, 0xb0, 0x0, - 0x19, 0xef, 0xe8, 0x0, - - /* U+0037 "7" */ - 0x8f, 0xff, 0xff, 0xff, 0xe8, 0xf7, 0x77, 0x77, - 0xfc, 0x8f, 0x0, 0x0, 0x4f, 0x55, 0x90, 0x0, - 0xb, 0xe0, 0x0, 0x0, 0x2, 0xf8, 0x0, 0x0, - 0x0, 0x8f, 0x10, 0x0, 0x0, 0xf, 0xb0, 0x0, - 0x0, 0x6, 0xf4, 0x0, 0x0, 0x0, 0xdd, 0x0, - 0x0, 0x0, 0x3f, 0x70, 0x0, 0x0, 0xa, 0xf1, - 0x0, 0x0, 0x1, 0xf9, 0x0, 0x0, - - /* U+0038 "8" */ - 0x0, 0x5c, 0xff, 0xd8, 0x0, 0x6, 0xfc, 0x66, - 0xaf, 0xa0, 0xc, 0xd0, 0x0, 0x9, 0xf1, 0xd, - 0xb0, 0x0, 0x6, 0xf2, 0x8, 0xf5, 0x0, 0x3d, - 0xd0, 0x0, 0xdf, 0xff, 0xff, 0x30, 0xa, 0xf7, - 0x44, 0x5e, 0xe1, 0x2f, 0x70, 0x0, 0x3, 0xf7, - 0x4f, 0x50, 0x0, 0x0, 0xf9, 0x2f, 0xa0, 0x0, - 0x5, 0xf6, 0x9, 0xfb, 0x66, 0x9f, 0xd0, 0x0, - 0x6c, 0xff, 0xd8, 0x10, - - /* U+0039 "9" */ - 0x1, 0x9e, 0xfe, 0x80, 0x0, 0xc, 0xf8, 0x58, - 0xfc, 0x0, 0x5f, 0x50, 0x0, 0x3f, 0x70, 0x8f, - 0x0, 0x0, 0xe, 0xd0, 0x7f, 0x20, 0x0, 0x1f, - 0xf0, 0x1f, 0xd4, 0x13, 0xcf, 0xf1, 0x4, 0xef, - 0xff, 0xb9, 0xf1, 0x0, 0x3, 0x41, 0xa, 0xf0, - 0x0, 0x0, 0x0, 0xe, 0xb0, 0x0, 0x0, 0x0, - 0x9f, 0x40, 0x9, 0xa7, 0x8d, 0xf8, 0x0, 0x8, - 0xdf, 0xfc, 0x40, 0x0, - - /* U+003A ":" */ - 0x1e, 0x92, 0xfc, 0x3, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x12, 0xfc, 0x1e, 0x90, - - /* U+003B ";" */ - 0x1e, 0x92, 0xfc, 0x3, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x12, 0xfc, 0x1e, 0xc0, 0xb7, 0xe, - 0x20, 0x70, - - /* U+003C "<" */ - 0x0, 0x0, 0x0, 0x42, 0x0, 0x1, 0x7d, 0xf3, - 0x3, 0x9f, 0xe8, 0x10, 0xbf, 0xb5, 0x0, 0x0, - 0xee, 0x71, 0x0, 0x0, 0x17, 0xdf, 0xb4, 0x0, - 0x0, 0x4, 0xaf, 0xd2, 0x0, 0x0, 0x1, 0x82, - - /* U+003D "=" */ - 0xef, 0xff, 0xff, 0xf3, 0x45, 0x55, 0x55, 0x51, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0x10, - 0xef, 0xff, 0xff, 0xf3, 0x34, 0x44, 0x44, 0x40, - - /* U+003E ">" */ - 0x50, 0x0, 0x0, 0x0, 0xef, 0x92, 0x0, 0x0, - 0x6, 0xcf, 0xc5, 0x0, 0x0, 0x3, 0x9f, 0xe2, - 0x0, 0x0, 0x5c, 0xf3, 0x2, 0x8e, 0xf8, 0x20, - 0xbf, 0xc6, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, - - /* U+003F "?" */ - 0x5, 0xbf, 0xfd, 0x80, 0x8, 0xfc, 0x77, 0xbf, - 0xa0, 0x27, 0x0, 0x0, 0xbf, 0x0, 0x0, 0x0, - 0x9, 0xf0, 0x0, 0x0, 0x1, 0xeb, 0x0, 0x0, - 0x1, 0xdd, 0x10, 0x0, 0x0, 0xde, 0x10, 0x0, - 0x0, 0x4f, 0x60, 0x0, 0x0, 0x1, 0x30, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x7, 0xf5, - 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, - - /* U+0040 "@" */ - 0x0, 0x0, 0x18, 0xdf, 0xfe, 0xb6, 0x0, 0x0, - 0x0, 0x7, 0xfb, 0x52, 0x23, 0x6d, 0xd2, 0x0, - 0x0, 0x7e, 0x40, 0x0, 0x0, 0x0, 0x7e, 0x20, - 0x3, 0xf3, 0x2, 0xbf, 0xfa, 0x3f, 0x48, 0xc0, - 0xa, 0x90, 0x1e, 0xc4, 0x39, 0xef, 0x40, 0xe4, - 0xf, 0x30, 0x9e, 0x0, 0x0, 0x9f, 0x40, 0x99, - 0x2f, 0x0, 0xd9, 0x0, 0x0, 0x3f, 0x40, 0x6b, - 0x3f, 0x0, 0xf7, 0x0, 0x0, 0x1f, 0x40, 0x5c, - 0x2f, 0x0, 0xd9, 0x0, 0x0, 0x3f, 0x40, 0x6b, - 0xf, 0x30, 0x8e, 0x10, 0x0, 0xaf, 0x40, 0x98, - 0xa, 0x90, 0x1e, 0xd6, 0x4a, 0xde, 0xa5, 0xf2, - 0x3, 0xf3, 0x2, 0xbf, 0xfa, 0x16, 0xee, 0x60, - 0x0, 0x7e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xfa, 0x52, 0x23, 0x75, 0x0, 0x0, - 0x0, 0x0, 0x18, 0xdf, 0xfe, 0xa3, 0x0, 0x0, - - /* U+0041 "A" */ - 0x0, 0x0, 0x2, 0xfd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0xf, - 0x8d, 0xb0, 0x0, 0x0, 0x0, 0x6, 0xf2, 0x7f, - 0x20, 0x0, 0x0, 0x0, 0xdb, 0x1, 0xf8, 0x0, - 0x0, 0x0, 0x4f, 0x40, 0xa, 0xe0, 0x0, 0x0, - 0xb, 0xe0, 0x0, 0x3f, 0x60, 0x0, 0x2, 0xf8, - 0x11, 0x11, 0xdd, 0x0, 0x0, 0x8f, 0xff, 0xff, - 0xff, 0xf4, 0x0, 0xe, 0xb4, 0x44, 0x44, 0x4f, - 0xa0, 0x6, 0xf3, 0x0, 0x0, 0x0, 0x9f, 0x10, - 0xcd, 0x0, 0x0, 0x0, 0x2, 0xf8, - - /* U+0042 "B" */ - 0x5f, 0xff, 0xff, 0xfc, 0x50, 0x5, 0xf8, 0x55, - 0x57, 0xdf, 0x50, 0x5f, 0x40, 0x0, 0x1, 0xfa, - 0x5, 0xf4, 0x0, 0x0, 0xe, 0xa0, 0x5f, 0x51, - 0x11, 0x29, 0xf4, 0x5, 0xff, 0xff, 0xff, 0xfa, - 0x0, 0x5f, 0x74, 0x44, 0x48, 0xfa, 0x5, 0xf4, - 0x0, 0x0, 0x8, 0xf2, 0x5f, 0x40, 0x0, 0x0, - 0x5f, 0x45, 0xf4, 0x0, 0x0, 0x8, 0xf3, 0x5f, - 0x85, 0x55, 0x6a, 0xfb, 0x5, 0xff, 0xff, 0xff, - 0xd8, 0x0, - - /* U+0043 "C" */ - 0x0, 0x2, 0x9e, 0xff, 0xb5, 0x0, 0x5, 0xff, - 0xa8, 0x9d, 0xf9, 0x3, 0xfd, 0x20, 0x0, 0x8, - 0x50, 0xbf, 0x10, 0x0, 0x0, 0x0, 0x1f, 0x90, - 0x0, 0x0, 0x0, 0x3, 0xf6, 0x0, 0x0, 0x0, - 0x0, 0x3f, 0x60, 0x0, 0x0, 0x0, 0x1, 0xf9, - 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, - 0x0, 0x0, 0x3f, 0xd2, 0x0, 0x0, 0x85, 0x0, - 0x5f, 0xfa, 0x89, 0xdf, 0x90, 0x0, 0x29, 0xef, - 0xfb, 0x50, - - /* U+0044 "D" */ - 0x5f, 0xff, 0xff, 0xea, 0x40, 0x0, 0x5f, 0x97, - 0x77, 0x9e, 0xf9, 0x0, 0x5f, 0x40, 0x0, 0x0, - 0x9f, 0x70, 0x5f, 0x40, 0x0, 0x0, 0xc, 0xf0, - 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf4, 0x5f, 0x40, - 0x0, 0x0, 0x2, 0xf6, 0x5f, 0x40, 0x0, 0x0, - 0x3, 0xf6, 0x5f, 0x40, 0x0, 0x0, 0x6, 0xf4, - 0x5f, 0x40, 0x0, 0x0, 0xc, 0xe0, 0x5f, 0x40, - 0x0, 0x0, 0xaf, 0x60, 0x5f, 0x97, 0x77, 0x9e, - 0xf8, 0x0, 0x5f, 0xff, 0xff, 0xea, 0x40, 0x0, - - /* U+0045 "E" */ - 0x5f, 0xff, 0xff, 0xff, 0x95, 0xf9, 0x77, 0x77, - 0x74, 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf4, 0x0, - 0x0, 0x0, 0x5f, 0x51, 0x11, 0x11, 0x5, 0xff, - 0xff, 0xff, 0xe0, 0x5f, 0x74, 0x44, 0x44, 0x5, - 0xf4, 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, - 0x5, 0xf4, 0x0, 0x0, 0x0, 0x5f, 0x97, 0x77, - 0x77, 0x65, 0xff, 0xff, 0xff, 0xfd, - - /* U+0046 "F" */ - 0x5f, 0xff, 0xff, 0xff, 0x95, 0xf9, 0x77, 0x77, - 0x74, 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf4, 0x0, - 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf6, - 0x22, 0x22, 0x10, 0x5f, 0xff, 0xff, 0xfe, 0x5, - 0xf8, 0x55, 0x55, 0x40, 0x5f, 0x40, 0x0, 0x0, - 0x5, 0xf4, 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, - 0x0, 0x5, 0xf4, 0x0, 0x0, 0x0, - - /* U+0047 "G" */ - 0x0, 0x2, 0x9e, 0xff, 0xc6, 0x0, 0x0, 0x5f, - 0xfb, 0x88, 0xcf, 0xb0, 0x3, 0xfd, 0x20, 0x0, - 0x6, 0x60, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, - 0x1f, 0x90, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x60, - 0x0, 0x0, 0x0, 0x10, 0x3f, 0x60, 0x0, 0x0, - 0x9, 0xf0, 0x1f, 0x90, 0x0, 0x0, 0x9, 0xf0, - 0xb, 0xf1, 0x0, 0x0, 0x9, 0xf0, 0x3, 0xfd, - 0x20, 0x0, 0xa, 0xf0, 0x0, 0x5f, 0xfb, 0x88, - 0xcf, 0xd0, 0x0, 0x2, 0x9e, 0xff, 0xc6, 0x0, - - /* U+0048 "H" */ - 0x5f, 0x40, 0x0, 0x0, 0x4f, 0x55, 0xf4, 0x0, - 0x0, 0x4, 0xf5, 0x5f, 0x40, 0x0, 0x0, 0x4f, - 0x55, 0xf4, 0x0, 0x0, 0x4, 0xf5, 0x5f, 0x62, - 0x22, 0x22, 0x6f, 0x55, 0xff, 0xff, 0xff, 0xff, - 0xf5, 0x5f, 0x85, 0x55, 0x55, 0x8f, 0x55, 0xf4, - 0x0, 0x0, 0x4, 0xf5, 0x5f, 0x40, 0x0, 0x0, - 0x4f, 0x55, 0xf4, 0x0, 0x0, 0x4, 0xf5, 0x5f, - 0x40, 0x0, 0x0, 0x4f, 0x55, 0xf4, 0x0, 0x0, - 0x4, 0xf5, - - /* U+0049 "I" */ - 0x5f, 0x45, 0xf4, 0x5f, 0x45, 0xf4, 0x5f, 0x45, - 0xf4, 0x5f, 0x45, 0xf4, 0x5f, 0x45, 0xf4, 0x5f, - 0x45, 0xf4, - - /* U+004A "J" */ - 0x0, 0xff, 0xff, 0xfa, 0x0, 0x77, 0x77, 0xfa, - 0x0, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0xfa, - 0x0, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0xfa, - 0x0, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0xfa, - 0x0, 0x0, 0x0, 0xf9, 0x7, 0x20, 0x3, 0xf7, - 0xe, 0xf8, 0x8e, 0xf1, 0x1, 0xaf, 0xfc, 0x30, - - /* U+004B "K" */ - 0x5f, 0x40, 0x0, 0x2, 0xeb, 0x5, 0xf4, 0x0, - 0x1, 0xec, 0x0, 0x5f, 0x40, 0x1, 0xde, 0x10, - 0x5, 0xf4, 0x0, 0xce, 0x20, 0x0, 0x5f, 0x40, - 0xbf, 0x30, 0x0, 0x5, 0xf4, 0x9f, 0x90, 0x0, - 0x0, 0x5f, 0xcf, 0xef, 0x40, 0x0, 0x5, 0xff, - 0x91, 0xee, 0x10, 0x0, 0x5f, 0xa0, 0x3, 0xfc, - 0x0, 0x5, 0xf4, 0x0, 0x6, 0xf8, 0x0, 0x5f, - 0x40, 0x0, 0x9, 0xf5, 0x5, 0xf4, 0x0, 0x0, - 0xc, 0xf2, - - /* U+004C "L" */ - 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf4, 0x0, 0x0, - 0x0, 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf4, 0x0, - 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, 0x5, 0xf4, - 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, 0x5, - 0xf4, 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, - 0x5, 0xf4, 0x0, 0x0, 0x0, 0x5f, 0x97, 0x77, - 0x77, 0x25, 0xff, 0xff, 0xff, 0xf5, - - /* U+004D "M" */ - 0x5f, 0x40, 0x0, 0x0, 0x0, 0x1e, 0x95, 0xfc, - 0x0, 0x0, 0x0, 0x8, 0xf9, 0x5f, 0xf5, 0x0, - 0x0, 0x1, 0xff, 0x95, 0xff, 0xd0, 0x0, 0x0, - 0xaf, 0xf9, 0x5f, 0x8f, 0x70, 0x0, 0x2f, 0x8f, - 0x95, 0xf3, 0xbe, 0x10, 0xb, 0xe0, 0xf9, 0x5f, - 0x32, 0xf8, 0x3, 0xf6, 0xf, 0x95, 0xf3, 0x8, - 0xf2, 0xcc, 0x0, 0xf9, 0x5f, 0x30, 0xe, 0xdf, - 0x30, 0xf, 0x95, 0xf3, 0x0, 0x6f, 0xa0, 0x0, - 0xf9, 0x5f, 0x30, 0x0, 0x81, 0x0, 0xf, 0x95, - 0xf3, 0x0, 0x0, 0x0, 0x0, 0xf9, - - /* U+004E "N" */ - 0x5f, 0x50, 0x0, 0x0, 0x4f, 0x55, 0xff, 0x20, - 0x0, 0x4, 0xf5, 0x5f, 0xfd, 0x0, 0x0, 0x4f, - 0x55, 0xfc, 0xfa, 0x0, 0x4, 0xf5, 0x5f, 0x4b, - 0xf7, 0x0, 0x4f, 0x55, 0xf4, 0x1e, 0xf3, 0x4, - 0xf5, 0x5f, 0x40, 0x3f, 0xe1, 0x4f, 0x55, 0xf4, - 0x0, 0x7f, 0xb4, 0xf5, 0x5f, 0x40, 0x0, 0xaf, - 0xcf, 0x55, 0xf4, 0x0, 0x0, 0xdf, 0xf5, 0x5f, - 0x40, 0x0, 0x2, 0xff, 0x55, 0xf4, 0x0, 0x0, - 0x6, 0xf5, - - /* U+004F "O" */ - 0x0, 0x2, 0x9e, 0xff, 0xb5, 0x0, 0x0, 0x5, - 0xff, 0xa8, 0x9d, 0xfb, 0x0, 0x3, 0xfd, 0x20, - 0x0, 0x7, 0xfa, 0x0, 0xbf, 0x10, 0x0, 0x0, - 0x9, 0xf3, 0x1f, 0x90, 0x0, 0x0, 0x0, 0x2f, - 0x73, 0xf6, 0x0, 0x0, 0x0, 0x0, 0xfa, 0x3f, - 0x60, 0x0, 0x0, 0x0, 0xf, 0xa1, 0xf9, 0x0, - 0x0, 0x0, 0x2, 0xf7, 0xb, 0xf1, 0x0, 0x0, - 0x0, 0xaf, 0x20, 0x3f, 0xd2, 0x0, 0x0, 0x7f, - 0xa0, 0x0, 0x4f, 0xfa, 0x89, 0xdf, 0xb0, 0x0, - 0x0, 0x29, 0xef, 0xfb, 0x50, 0x0, - - /* U+0050 "P" */ - 0x5f, 0xff, 0xff, 0xd8, 0x0, 0x5f, 0x97, 0x77, - 0xbf, 0xc0, 0x5f, 0x40, 0x0, 0x6, 0xf6, 0x5f, - 0x40, 0x0, 0x0, 0xfa, 0x5f, 0x40, 0x0, 0x0, - 0xeb, 0x5f, 0x40, 0x0, 0x3, 0xf8, 0x5f, 0x62, - 0x22, 0x6e, 0xf1, 0x5f, 0xff, 0xff, 0xfd, 0x30, - 0x5f, 0x85, 0x54, 0x20, 0x0, 0x5f, 0x40, 0x0, - 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, 0x0, 0x5f, - 0x40, 0x0, 0x0, 0x0, - - /* U+0051 "Q" */ - 0x0, 0x2, 0x9e, 0xff, 0xb5, 0x0, 0x0, 0x0, - 0x5f, 0xfa, 0x89, 0xdf, 0xb0, 0x0, 0x3, 0xfd, - 0x20, 0x0, 0x7, 0xfa, 0x0, 0xb, 0xf1, 0x0, - 0x0, 0x0, 0x9f, 0x30, 0x1f, 0x90, 0x0, 0x0, - 0x0, 0x2f, 0x70, 0x3f, 0x60, 0x0, 0x0, 0x0, - 0xf, 0xa0, 0x3f, 0x60, 0x0, 0x0, 0x0, 0xf, - 0xa0, 0x1f, 0x90, 0x0, 0x0, 0x0, 0x2f, 0x70, - 0xb, 0xf2, 0x0, 0x0, 0x0, 0xaf, 0x20, 0x3, - 0xfd, 0x20, 0x0, 0x8, 0xfa, 0x0, 0x0, 0x4f, - 0xfa, 0x89, 0xdf, 0xb0, 0x0, 0x0, 0x2, 0x9e, - 0xff, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, - 0xe4, 0x15, 0xb0, 0x0, 0x0, 0x0, 0x2, 0xcf, - 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x2, 0x31, - 0x0, - - /* U+0052 "R" */ - 0x5f, 0xff, 0xff, 0xd8, 0x0, 0x5f, 0x97, 0x77, - 0xbf, 0xc0, 0x5f, 0x40, 0x0, 0x6, 0xf6, 0x5f, - 0x40, 0x0, 0x0, 0xfa, 0x5f, 0x40, 0x0, 0x0, - 0xeb, 0x5f, 0x40, 0x0, 0x3, 0xf8, 0x5f, 0x62, - 0x22, 0x6e, 0xf1, 0x5f, 0xff, 0xff, 0xfd, 0x30, - 0x5f, 0x85, 0x55, 0xf9, 0x0, 0x5f, 0x40, 0x0, - 0x7f, 0x40, 0x5f, 0x40, 0x0, 0xc, 0xe0, 0x5f, - 0x40, 0x0, 0x2, 0xf9, - - /* U+0053 "S" */ - 0x0, 0x5c, 0xff, 0xea, 0x20, 0x7, 0xfc, 0x77, - 0x9e, 0xa0, 0xf, 0xb0, 0x0, 0x0, 0x10, 0x1f, - 0x80, 0x0, 0x0, 0x0, 0xd, 0xe5, 0x0, 0x0, - 0x0, 0x3, 0xef, 0xea, 0x50, 0x0, 0x0, 0x5, - 0xae, 0xff, 0x50, 0x0, 0x0, 0x0, 0x4d, 0xf1, - 0x0, 0x0, 0x0, 0x5, 0xf4, 0x8, 0x0, 0x0, - 0x8, 0xf2, 0x2f, 0xfa, 0x77, 0xaf, 0xa0, 0x2, - 0x9d, 0xff, 0xd7, 0x0, - - /* U+0054 "T" */ - 0xff, 0xff, 0xff, 0xff, 0xf5, 0x67, 0x78, 0xfb, - 0x77, 0x72, 0x0, 0x1, 0xf7, 0x0, 0x0, 0x0, - 0x1, 0xf7, 0x0, 0x0, 0x0, 0x1, 0xf7, 0x0, - 0x0, 0x0, 0x1, 0xf7, 0x0, 0x0, 0x0, 0x1, - 0xf7, 0x0, 0x0, 0x0, 0x1, 0xf7, 0x0, 0x0, - 0x0, 0x1, 0xf7, 0x0, 0x0, 0x0, 0x1, 0xf7, - 0x0, 0x0, 0x0, 0x1, 0xf7, 0x0, 0x0, 0x0, - 0x1, 0xf7, 0x0, 0x0, - - /* U+0055 "U" */ - 0x6f, 0x30, 0x0, 0x0, 0x8f, 0x16, 0xf3, 0x0, - 0x0, 0x8, 0xf1, 0x6f, 0x30, 0x0, 0x0, 0x8f, - 0x16, 0xf3, 0x0, 0x0, 0x8, 0xf1, 0x6f, 0x30, - 0x0, 0x0, 0x8f, 0x16, 0xf3, 0x0, 0x0, 0x8, - 0xf1, 0x6f, 0x30, 0x0, 0x0, 0x8f, 0x16, 0xf3, - 0x0, 0x0, 0x8, 0xf0, 0x3f, 0x70, 0x0, 0x0, - 0xce, 0x0, 0xee, 0x10, 0x0, 0x4f, 0x80, 0x4, - 0xfe, 0x98, 0xbf, 0xd1, 0x0, 0x3, 0xbf, 0xfe, - 0x91, 0x0, - - /* U+0056 "V" */ - 0xc, 0xe0, 0x0, 0x0, 0x0, 0x6f, 0x30, 0x6f, - 0x50, 0x0, 0x0, 0xc, 0xc0, 0x0, 0xfb, 0x0, - 0x0, 0x3, 0xf6, 0x0, 0x9, 0xf2, 0x0, 0x0, - 0xaf, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x1f, 0x90, - 0x0, 0x0, 0xce, 0x0, 0x7, 0xf2, 0x0, 0x0, - 0x5, 0xf5, 0x0, 0xdc, 0x0, 0x0, 0x0, 0xe, - 0xc0, 0x4f, 0x50, 0x0, 0x0, 0x0, 0x8f, 0x2b, - 0xe0, 0x0, 0x0, 0x0, 0x2, 0xfb, 0xf8, 0x0, - 0x0, 0x0, 0x0, 0xb, 0xff, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x4f, 0xb0, 0x0, 0x0, - - /* U+0057 "W" */ - 0x5f, 0x40, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x2, - 0xf5, 0xf, 0x90, 0x0, 0x2, 0xff, 0x40, 0x0, - 0x7, 0xf0, 0xb, 0xe0, 0x0, 0x7, 0xfe, 0x90, - 0x0, 0xc, 0xb0, 0x6, 0xf3, 0x0, 0xc, 0xa9, - 0xe0, 0x0, 0x1f, 0x60, 0x1, 0xf8, 0x0, 0x1f, - 0x54, 0xf3, 0x0, 0x6f, 0x10, 0x0, 0xcd, 0x0, - 0x6f, 0x10, 0xf8, 0x0, 0xbc, 0x0, 0x0, 0x7f, - 0x20, 0xcb, 0x0, 0xad, 0x1, 0xf7, 0x0, 0x0, - 0x2f, 0x71, 0xf6, 0x0, 0x5f, 0x26, 0xf2, 0x0, - 0x0, 0xd, 0xc6, 0xf1, 0x0, 0xf, 0x7b, 0xd0, - 0x0, 0x0, 0x8, 0xfd, 0xc0, 0x0, 0xb, 0xdf, - 0x80, 0x0, 0x0, 0x3, 0xff, 0x70, 0x0, 0x6, - 0xff, 0x30, 0x0, 0x0, 0x0, 0xef, 0x20, 0x0, - 0x1, 0xfe, 0x0, 0x0, - - /* U+0058 "X" */ - 0x3f, 0x90, 0x0, 0x0, 0xce, 0x0, 0x8f, 0x40, - 0x0, 0x7f, 0x40, 0x0, 0xde, 0x10, 0x3f, 0x90, - 0x0, 0x3, 0xfa, 0xd, 0xd0, 0x0, 0x0, 0x8, - 0xfc, 0xf3, 0x0, 0x0, 0x0, 0xd, 0xf9, 0x0, - 0x0, 0x0, 0x1, 0xff, 0xc0, 0x0, 0x0, 0x0, - 0xbf, 0x7f, 0x80, 0x0, 0x0, 0x6f, 0x60, 0xaf, - 0x30, 0x0, 0x2f, 0xb0, 0x1, 0xed, 0x0, 0xc, - 0xf1, 0x0, 0x4, 0xf8, 0x7, 0xf6, 0x0, 0x0, - 0x9, 0xf3, - - /* U+0059 "Y" */ - 0xc, 0xe0, 0x0, 0x0, 0x7, 0xf2, 0x3, 0xf7, - 0x0, 0x0, 0x1f, 0x90, 0x0, 0xaf, 0x10, 0x0, - 0x9e, 0x10, 0x0, 0x1f, 0xa0, 0x2, 0xf6, 0x0, - 0x0, 0x8, 0xf3, 0xb, 0xd0, 0x0, 0x0, 0x0, - 0xec, 0x4f, 0x40, 0x0, 0x0, 0x0, 0x5f, 0xfb, - 0x0, 0x0, 0x0, 0x0, 0xd, 0xf2, 0x0, 0x0, - 0x0, 0x0, 0x9, 0xf0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf0, - 0x0, 0x0, 0x0, 0x0, 0x9, 0xf0, 0x0, 0x0, - - /* U+005A "Z" */ - 0x3f, 0xff, 0xff, 0xff, 0xfd, 0x1, 0x77, 0x77, - 0x77, 0xbf, 0x90, 0x0, 0x0, 0x0, 0x2e, 0xc0, - 0x0, 0x0, 0x0, 0xc, 0xf2, 0x0, 0x0, 0x0, - 0x8, 0xf5, 0x0, 0x0, 0x0, 0x4, 0xf9, 0x0, - 0x0, 0x0, 0x1, 0xed, 0x0, 0x0, 0x0, 0x0, - 0xcf, 0x20, 0x0, 0x0, 0x0, 0x8f, 0x50, 0x0, - 0x0, 0x0, 0x4f, 0x90, 0x0, 0x0, 0x0, 0x1e, - 0xf8, 0x77, 0x77, 0x77, 0x5, 0xff, 0xff, 0xff, - 0xff, 0xf0, - - /* U+005B "[" */ - 0x5f, 0xff, 0x5, 0xf7, 0x50, 0x5f, 0x30, 0x5, - 0xf3, 0x0, 0x5f, 0x30, 0x5, 0xf3, 0x0, 0x5f, - 0x30, 0x5, 0xf3, 0x0, 0x5f, 0x30, 0x5, 0xf3, - 0x0, 0x5f, 0x30, 0x5, 0xf3, 0x0, 0x5f, 0x30, - 0x5, 0xf7, 0x50, 0x5f, 0xff, 0x0, - - /* U+005C "\\" */ - 0x7e, 0x0, 0x0, 0x0, 0x1f, 0x40, 0x0, 0x0, - 0xc, 0x90, 0x0, 0x0, 0x7, 0xe0, 0x0, 0x0, - 0x2, 0xf4, 0x0, 0x0, 0x0, 0xc9, 0x0, 0x0, - 0x0, 0x7e, 0x0, 0x0, 0x0, 0x2f, 0x40, 0x0, - 0x0, 0xc, 0x90, 0x0, 0x0, 0x7, 0xe0, 0x0, - 0x0, 0x2, 0xf3, 0x0, 0x0, 0x0, 0xd9, 0x0, - 0x0, 0x0, 0x7e, 0x0, 0x0, 0x0, 0x2f, 0x30, - 0x0, 0x0, 0xd, 0x90, 0x0, 0x0, 0x7, 0xe0, - - /* U+005D "]" */ - 0xbf, 0xfa, 0x35, 0xea, 0x0, 0xea, 0x0, 0xea, - 0x0, 0xea, 0x0, 0xea, 0x0, 0xea, 0x0, 0xea, - 0x0, 0xea, 0x0, 0xea, 0x0, 0xea, 0x0, 0xea, - 0x0, 0xea, 0x35, 0xea, 0xbf, 0xfa, - - /* U+005E "^" */ - 0x0, 0x2f, 0x80, 0x0, 0x0, 0x9d, 0xe0, 0x0, - 0x0, 0xf3, 0xd5, 0x0, 0x6, 0xc0, 0x7b, 0x0, - 0xc, 0x60, 0x1f, 0x20, 0x3f, 0x10, 0xb, 0x80, - 0x9a, 0x0, 0x4, 0xe0, - - /* U+005F "_" */ - 0xff, 0xff, 0xff, 0xff, 0x11, 0x11, 0x11, 0x11, - - /* U+0060 "`" */ - 0x7, 0xf6, 0x0, 0x3, 0xe7, - - /* U+0061 "a" */ - 0x2, 0xae, 0xfe, 0x90, 0x0, 0xcd, 0x86, 0xaf, - 0xa0, 0x2, 0x0, 0x0, 0x9f, 0x0, 0x0, 0x0, - 0x5, 0xf2, 0x3, 0xbf, 0xff, 0xff, 0x20, 0xec, - 0x42, 0x27, 0xf2, 0x2f, 0x50, 0x0, 0x7f, 0x20, - 0xec, 0x32, 0x7f, 0xf2, 0x3, 0xcf, 0xfb, 0x7f, - 0x20, - - /* U+0062 "b" */ - 0x8f, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x0, 0x0, - 0x0, 0x0, 0x8f, 0x0, 0x0, 0x0, 0x0, 0x8f, - 0x2b, 0xff, 0xb3, 0x0, 0x8f, 0xec, 0x78, 0xef, - 0x40, 0x8f, 0x90, 0x0, 0x1e, 0xd0, 0x8f, 0x10, - 0x0, 0x7, 0xf2, 0x8f, 0x0, 0x0, 0x5, 0xf3, - 0x8f, 0x10, 0x0, 0x7, 0xf2, 0x8f, 0x90, 0x0, - 0x1e, 0xd0, 0x8f, 0xfb, 0x77, 0xef, 0x40, 0x8e, - 0x2b, 0xff, 0xb3, 0x0, - - /* U+0063 "c" */ - 0x0, 0x3b, 0xff, 0xc4, 0x0, 0x4f, 0xd8, 0x7c, - 0xf5, 0xe, 0xd0, 0x0, 0x7, 0x13, 0xf5, 0x0, - 0x0, 0x0, 0x5f, 0x30, 0x0, 0x0, 0x3, 0xf5, - 0x0, 0x0, 0x0, 0xe, 0xd0, 0x0, 0x6, 0x10, - 0x4f, 0xd7, 0x7c, 0xf5, 0x0, 0x3b, 0xff, 0xc4, - 0x0, - - /* U+0064 "d" */ - 0x0, 0x0, 0x0, 0x1, 0xf7, 0x0, 0x0, 0x0, - 0x1, 0xf7, 0x0, 0x0, 0x0, 0x1, 0xf7, 0x0, - 0x4c, 0xff, 0xa3, 0xf7, 0x5, 0xfd, 0x77, 0xce, - 0xf7, 0xe, 0xd0, 0x0, 0xb, 0xf7, 0x3f, 0x50, - 0x0, 0x3, 0xf7, 0x5f, 0x30, 0x0, 0x1, 0xf7, - 0x3f, 0x50, 0x0, 0x3, 0xf7, 0xe, 0xd0, 0x0, - 0xb, 0xf7, 0x5, 0xfd, 0x77, 0xce, 0xf7, 0x0, - 0x4c, 0xff, 0xb2, 0xf7, - - /* U+0065 "e" */ - 0x0, 0x4c, 0xff, 0xb2, 0x0, 0x5, 0xfc, 0x67, - 0xde, 0x20, 0xe, 0xb0, 0x0, 0xd, 0xa0, 0x3f, - 0x40, 0x0, 0x7, 0xf0, 0x5f, 0xff, 0xff, 0xff, - 0xf1, 0x3f, 0x62, 0x22, 0x22, 0x20, 0xe, 0xc0, - 0x0, 0x2, 0x0, 0x4, 0xfd, 0x86, 0xaf, 0x50, - 0x0, 0x3b, 0xff, 0xd6, 0x0, - - /* U+0066 "f" */ - 0x0, 0x4d, 0xfd, 0x10, 0x1f, 0xc5, 0x70, 0x4, - 0xf3, 0x0, 0xc, 0xff, 0xff, 0xa0, 0x48, 0xf7, - 0x53, 0x0, 0x5f, 0x30, 0x0, 0x5, 0xf3, 0x0, - 0x0, 0x5f, 0x30, 0x0, 0x5, 0xf3, 0x0, 0x0, - 0x5f, 0x30, 0x0, 0x5, 0xf3, 0x0, 0x0, 0x5f, - 0x30, 0x0, - - /* U+0067 "g" */ - 0x0, 0x3c, 0xff, 0xb2, 0xe9, 0x5, 0xfc, 0x65, - 0xaf, 0xf9, 0xe, 0xc0, 0x0, 0x8, 0xf9, 0x3f, - 0x50, 0x0, 0x1, 0xf9, 0x5f, 0x30, 0x0, 0x0, - 0xf9, 0x3f, 0x60, 0x0, 0x1, 0xf9, 0xe, 0xd0, - 0x0, 0x9, 0xf9, 0x4, 0xfd, 0x77, 0xbe, 0xf8, - 0x0, 0x3b, 0xff, 0xb2, 0xf7, 0x0, 0x0, 0x0, - 0x5, 0xf4, 0x9, 0xe9, 0x76, 0x9f, 0xc0, 0x1, - 0x7c, 0xff, 0xd8, 0x0, - - /* U+0068 "h" */ - 0x8f, 0x0, 0x0, 0x0, 0x8, 0xf0, 0x0, 0x0, - 0x0, 0x8f, 0x0, 0x0, 0x0, 0x8, 0xf3, 0xbf, - 0xfb, 0x20, 0x8f, 0xfb, 0x79, 0xfe, 0x8, 0xf8, - 0x0, 0x6, 0xf5, 0x8f, 0x10, 0x0, 0x1f, 0x78, - 0xf0, 0x0, 0x0, 0xf8, 0x8f, 0x0, 0x0, 0xf, - 0x88, 0xf0, 0x0, 0x0, 0xf8, 0x8f, 0x0, 0x0, - 0xf, 0x88, 0xf0, 0x0, 0x0, 0xf8, - - /* U+0069 "i" */ - 0x9e, 0x1a, 0xf2, 0x0, 0x8, 0xf0, 0x8f, 0x8, - 0xf0, 0x8f, 0x8, 0xf0, 0x8f, 0x8, 0xf0, 0x8f, - 0x8, 0xf0, - - /* U+006A "j" */ - 0x0, 0x8, 0xf2, 0x0, 0x9, 0xf3, 0x0, 0x0, - 0x10, 0x0, 0x7, 0xf1, 0x0, 0x7, 0xf1, 0x0, - 0x7, 0xf1, 0x0, 0x7, 0xf1, 0x0, 0x7, 0xf1, - 0x0, 0x7, 0xf1, 0x0, 0x7, 0xf1, 0x0, 0x7, - 0xf1, 0x0, 0x7, 0xf1, 0x0, 0x8, 0xf0, 0x18, - 0x6e, 0xc0, 0x3e, 0xfc, 0x20, - - /* U+006B "k" */ - 0x8f, 0x0, 0x0, 0x0, 0x8, 0xf0, 0x0, 0x0, - 0x0, 0x8f, 0x0, 0x0, 0x0, 0x8, 0xf0, 0x0, - 0x1d, 0xe1, 0x8f, 0x0, 0x1d, 0xe2, 0x8, 0xf0, - 0x1d, 0xe2, 0x0, 0x8f, 0x2d, 0xf3, 0x0, 0x8, - 0xfe, 0xff, 0x70, 0x0, 0x8f, 0xe2, 0xbf, 0x30, - 0x8, 0xf2, 0x1, 0xee, 0x10, 0x8f, 0x0, 0x3, - 0xfb, 0x8, 0xf0, 0x0, 0x7, 0xf7, - - /* U+006C "l" */ - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8f, 0x8f, 0x8f, - - /* U+006D "m" */ - 0x8e, 0x3c, 0xfe, 0x90, 0x2b, 0xff, 0xb2, 0x8, - 0xff, 0xa7, 0xaf, 0xcf, 0xc7, 0x9f, 0xe0, 0x8f, - 0x80, 0x0, 0x9f, 0xc0, 0x0, 0x5f, 0x58, 0xf1, - 0x0, 0x5, 0xf5, 0x0, 0x0, 0xf8, 0x8f, 0x0, - 0x0, 0x4f, 0x40, 0x0, 0xf, 0x88, 0xf0, 0x0, - 0x4, 0xf4, 0x0, 0x0, 0xf8, 0x8f, 0x0, 0x0, - 0x4f, 0x40, 0x0, 0xf, 0x88, 0xf0, 0x0, 0x4, - 0xf4, 0x0, 0x0, 0xf8, 0x8f, 0x0, 0x0, 0x4f, - 0x40, 0x0, 0xf, 0x80, - - /* U+006E "n" */ - 0x8e, 0x3b, 0xff, 0xb2, 0x8, 0xff, 0xb7, 0x9f, - 0xe0, 0x8f, 0x80, 0x0, 0x6f, 0x58, 0xf1, 0x0, - 0x1, 0xf7, 0x8f, 0x0, 0x0, 0xf, 0x88, 0xf0, - 0x0, 0x0, 0xf8, 0x8f, 0x0, 0x0, 0xf, 0x88, - 0xf0, 0x0, 0x0, 0xf8, 0x8f, 0x0, 0x0, 0xf, - 0x80, - - /* U+006F "o" */ - 0x0, 0x3b, 0xff, 0xc5, 0x0, 0x4, 0xfd, 0x77, - 0xcf, 0x70, 0xe, 0xd0, 0x0, 0xa, 0xf1, 0x3f, - 0x50, 0x0, 0x3, 0xf6, 0x5f, 0x30, 0x0, 0x1, - 0xf7, 0x3f, 0x50, 0x0, 0x3, 0xf6, 0xe, 0xd0, - 0x0, 0xb, 0xf1, 0x4, 0xfd, 0x77, 0xcf, 0x60, - 0x0, 0x3b, 0xff, 0xc5, 0x0, - - /* U+0070 "p" */ - 0x8e, 0x2b, 0xff, 0xb3, 0x0, 0x8f, 0xfc, 0x78, - 0xef, 0x40, 0x8f, 0x90, 0x0, 0x1e, 0xd0, 0x8f, - 0x10, 0x0, 0x7, 0xf2, 0x8f, 0x0, 0x0, 0x5, - 0xf3, 0x8f, 0x10, 0x0, 0x7, 0xf2, 0x8f, 0x90, - 0x0, 0x1e, 0xd0, 0x8f, 0xeb, 0x77, 0xef, 0x40, - 0x8f, 0x2b, 0xff, 0xb3, 0x0, 0x8f, 0x0, 0x0, - 0x0, 0x0, 0x8f, 0x0, 0x0, 0x0, 0x0, 0x8f, - 0x0, 0x0, 0x0, 0x0, - - /* U+0071 "q" */ - 0x0, 0x4c, 0xff, 0xb2, 0xf7, 0x5, 0xfd, 0x77, - 0xce, 0xf7, 0xe, 0xd0, 0x0, 0xb, 0xf7, 0x3f, - 0x50, 0x0, 0x3, 0xf7, 0x5f, 0x30, 0x0, 0x1, - 0xf7, 0x3f, 0x50, 0x0, 0x3, 0xf7, 0xe, 0xd0, - 0x0, 0xb, 0xf7, 0x5, 0xfd, 0x77, 0xce, 0xf7, - 0x0, 0x4c, 0xff, 0xa3, 0xf7, 0x0, 0x0, 0x0, - 0x1, 0xf7, 0x0, 0x0, 0x0, 0x1, 0xf7, 0x0, - 0x0, 0x0, 0x1, 0xf7, - - /* U+0072 "r" */ - 0x8e, 0x3c, 0xf0, 0x8f, 0xfb, 0x70, 0x8f, 0x80, - 0x0, 0x8f, 0x10, 0x0, 0x8f, 0x0, 0x0, 0x8f, - 0x0, 0x0, 0x8f, 0x0, 0x0, 0x8f, 0x0, 0x0, - 0x8f, 0x0, 0x0, - - /* U+0073 "s" */ - 0x3, 0xbf, 0xfd, 0x91, 0x1f, 0xd7, 0x69, 0xd0, - 0x5f, 0x30, 0x0, 0x0, 0x3f, 0xb4, 0x10, 0x0, - 0x6, 0xef, 0xfd, 0x70, 0x0, 0x2, 0x5a, 0xf5, - 0x1, 0x0, 0x0, 0xf8, 0x6f, 0x96, 0x6b, 0xf3, - 0x19, 0xdf, 0xfc, 0x40, - - /* U+0074 "t" */ - 0x5, 0xf3, 0x0, 0x0, 0x5f, 0x30, 0x0, 0xcf, - 0xff, 0xfa, 0x4, 0x8f, 0x75, 0x30, 0x5, 0xf3, - 0x0, 0x0, 0x5f, 0x30, 0x0, 0x5, 0xf3, 0x0, - 0x0, 0x5f, 0x30, 0x0, 0x4, 0xf4, 0x0, 0x0, - 0x1f, 0xc6, 0x80, 0x0, 0x5e, 0xfc, 0x10, - - /* U+0075 "u" */ - 0xae, 0x0, 0x0, 0x2f, 0x5a, 0xe0, 0x0, 0x2, - 0xf5, 0xae, 0x0, 0x0, 0x2f, 0x5a, 0xe0, 0x0, - 0x2, 0xf5, 0xae, 0x0, 0x0, 0x2f, 0x59, 0xf0, - 0x0, 0x4, 0xf5, 0x7f, 0x40, 0x0, 0xbf, 0x51, - 0xff, 0x87, 0xce, 0xf5, 0x3, 0xbf, 0xfb, 0x3f, - 0x50, - - /* U+0076 "v" */ - 0xd, 0xc0, 0x0, 0x0, 0xcc, 0x6, 0xf2, 0x0, - 0x2, 0xf5, 0x0, 0xf9, 0x0, 0x9, 0xe0, 0x0, - 0x9f, 0x0, 0xf, 0x80, 0x0, 0x2f, 0x60, 0x6f, - 0x10, 0x0, 0xc, 0xc0, 0xdb, 0x0, 0x0, 0x5, - 0xf6, 0xf4, 0x0, 0x0, 0x0, 0xef, 0xd0, 0x0, - 0x0, 0x0, 0x8f, 0x70, 0x0, - - /* U+0077 "w" */ - 0xbb, 0x0, 0x0, 0x9f, 0x10, 0x0, 0x4f, 0x16, - 0xf1, 0x0, 0xe, 0xf6, 0x0, 0x9, 0xc0, 0xf, - 0x60, 0x5, 0xfc, 0xb0, 0x0, 0xf6, 0x0, 0xac, - 0x0, 0xab, 0x5f, 0x10, 0x5f, 0x10, 0x5, 0xf1, - 0x1f, 0x50, 0xf7, 0xa, 0xb0, 0x0, 0xf, 0x76, - 0xf0, 0x9, 0xc0, 0xf5, 0x0, 0x0, 0xac, 0xca, - 0x0, 0x4f, 0x8f, 0x0, 0x0, 0x4, 0xff, 0x40, - 0x0, 0xef, 0xa0, 0x0, 0x0, 0xe, 0xe0, 0x0, - 0x8, 0xf4, 0x0, 0x0, - - /* U+0078 "x" */ - 0x4f, 0x70, 0x0, 0x9f, 0x20, 0x8f, 0x30, 0x5f, - 0x50, 0x0, 0xcd, 0x2e, 0x90, 0x0, 0x2, 0xff, - 0xd0, 0x0, 0x0, 0xa, 0xf6, 0x0, 0x0, 0x4, - 0xfd, 0xe1, 0x0, 0x1, 0xeb, 0xd, 0xc0, 0x0, - 0xbe, 0x10, 0x3f, 0x80, 0x6f, 0x40, 0x0, 0x7f, - 0x40, - - /* U+0079 "y" */ - 0xd, 0xc0, 0x0, 0x0, 0xcb, 0x6, 0xf3, 0x0, - 0x2, 0xf4, 0x0, 0xea, 0x0, 0x9, 0xd0, 0x0, - 0x8f, 0x10, 0x1f, 0x70, 0x0, 0x1f, 0x70, 0x7f, - 0x10, 0x0, 0xa, 0xe0, 0xd9, 0x0, 0x0, 0x3, - 0xfa, 0xf2, 0x0, 0x0, 0x0, 0xcf, 0xb0, 0x0, - 0x0, 0x0, 0x6f, 0x40, 0x0, 0x0, 0x0, 0xad, - 0x0, 0x0, 0x1c, 0x69, 0xf6, 0x0, 0x0, 0x1b, - 0xfe, 0x70, 0x0, 0x0, - - /* U+007A "z" */ - 0x4f, 0xff, 0xff, 0xf9, 0x15, 0x55, 0x5b, 0xf4, - 0x0, 0x0, 0x3f, 0x80, 0x0, 0x1, 0xec, 0x0, - 0x0, 0xb, 0xe1, 0x0, 0x0, 0x8f, 0x40, 0x0, - 0x4, 0xf7, 0x0, 0x0, 0x1e, 0xe5, 0x55, 0x53, - 0x5f, 0xff, 0xff, 0xfc, - - /* U+007B "{" */ - 0x0, 0x2c, 0xf5, 0x0, 0xaf, 0x61, 0x0, 0xcc, - 0x0, 0x0, 0xdb, 0x0, 0x0, 0xdb, 0x0, 0x0, - 0xdb, 0x0, 0x1, 0xeb, 0x0, 0x1f, 0xf4, 0x0, - 0x4, 0xfa, 0x0, 0x0, 0xdb, 0x0, 0x0, 0xdb, - 0x0, 0x0, 0xdb, 0x0, 0x0, 0xcc, 0x0, 0x0, - 0xbf, 0x61, 0x0, 0x2c, 0xf5, - - /* U+007C "|" */ - 0x5f, 0x15, 0xf1, 0x5f, 0x15, 0xf1, 0x5f, 0x15, - 0xf1, 0x5f, 0x15, 0xf1, 0x5f, 0x15, 0xf1, 0x5f, - 0x15, 0xf1, 0x5f, 0x15, 0xf1, 0x5f, 0x10, - - /* U+007D "}" */ - 0xbf, 0x90, 0x3, 0xaf, 0x40, 0x1, 0xf6, 0x0, - 0x1f, 0x70, 0x1, 0xf7, 0x0, 0x1f, 0x70, 0x0, - 0xf9, 0x0, 0xa, 0xfb, 0x0, 0xfb, 0x20, 0x1f, - 0x70, 0x1, 0xf7, 0x0, 0x1f, 0x70, 0x1, 0xf6, - 0x3, 0xaf, 0x50, 0xbf, 0x90, 0x0, - - /* U+007E "~" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0xe5, 0x0, - 0xa5, 0xc, 0x85, 0xf6, 0x2e, 0x20, 0xf0, 0x4, - 0xef, 0xa0, 0x3, 0x0, 0x1, 0x20, 0x0, - - /* U+00B0 "°" */ - 0x2, 0xce, 0xa0, 0xd, 0x30, 0x89, 0x3a, 0x0, - 0xe, 0x3a, 0x0, 0xe, 0xd, 0x30, 0x89, 0x3, - 0xce, 0xa0, - - /* U+2022 "•" */ - 0x0, 0x8, 0xf9, 0xef, 0xe7, 0xf8 -}; - - -/*--------------------- - * GLYPH DESCRIPTION - *--------------------*/ - -static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { - {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 69, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 0, .adv_w = 69, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 18, .adv_w = 100, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 7}, - {.bitmap_index = 31, .adv_w = 180, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 97, .adv_w = 159, .box_w = 10, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 177, .adv_w = 216, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 255, .adv_w = 176, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 327, .adv_w = 54, .box_w = 2, .box_h = 5, .ofs_x = 1, .ofs_y = 7}, - {.bitmap_index = 332, .adv_w = 86, .box_w = 4, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 362, .adv_w = 87, .box_w = 4, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 392, .adv_w = 102, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 417, .adv_w = 149, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 453, .adv_w = 58, .box_w = 3, .box_h = 6, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 462, .adv_w = 98, .box_w = 6, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 471, .adv_w = 58, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 476, .adv_w = 90, .box_w = 8, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 540, .adv_w = 171, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 600, .adv_w = 95, .box_w = 5, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 630, .adv_w = 147, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 684, .adv_w = 146, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 738, .adv_w = 171, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 804, .adv_w = 147, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 858, .adv_w = 158, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 918, .adv_w = 153, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 972, .adv_w = 165, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1032, .adv_w = 158, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1092, .adv_w = 58, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1106, .adv_w = 58, .box_w = 3, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1124, .adv_w = 149, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 1156, .adv_w = 149, .box_w = 8, .box_h = 6, .ofs_x = 1, .ofs_y = 3}, - {.bitmap_index = 1180, .adv_w = 149, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 1212, .adv_w = 147, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1266, .adv_w = 265, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 1386, .adv_w = 187, .box_w = 13, .box_h = 12, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 1464, .adv_w = 194, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1530, .adv_w = 185, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1596, .adv_w = 211, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1668, .adv_w = 172, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1722, .adv_w = 163, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1776, .adv_w = 198, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1848, .adv_w = 208, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1914, .adv_w = 79, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1932, .adv_w = 131, .box_w = 8, .box_h = 12, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 1980, .adv_w = 184, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2046, .adv_w = 152, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2100, .adv_w = 244, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2178, .adv_w = 208, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2244, .adv_w = 215, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2322, .adv_w = 185, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2382, .adv_w = 215, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2487, .adv_w = 186, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2547, .adv_w = 159, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2607, .adv_w = 150, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2667, .adv_w = 202, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2733, .adv_w = 182, .box_w = 13, .box_h = 12, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 2811, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2919, .adv_w = 172, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2985, .adv_w = 166, .box_w = 12, .box_h = 12, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 3057, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3123, .adv_w = 85, .box_w = 5, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 3161, .adv_w = 90, .box_w = 8, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 3225, .adv_w = 85, .box_w = 4, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3255, .adv_w = 149, .box_w = 8, .box_h = 7, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 3283, .adv_w = 128, .box_w = 8, .box_h = 2, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3291, .adv_w = 154, .box_w = 5, .box_h = 2, .ofs_x = 1, .ofs_y = 10}, - {.bitmap_index = 3296, .adv_w = 153, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3337, .adv_w = 175, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3397, .adv_w = 146, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3438, .adv_w = 175, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3498, .adv_w = 157, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3543, .adv_w = 90, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3585, .adv_w = 177, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 3645, .adv_w = 174, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3699, .adv_w = 71, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3717, .adv_w = 73, .box_w = 6, .box_h = 15, .ofs_x = -2, .ofs_y = -3}, - {.bitmap_index = 3762, .adv_w = 158, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3816, .adv_w = 71, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3828, .adv_w = 271, .box_w = 15, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3896, .adv_w = 174, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3937, .adv_w = 163, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3982, .adv_w = 175, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 4042, .adv_w = 175, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 4102, .adv_w = 105, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 4129, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4165, .adv_w = 106, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4204, .adv_w = 173, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 4245, .adv_w = 143, .box_w = 10, .box_h = 9, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 4290, .adv_w = 230, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4358, .adv_w = 141, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4399, .adv_w = 143, .box_w = 10, .box_h = 12, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 4459, .adv_w = 133, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4495, .adv_w = 90, .box_w = 6, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 4540, .adv_w = 77, .box_w = 3, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 4563, .adv_w = 90, .box_w = 5, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 4601, .adv_w = 149, .box_w = 9, .box_h = 5, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 4624, .adv_w = 107, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 6}, - {.bitmap_index = 4642, .adv_w = 80, .box_w = 3, .box_h = 4, .ofs_x = 1, .ofs_y = 3} -}; - -/*--------------------- - * CHARACTER MAPPING - *--------------------*/ - -static const uint16_t unicode_list_1[] = { - 0x0, 0x1f72 -}; - -/*Collect the unicode lists and glyph_id offsets*/ -static const lv_font_fmt_txt_cmap_t cmaps[] = -{ - { - .range_start = 32, .range_length = 95, .glyph_id_start = 1, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 176, .range_length = 8051, .glyph_id_start = 96, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 2, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - } -}; - - - -/*-------------------- - * ALL CUSTOM DATA - *--------------------*/ - -#if LV_VERSION_CHECK(8, 0, 0) -/*Store all the custom data of the font*/ -static lv_font_fmt_txt_glyph_cache_t cache; -static const lv_font_fmt_txt_dsc_t font_dsc = { -#else -static lv_font_fmt_txt_dsc_t font_dsc = { -#endif - .glyph_bitmap = glyph_bitmap, - .glyph_dsc = glyph_dsc, - .cmaps = cmaps, - .kern_dsc = NULL, - .kern_scale = 0, - .cmap_num = 2, - .bpp = 4, - .kern_classes = 0, - .bitmap_format = 0, -#if LV_VERSION_CHECK(8, 0, 0) - .cache = &cache -#endif -}; - - -/*----------------- - * PUBLIC FONT - *----------------*/ - -/*Initialize a public general font descriptor*/ -#if LV_VERSION_CHECK(8, 0, 0) -const lv_font_t montserrat_16 = { -#else -lv_font_t montserrat_16 = { -#endif - .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ - .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 17, /*The maximum line height required by the font*/ - .base_line = 3, /*Baseline measured from the bottom of the line*/ -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) - .subpx = LV_FONT_SUBPX_NONE, -#endif -#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 - .underline_position = -2, - .underline_thickness = 1, -#endif - .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ -}; - - - -#endif /*#if MONTSERRAT_16*/ - diff --git a/src/robodash/core.c b/src/robodash/core.c deleted file mode 100644 index 558427d..0000000 --- a/src/robodash/core.c +++ /dev/null @@ -1,186 +0,0 @@ -#include "apix.h" -#include - -#define CLOSED_SIDEBAR_WIDTH 40 -#define OPEN_SIDEBAR_WIDTH 192 - -// ============================== UI Elements ============================== // - -lv_obj_t *screen; -lv_obj_t *view_cont; - -lv_obj_t *sidebar_open_btn; - -lv_obj_t *sidebar_open; -lv_obj_t *sidebar_close_btn; -lv_obj_t *view_list; -lv_obj_t *sidebar_modal; - -lv_anim_t anim_sidebar_open; -lv_anim_t anim_sidebar_close; -lv_anim_t anim_modal_hide; -lv_anim_t anim_modal_show; - -rd_view_t *current_view; - -// ============================== UI Callbacks ============================== // - -void view_btn_cb(lv_event_t *event) { rd_view_focus((rd_view_t *)lv_event_get_user_data(event)); } - -void open_sidebar(lv_event_t *event) { - lv_obj_clear_flag(sidebar_open, LV_OBJ_FLAG_HIDDEN); - lv_obj_clear_flag(sidebar_modal, LV_OBJ_FLAG_HIDDEN); - lv_anim_start(&anim_sidebar_open); - lv_anim_start(&anim_modal_show); -} - -void close_sidebar(lv_event_t *event) { - lv_anim_start(&anim_sidebar_close); - lv_anim_start(&anim_modal_hide); -} - -// =========================== UI Initialization =========================== // - -void create_ui() { - screen = lv_scr_act(); - lv_obj_clear_flag(screen, LV_OBJ_FLAG_SCROLLABLE); - - // View container - view_cont = lv_obj_create(screen); - lv_obj_set_size(view_cont, 480, 240); - lv_obj_add_style(view_cont, &style_bg, 0); - lv_obj_align(view_cont, LV_ALIGN_TOP_LEFT, 0, 0); - - sidebar_open_btn = lv_btn_create(screen); - lv_obj_set_size(sidebar_open_btn, 32, 32); - lv_obj_add_style(sidebar_open_btn, &style_bar_button, 0); - lv_obj_add_style(sidebar_open_btn, &style_bar_button_pr, LV_STATE_PRESSED); - lv_obj_align(sidebar_open_btn, LV_ALIGN_TOP_RIGHT, -4, 4); - lv_obj_add_event_cb(sidebar_open_btn, open_sidebar, LV_EVENT_PRESSED, NULL); - - lv_obj_t *open_img = lv_img_create(sidebar_open_btn); - lv_img_set_src(open_img, &stack); - lv_obj_set_style_img_recolor(open_img, color_text, 0); - lv_obj_set_style_img_recolor_opa(open_img, LV_OPA_COVER, 0); - lv_obj_align(open_img, LV_ALIGN_CENTER, 0, 0); - - // Modal - sidebar_modal = lv_obj_create(screen); - lv_obj_set_size(sidebar_modal, LV_PCT(100), LV_PCT(100)); - lv_obj_add_style(sidebar_modal, &style_bar_modal, 0); - lv_obj_add_flag(sidebar_modal, LV_OBJ_FLAG_HIDDEN); - lv_obj_add_event_cb(sidebar_modal, close_sidebar, LV_EVENT_PRESSED, NULL); - - // Open sidebar - sidebar_open = lv_obj_create(screen); - lv_obj_set_size(sidebar_open, OPEN_SIDEBAR_WIDTH, 240); - lv_obj_align(sidebar_open, LV_ALIGN_TOP_RIGHT, 0, 0); - lv_obj_add_style(sidebar_open, &style_bar_bg, 0); - lv_obj_add_flag(sidebar_open, LV_OBJ_FLAG_HIDDEN); - - lv_obj_t *title = lv_label_create(sidebar_open); - lv_label_set_text(title, "Select View"); - lv_obj_add_style(title, &style_text_large, 0); - lv_obj_align(title, LV_ALIGN_TOP_LEFT, 12, 12); - - sidebar_close_btn = lv_btn_create(sidebar_open); - lv_obj_set_size(sidebar_close_btn, 32, 32); - lv_obj_add_style(sidebar_close_btn, &style_transp, 0); - lv_obj_add_style(sidebar_close_btn, &style_transp, LV_STATE_PRESSED); - lv_obj_align(sidebar_close_btn, LV_ALIGN_TOP_RIGHT, -4, 4); - lv_obj_add_event_cb(sidebar_close_btn, close_sidebar, LV_EVENT_PRESSED, NULL); - - lv_obj_t *close_img = lv_img_create(sidebar_close_btn); - lv_img_set_src(close_img, LV_SYMBOL_CLOSE); - lv_obj_align(close_img, LV_ALIGN_CENTER, 0, 0); - - // View switcher - view_list = lv_list_create(sidebar_open); - lv_obj_set_size(view_list, LV_PCT(100) - 8, LV_PCT(100) - 32); - lv_obj_add_style(view_list, &style_bar_list, 0); - lv_obj_align(view_list, LV_ALIGN_TOP_LEFT, 4, 36); -} - -void create_anims() { - // Sidebar animations - lv_anim_init(&anim_sidebar_open); - lv_anim_set_var(&anim_sidebar_open, sidebar_open); - lv_anim_set_time(&anim_sidebar_open, 200); - lv_anim_set_exec_cb(&anim_sidebar_open, &anim_x_cb); - - anim_sidebar_close = anim_sidebar_open; - - lv_anim_set_path_cb(&anim_sidebar_open, &lv_anim_path_ease_out); - lv_anim_set_values(&anim_sidebar_open, OPEN_SIDEBAR_WIDTH, 0); - - lv_anim_set_values(&anim_sidebar_close, 0, OPEN_SIDEBAR_WIDTH); - lv_anim_set_path_cb(&anim_sidebar_close, &lv_anim_path_ease_out); - - // Modal animations - lv_anim_init(&anim_modal_hide); - lv_anim_set_var(&anim_modal_hide, sidebar_modal); - lv_anim_set_time(&anim_modal_hide, 200); - lv_anim_set_exec_cb(&anim_modal_hide, &anim_opa_cb); - - anim_modal_show = anim_modal_hide; - - lv_anim_set_values(&anim_modal_hide, 144, 0); - lv_anim_set_deleted_cb(&anim_modal_hide, &anim_del_cb); - lv_anim_set_values(&anim_modal_show, 0, 144); -} - -// =============================== Initialize =============================== // - -bool initialized = false; - -void initialize() { - if (initialized) return; - - _init_fs(); - _init_styles(); - - create_ui(); - create_anims(); - - initialized = true; -} - -// =============================== View Class =============================== // - -rd_view_t *rd_view_create(const char *name) { - initialize(); - - rd_view_t *view = (rd_view_t *)malloc(sizeof(rd_view_t)); - - view->obj = lv_obj_create(lv_scr_act()); - lv_obj_set_size(view->obj, lv_pct(100), lv_pct(100)); - lv_obj_add_flag(view->obj, LV_OBJ_FLAG_HIDDEN); - lv_obj_add_style(view->obj, &style_bg, 0); - - lv_obj_set_parent(view->obj, view_cont); - if (!current_view) rd_view_focus(view); - - view->_btn = lv_list_add_btn(view_list, NULL, name); - lv_obj_add_style(view->_btn, &style_bar_list_btn, 0); - lv_obj_add_style(view->_btn, &style_list_btn_pr, LV_STATE_PRESSED); - lv_obj_add_event_cb(view->_btn, view_btn_cb, LV_EVENT_PRESSED, view); - lv_obj_add_event_cb(view->_btn, close_sidebar, LV_EVENT_PRESSED, NULL); - - return view; -} - -void rd_view_del(rd_view_t *view) { - lv_obj_del(view->_btn); - lv_obj_del(view->obj); - if (current_view == view) current_view = NULL; - free(view); -} - -lv_obj_t *rd_view_obj(rd_view_t *view) { return view->obj; } - -void rd_view_focus(rd_view_t *view) { - if (view == NULL) return; - if (current_view != NULL) lv_obj_add_flag(current_view->obj, LV_OBJ_FLAG_HIDDEN); - current_view = view; - lv_obj_clear_flag(current_view->obj, LV_OBJ_FLAG_HIDDEN); -} diff --git a/src/robodash/core.cpp b/src/robodash/core.cpp new file mode 100644 index 0000000..7b74716 --- /dev/null +++ b/src/robodash/core.cpp @@ -0,0 +1,337 @@ +#include "apix.h" + +const int view_menu_width = 192; + +// ============================== UI Elements ============================== // + +lv_obj_t *screen; +lv_obj_t *view_cont; + +lv_obj_t *shade; +lv_obj_t *view_menu; +lv_obj_t *view_list; +lv_obj_t *alert_cont; +lv_obj_t *alert_btn; +lv_obj_t *anim_label; + +lv_anim_t anim_sidebar_open; +lv_anim_t anim_sidebar_close; +lv_anim_t anim_shade_hide; +lv_anim_t anim_shade_show; + +rd_view_t *current_view; + +// ============================ Helper Functions============================ // + +bool valid_view(rd_view_t *view) { + if (view == NULL) return false; + + for (int i = 0; i < lv_obj_get_child_cnt(view_list); i++) { + lv_obj_t *child = lv_obj_get_child(view_list, i); + rd_view_t *reg_view = (rd_view_t *)lv_obj_get_user_data(child); + if (reg_view == view) return true; + } + + return false; +} + +// ============================== UI Callbacks ============================== // + +void view_focus_cb(lv_event_t *event) { + rd_view_t *view = (rd_view_t *)lv_event_get_user_data(event); + rd_view_focus(view); +} + +void views_btn_cb(lv_event_t *event) { + lv_obj_clear_flag(view_menu, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(shade, LV_OBJ_FLAG_HIDDEN); + + if (rd_view_get_anims(current_view) == RD_ANIM_ON) { + lv_anim_start(&anim_sidebar_open); + lv_anim_start(&anim_shade_show); + } +} + +void close_cb(lv_event_t *event) { + if (lv_obj_get_child_cnt(alert_cont) > 0) { + lv_obj_clear_flag(alert_btn, LV_OBJ_FLAG_HIDDEN); + } + + lv_obj_add_flag(alert_cont, LV_OBJ_FLAG_HIDDEN); + + if (rd_view_get_anims(current_view) == RD_ANIM_ON) { + lv_anim_start(&anim_sidebar_close); + lv_anim_start(&anim_shade_hide); + } else { + lv_obj_add_flag(view_menu, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(shade, LV_OBJ_FLAG_HIDDEN); + } +} + +void alert_btn_cb(lv_event_t *event) { + if (!lv_obj_has_flag(alert_cont, LV_OBJ_FLAG_HIDDEN)) return; + lv_obj_add_flag(alert_btn, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(alert_cont, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(shade, LV_OBJ_FLAG_HIDDEN); + if (rd_view_get_anims(current_view) == RD_ANIM_ON) lv_anim_start(&anim_shade_show); +} + +void alert_cb(lv_event_t *event) { + rd_view_t *view = (rd_view_t *)lv_event_get_user_data(event); + rd_view_focus(view); + + lv_obj_t *alert = lv_event_get_target(event); + lv_obj_del(alert); + + if (lv_obj_get_child_cnt(alert_cont) == 0) { + lv_obj_add_flag(alert_cont, LV_OBJ_FLAG_HIDDEN); + + if (rd_view_get_anims(current_view) == RD_ANIM_ON) { + lv_anim_start(&anim_shade_hide); + } else { + lv_obj_add_flag(shade, LV_OBJ_FLAG_HIDDEN); + } + } +} + +// =========================== UI Initialization =========================== // + +void create_ui() { + screen = lv_scr_act(); + lv_obj_clear_flag(screen, LV_OBJ_FLAG_SCROLLABLE); + + view_cont = lv_obj_create(screen); + lv_obj_set_size(view_cont, 480, 240); + lv_obj_add_style(view_cont, &style_bg, 0); + lv_obj_align(view_cont, LV_ALIGN_TOP_LEFT, 0, 0); + + // ---------------------------- Top Buttons ---------------------------- // + + lv_obj_t *views_open_btn = lv_btn_create(screen); + lv_obj_set_size(views_open_btn, 32, 32); + lv_obj_add_style(views_open_btn, &style_core_button, 0); + lv_obj_add_style(views_open_btn, &style_core_button_pr, LV_STATE_PRESSED); + lv_obj_align(views_open_btn, LV_ALIGN_TOP_RIGHT, -4, 4); + lv_obj_add_event_cb(views_open_btn, views_btn_cb, LV_EVENT_PRESSED, NULL); + + lv_obj_t *open_img = lv_img_create(views_open_btn); + lv_img_set_src(open_img, &stack); + lv_obj_set_style_img_recolor(open_img, color_text, 0); + lv_obj_set_style_img_recolor_opa(open_img, LV_OPA_COVER, 0); + lv_obj_align(open_img, LV_ALIGN_CENTER, 0, 0); + + alert_btn = lv_btn_create(screen); + lv_obj_set_size(alert_btn, 32, 32); + lv_obj_add_style(alert_btn, &style_core_button, 0); + lv_obj_add_style(alert_btn, &style_core_button_pr, LV_STATE_PRESSED); + lv_obj_align(alert_btn, LV_ALIGN_TOP_RIGHT, -42, 4); + lv_obj_add_event_cb(alert_btn, alert_btn_cb, LV_EVENT_PRESSED, NULL); + lv_obj_add_flag(alert_btn, LV_OBJ_FLAG_HIDDEN); + + lv_obj_t *alert_img = lv_img_create(alert_btn); + lv_img_set_src(alert_img, LV_SYMBOL_BELL); + lv_obj_set_style_img_recolor(alert_img, color_text, 0); + lv_obj_set_style_img_recolor_opa(alert_img, LV_OPA_COVER, 0); + lv_obj_align(alert_img, LV_ALIGN_CENTER, 0, 0); + + // ------------------------------- Shade ------------------------------- // + + shade = lv_obj_create(screen); + lv_obj_set_size(shade, lv_pct(100), lv_pct(100)); + lv_obj_add_style(shade, &style_core_shade, 0); + lv_obj_add_flag(shade, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_event_cb(shade, close_cb, LV_EVENT_PRESSED, NULL); + + // ----------------------------- View Menu ----------------------------- // + + view_menu = lv_obj_create(screen); + lv_obj_set_size(view_menu, view_menu_width, 240); + lv_obj_align(view_menu, LV_ALIGN_TOP_RIGHT, 0, 0); + lv_obj_add_style(view_menu, &style_core_bg, 0); + lv_obj_add_flag(view_menu, LV_OBJ_FLAG_HIDDEN); + + lv_obj_t *title = lv_label_create(view_menu); + lv_label_set_text(title, "Select View"); + lv_obj_add_style(title, &style_text_large, 0); + lv_obj_align(title, LV_ALIGN_TOP_LEFT, 12, 12); + + lv_obj_t *views_close_btn = lv_btn_create(view_menu); + lv_obj_set_size(views_close_btn, 32, 32); + lv_obj_add_style(views_close_btn, &style_transp, 0); + lv_obj_add_style(views_close_btn, &style_transp, LV_STATE_PRESSED); + lv_obj_align(views_close_btn, LV_ALIGN_TOP_RIGHT, -4, 4); + lv_obj_add_event_cb(views_close_btn, close_cb, LV_EVENT_PRESSED, NULL); + + lv_obj_t *close_img = lv_img_create(views_close_btn); + lv_img_set_src(close_img, LV_SYMBOL_CLOSE); + lv_obj_align(close_img, LV_ALIGN_CENTER, 0, 0); + + view_list = lv_list_create(view_menu); + lv_obj_set_size(view_list, lv_pct(100) - 8, lv_pct(100) - 32); + lv_obj_add_style(view_list, &style_core_list, 0); + lv_obj_align(view_list, LV_ALIGN_TOP_LEFT, 4, 36); + + anim_label = lv_label_create(view_menu); + lv_label_set_text(anim_label, "Animations are disabled\nfor this view"); + lv_obj_add_style(anim_label, &style_text_small, 0); + lv_obj_add_style(anim_label, &style_text_centered, 0); + lv_obj_align(anim_label, LV_ALIGN_BOTTOM_MID, 0, -2); + lv_obj_add_flag(anim_label, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_text_font(anim_label, &lv_font_montserrat_10, 0); + + // -------------------------- Alert Container -------------------------- // + + alert_cont = lv_obj_create(screen); + lv_obj_set_size(alert_cont, 320, lv_pct(100)); + lv_obj_align(alert_cont, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_style(alert_cont, &style_transp, 0); + lv_obj_clear_flag(alert_cont, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_flex_align( + alert_cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START + ); + lv_obj_set_flex_flow(alert_cont, LV_FLEX_FLOW_COLUMN); +} + +void create_anims() { + // ------------------------- Sidebar Animations ------------------------- // + + lv_anim_init(&anim_sidebar_open); + lv_anim_set_var(&anim_sidebar_open, view_menu); + lv_anim_set_time(&anim_sidebar_open, 200); + lv_anim_set_exec_cb(&anim_sidebar_open, &anim_x_cb); + + anim_sidebar_close = anim_sidebar_open; + + lv_anim_set_path_cb(&anim_sidebar_open, &lv_anim_path_ease_out); + lv_anim_set_values(&anim_sidebar_open, view_menu_width, 0); + + lv_anim_set_values(&anim_sidebar_close, 0, view_menu_width); + lv_anim_set_deleted_cb(&anim_sidebar_close, &anim_del_cb); + lv_anim_set_path_cb(&anim_sidebar_close, &lv_anim_path_ease_out); + + // -------------------------- Shade Animations -------------------------- // + + lv_anim_init(&anim_shade_hide); + lv_anim_set_var(&anim_shade_hide, shade); + lv_anim_set_time(&anim_shade_hide, 200); + lv_anim_set_exec_cb(&anim_shade_hide, &anim_opa_cb); + + anim_shade_show = anim_shade_hide; + + lv_anim_set_values(&anim_shade_hide, 144, 0); + lv_anim_set_deleted_cb(&anim_shade_hide, &anim_del_cb); + lv_anim_set_values(&anim_shade_show, 0, 144); +} + +// =============================== Initialize =============================== // + +bool initialized = false; + +void initialize() { + if (initialized) return; + + _init_fs(); + _init_styles(); + + create_ui(); + create_anims(); + + initialized = true; +} + +// =============================== View Class =============================== // + +rd_view_t *rd_view_create(const char *name) { + initialize(); + + rd_view_t *view = (rd_view_t *)malloc(sizeof(rd_view_t)); + + view->obj = lv_obj_create(lv_scr_act()); + lv_obj_set_size(view->obj, lv_pct(100), lv_pct(100)); + lv_obj_add_flag(view->obj, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_style(view->obj, &style_bg, 0); + lv_obj_set_parent(view->obj, view_cont); + + view->_list_btn = lv_list_add_btn(view_list, NULL, name); + lv_obj_add_style(view->_list_btn, &style_core_list_btn, 0); + lv_obj_add_style(view->_list_btn, &style_list_btn_pr, LV_STATE_PRESSED); + lv_obj_set_user_data(view->_list_btn, view); + lv_obj_add_event_cb(view->_list_btn, view_focus_cb, LV_EVENT_PRESSED, view); + lv_obj_add_event_cb(view->_list_btn, close_cb, LV_EVENT_PRESSED, NULL); + + view->name = name; + view->anims = RD_ANIM_ON; + + if (!current_view) rd_view_focus(view); + + return view; +} + +void rd_view_del(rd_view_t *view) { + if (!valid_view(view)) return; + + lv_obj_del(view->_list_btn); + lv_obj_del(view->obj); + if (current_view == view) current_view = NULL; + + free(view); +} + +void rd_view_set_anims(rd_view_t *view, rd_anim_state_t state) { view->anims = state; } + +rd_anim_state_t rd_view_get_anims(rd_view_t *view) { return view->anims; } + +lv_obj_t *rd_view_obj(rd_view_t *view) { + if (!valid_view(view)) return NULL; + + return view->obj; +} + +void rd_view_focus(rd_view_t *view) { + if (!valid_view(view)) return; + + if (current_view != NULL) lv_obj_add_flag(current_view->obj, LV_OBJ_FLAG_HIDDEN); + current_view = view; + lv_obj_clear_flag(current_view->obj, LV_OBJ_FLAG_HIDDEN); + + if (rd_view_get_anims(current_view) == RD_ANIM_ON) + lv_obj_add_flag(anim_label, LV_OBJ_FLAG_HIDDEN); + else + lv_obj_clear_flag(anim_label, LV_OBJ_FLAG_HIDDEN); +} + +void rd_view_alert(rd_view_t *view, const char *msg) { + if (!valid_view(view)) return; + + if (!lv_obj_has_flag(view_menu, LV_OBJ_FLAG_HIDDEN)) { + if (rd_view_get_anims(current_view) == RD_ANIM_ON) + lv_anim_start(&anim_sidebar_close); + else + lv_obj_add_flag(view_menu, LV_OBJ_FLAG_HIDDEN); + } + + if (lv_obj_has_flag(shade, LV_OBJ_FLAG_HIDDEN)) { + lv_obj_clear_flag(shade, LV_OBJ_FLAG_HIDDEN); + if (rd_view_get_anims(current_view) == RD_ANIM_ON) lv_anim_start(&anim_shade_show); + } + + lv_obj_clear_flag(alert_cont, LV_OBJ_FLAG_HIDDEN); + + lv_obj_t *alert = lv_obj_create(alert_cont); + lv_obj_set_width(alert, lv_pct(100)); + lv_obj_set_height(alert, LV_SIZE_CONTENT); + lv_obj_add_event_cb(alert, alert_cb, LV_EVENT_CLICKED, view); + lv_obj_add_style(alert, &style_alert, 0); + + lv_obj_t *origin_label = lv_label_create(alert); + lv_obj_align(origin_label, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_add_style(origin_label, &style_text_small, 0); + lv_label_set_text(origin_label, view->name); + + lv_obj_t *alert_msg = lv_label_create(alert); + lv_obj_align(alert_msg, LV_ALIGN_TOP_LEFT, 0, 18); + lv_obj_set_width(alert_msg, lv_pct(100)); + lv_obj_add_style(alert_msg, &style_text_medium, 0); + lv_label_set_long_mode(alert_msg, LV_LABEL_LONG_WRAP); + lv_label_set_text(alert_msg, msg); +} \ No newline at end of file diff --git a/src/robodash/styles/bar.c b/src/robodash/styles/bar.c deleted file mode 100644 index 2152007..0000000 --- a/src/robodash/styles/bar.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "robodash/apix.h" - -// ================================== Bar ================================== // - -lv_style_t style_bar_button; -lv_style_t style_bar_button_pr; -lv_style_t style_bar_list; -lv_style_t style_bar_list_btn; -lv_style_t style_bar_bg; -lv_style_t style_bar_modal; - -void _init_style_bar() { - // Sidebar button - lv_style_init(&style_bar_button); - lv_style_set_pad_all(&style_bar_button, 8); - lv_style_set_bg_color(&style_bar_button, color_bar); - lv_style_set_radius(&style_bar_button, 4); - lv_style_set_border_color(&style_bar_button, color_bar_outline); - lv_style_set_border_width(&style_bar_button, 0); - lv_style_set_shadow_width(&style_bar_button, 0); - lv_style_set_text_color(&style_bar_button, color_text); - lv_style_set_img_recolor(&style_bar_button, color_text); - - // Sidebar button pressed - lv_style_init(&style_bar_button_pr); - lv_style_set_bg_color(&style_bar_button_pr, color_bar_dark); - - // Sidebar list - lv_style_init(&style_bar_list); - lv_style_set_text_color(&style_bar_list, color_text); - lv_style_set_border_color(&style_bar_list, color_border); - lv_style_set_border_width(&style_bar_list, 0); - lv_style_set_bg_color(&style_bar_list, color_bar); - lv_style_set_pad_all(&style_bar_list, 8); - - // Sidebar list button - lv_style_init(&style_bar_list_btn); - lv_style_set_border_color(&style_bar_list_btn, color_bar_outline); - lv_style_set_border_width(&style_bar_list_btn, 1); - lv_style_set_border_opa(&style_bar_list_btn, LV_OPA_COVER); - lv_style_set_border_side(&style_bar_list_btn, LV_BORDER_SIDE_BOTTOM); - lv_style_set_text_color(&style_bar_list_btn, color_text); - lv_style_set_radius(&style_bar_list_btn, 0); - lv_style_set_bg_color(&style_bar_list_btn, color_bar); - - // Sidebar background - lv_style_init(&style_bar_bg); - lv_style_set_border_width(&style_bar_bg, 0); - lv_style_set_radius(&style_bar_bg, 0); - lv_style_set_bg_color(&style_bar_bg, color_bar); - lv_style_set_text_color(&style_bar_bg, color_text); - lv_style_set_pad_all(&style_bar_bg, 0); - - // Sidebar modal - lv_style_init(&style_bar_modal); - lv_style_set_bg_opa(&style_bar_modal, 144); - lv_style_set_bg_color(&style_bar_modal, lv_color_black()); - lv_style_set_radius(&style_bar_modal, 0); - lv_style_set_border_width(&style_bar_modal, 0); -} \ No newline at end of file diff --git a/src/robodash/styles/colors.c b/src/robodash/styles/colors.c index eb71970..7de7991 100644 --- a/src/robodash/styles/colors.c +++ b/src/robodash/styles/colors.c @@ -10,6 +10,7 @@ lv_color_t color_shade; lv_color_t color_primary; lv_color_t color_primary_dark; lv_color_t color_text; +lv_color_t color_red; lv_color_t color_bar; lv_color_t color_bar_dark; @@ -25,4 +26,5 @@ void _init_colors() { color_bar = lv_color_hsv_to_rgb(hue, 50, 25); color_bar_dark = lv_color_hsv_to_rgb(hue, 50, 15); color_bar_outline = lv_color_hsv_to_rgb(hue, 10, 50); + color_red = lv_color_hsv_to_rgb(0, 75, 100); } diff --git a/src/robodash/styles/core.c b/src/robodash/styles/core.c new file mode 100644 index 0000000..d87383d --- /dev/null +++ b/src/robodash/styles/core.c @@ -0,0 +1,60 @@ +#include "robodash/apix.h" + +// ================================== Core ================================== // + +lv_style_t style_core_button; +lv_style_t style_core_button_pr; +lv_style_t style_core_list; +lv_style_t style_core_list_btn; +lv_style_t style_core_bg; +lv_style_t style_core_shade; + +void _init_style_core() { + // Sidebar button + lv_style_init(&style_core_button); + lv_style_set_pad_all(&style_core_button, 8); + lv_style_set_bg_color(&style_core_button, color_bar); + lv_style_set_radius(&style_core_button, 4); + lv_style_set_border_color(&style_core_button, color_bar_outline); + lv_style_set_border_width(&style_core_button, 0); + lv_style_set_shadow_width(&style_core_button, 0); + lv_style_set_text_color(&style_core_button, color_text); + lv_style_set_img_recolor(&style_core_button, color_text); + + // Sidebar button pressed + lv_style_init(&style_core_button_pr); + lv_style_set_bg_color(&style_core_button_pr, color_bar_dark); + + // Sidebar list + lv_style_init(&style_core_list); + lv_style_set_text_color(&style_core_list, color_text); + lv_style_set_border_color(&style_core_list, color_border); + lv_style_set_border_width(&style_core_list, 0); + lv_style_set_bg_color(&style_core_list, color_bar); + lv_style_set_pad_all(&style_core_list, 8); + + // Sidebar list button + lv_style_init(&style_core_list_btn); + lv_style_set_border_color(&style_core_list_btn, color_bar_outline); + lv_style_set_border_width(&style_core_list_btn, 1); + lv_style_set_border_opa(&style_core_list_btn, LV_OPA_COVER); + lv_style_set_border_side(&style_core_list_btn, LV_BORDER_SIDE_BOTTOM); + lv_style_set_text_color(&style_core_list_btn, color_text); + lv_style_set_radius(&style_core_list_btn, 0); + lv_style_set_bg_color(&style_core_list_btn, color_bar); + + // Sidebar background + lv_style_init(&style_core_bg); + lv_style_set_border_width(&style_core_bg, 0); + lv_style_set_radius(&style_core_bg, 0); + lv_style_set_bg_color(&style_core_bg, color_bar); + lv_style_set_text_color(&style_core_bg, color_text); + lv_style_set_pad_all(&style_core_bg, 0); + + // Sidebar modal + lv_style_init(&style_core_shade); + lv_style_set_bg_opa(&style_core_shade, 144); + lv_style_set_bg_color(&style_core_shade, lv_color_black()); + lv_style_set_radius(&style_core_shade, 0); + lv_style_set_border_width(&style_core_shade, 0); +} \ No newline at end of file diff --git a/src/robodash/styles/initialize.c b/src/robodash/styles/initialize.c index 08a162e..af8baa9 100644 --- a/src/robodash/styles/initialize.c +++ b/src/robodash/styles/initialize.c @@ -6,5 +6,5 @@ void _init_styles() { _init_style_text(); _init_style_btn(); _init_style_list(); - _init_style_bar(); + _init_style_core(); } \ No newline at end of file diff --git a/src/robodash/styles/misc.c b/src/robodash/styles/misc.c index f97bc84..98e7ed3 100644 --- a/src/robodash/styles/misc.c +++ b/src/robodash/styles/misc.c @@ -4,6 +4,7 @@ lv_style_t style_bg; lv_style_t style_transp; +lv_style_t style_alert; void _init_style_misc() { // Background @@ -21,4 +22,14 @@ void _init_style_misc() { lv_style_set_radius(&style_transp, 0); lv_style_set_pad_all(&style_transp, 0); lv_style_set_shadow_width(&style_transp, 0); + + // Alert style + lv_style_init(&style_alert); + lv_style_set_radius(&style_alert, 4); + lv_style_set_bg_color(&style_alert, color_red); + lv_style_set_border_width(&style_alert, 0); + lv_style_set_pad_all(&style_alert, 8); + lv_style_set_img_recolor(&style_alert, color_bg); + lv_style_set_text_color(&style_alert, color_text); + lv_style_set_shadow_opa(&style_alert, LV_OPA_TRANSP); } \ No newline at end of file diff --git a/src/robodash/styles/text.c b/src/robodash/styles/text.c index 33561d5..b3cefbc 100644 --- a/src/robodash/styles/text.c +++ b/src/robodash/styles/text.c @@ -20,7 +20,7 @@ void _init_style_text() { lv_style_init(&style_text_small); lv_style_set_text_color(&style_text_small, color_text); lv_style_set_text_opa(&style_text_small, LV_OPA_COVER); - lv_style_set_text_font(&style_text_small, &montserrat_12); + lv_style_set_text_font(&style_text_small, &lv_font_montserrat_12); lv_style_set_text_letter_space(&style_text_small, 1); // Medium text @@ -34,7 +34,7 @@ void _init_style_text() { lv_style_init(&style_text_large); lv_style_set_text_color(&style_text_large, color_text); lv_style_set_text_opa(&style_text_large, LV_OPA_COVER); - lv_style_set_text_font(&style_text_large, &montserrat_16); + lv_style_set_text_font(&style_text_large, &lv_font_montserrat_16); // Text align lv_style_init(&style_text_centered); diff --git a/src/robodash/views/console.cpp b/src/robodash/views/console.cpp index 3f762ca..249c0d4 100644 --- a/src/robodash/views/console.cpp +++ b/src/robodash/views/console.cpp @@ -1,9 +1,5 @@ #include "console.hpp" #include "robodash/apix.h" -#include - -lv_obj_t *output; -std::ostringstream stream; // ============================= Core Functions ============================= // @@ -12,25 +8,32 @@ rd::Console::Console(std::string name) { lv_obj_set_style_bg_color(view->obj, color_bg, 0); - output = lv_label_create(view->obj); - lv_obj_set_size(output, 464, 224); - lv_obj_align(output, LV_ALIGN_CENTER, 0, 0); + this->output_cont = lv_obj_create(view->obj); + lv_obj_set_width(output_cont, lv_pct(100)); + lv_obj_set_height(output_cont, lv_pct(100)); + lv_obj_align(output_cont, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_style(output_cont, &style_transp, 0); + + this->output = lv_label_create(output_cont); + lv_obj_set_height(output, LV_SIZE_CONTENT); lv_obj_add_style(output, &style_transp, 0); lv_obj_add_style(output, &style_text_mono, 0); lv_label_set_recolor(output, true); + lv_label_set_long_mode(output, LV_LABEL_LONG_WRAP); } // =========================== Console Functions =========================== // void rd::Console::clear() { - lv_label_set_text(output, ""); - stream.str(""); - stream.clear(); + lv_label_set_text(this->output, ""); + this->stream.str(""); + this->stream.clear(); } void rd::Console::print(std::string str) { - stream << str; - if (output) lv_label_set_text(output, stream.str().c_str()); + this->stream << str; + if (this->output) lv_label_set_text(this->output, this->stream.str().c_str()); + lv_obj_scroll_to_y(this->output_cont, LV_COORD_MAX, LV_ANIM_OFF); } void rd::Console::println(std::string str) { this->print(str + "\n"); } diff --git a/src/robodash/views/image.cpp b/src/robodash/views/image.cpp index 1962097..99e6215 100644 --- a/src/robodash/views/image.cpp +++ b/src/robodash/views/image.cpp @@ -10,6 +10,7 @@ rd::Image::Image(lv_img_dsc_t image_dsc, std::string name) { lv_obj_t *image = lv_img_create(view->obj); lv_img_set_src(image, &image_dsc); lv_obj_align(image, LV_ALIGN_CENTER, 0, 0); + rd_view_set_anims(this->view, RD_ANIM_OFF); } rd::Image::Image(std::string path, std::string name) { @@ -19,6 +20,7 @@ rd::Image::Image(std::string path, std::string name) { lv_obj_t *image = lv_img_create(view->obj); lv_img_set_src(image, ("S:" + path).c_str()); lv_obj_align(image, LV_ALIGN_CENTER, 0, 0); + rd_view_set_anims(this->view, RD_ANIM_OFF); } void rd::Image::focus() { rd_view_focus(this->view); } \ No newline at end of file diff --git a/src/robodash/views/selector.cpp b/src/robodash/views/selector.cpp index a31415b..1f9e933 100644 --- a/src/robodash/views/selector.cpp +++ b/src/robodash/views/selector.cpp @@ -1,51 +1,32 @@ #include "api.h" #include "robodash/apix.h" -// ============================= Routine Class ============================= // - -class Routine { - public: - Routine(int id, std::string name, std::function action) - : id(id), name(name), action(action) {} - - int id; - std::string name; - std::function action; -}; - // =============================== Variables =============================== // -std::vector routines; -Routine *selected_routine = nullptr; -bool selection_done = false; -bool selection_running = false; +// TODO: Make variables members, so multiple selectors can be used -int saved_id; -char saved_name[256]; +std::vector routines; +rd::Selector::routine_t *selected_routine = nullptr; lv_obj_t *select_cont; lv_obj_t *selected_label; lv_obj_t *saved_toast; -lv_obj_t *routine_list; lv_anim_t anim_toast; // ============================= SD Card Saving ============================= // -void sdconf_save() { +void sd_save() { FILE *save_file; - save_file = fopen("/usd/autoconf.txt", "w"); + save_file = fopen("/usd/rd_auton.txt", "w"); if (selected_routine == nullptr) { - fputs("-1", save_file); + fputs("", save_file); } else { - std::string routine_name = selected_routine->name; - int routine_id = selected_routine->id; + std::string routine_name = selected_routine->first; - // File format: - // [id] [name] - char file_data[sizeof(routine_name) + sizeof(routine_id) + 1]; - sprintf(file_data, "%d %s", routine_id, routine_name.c_str()); + char file_data[sizeof(routine_name)]; + sprintf(file_data, "%s", routine_name.c_str()); fputs(file_data, save_file); } @@ -53,9 +34,9 @@ void sdconf_save() { fclose(save_file); } -void sdconf_load() { +void sd_load() { FILE *save_file; - save_file = fopen("/usd/autoconf.txt", "r"); + save_file = fopen("/usd/rd_auton.txt", "r"); if (!save_file) return; // Get file size @@ -64,15 +45,12 @@ void sdconf_load() { rewind(save_file); // Read contents - fscanf(save_file, "%d %[^\n]", &saved_id, saved_name); + char saved_name[file_size]; + fscanf(save_file, "%[^\n]", saved_name); fclose(save_file); -} - -void load_saved() { - if (!saved_id) return; // None selected condition - if (saved_id == -1) { + if (strcmp(saved_name, "") == 0) { lv_label_set_text(selected_label, "No routine\nselected"); lv_obj_align(selected_label, LV_ALIGN_CENTER, 120, 0); @@ -80,39 +58,33 @@ void load_saved() { return; } - // Out of bounds check - if (routines.size() < saved_id + 1) return; - - Routine selected = routines.at(saved_id); - std::string routine_name = selected.name; - - // Exit if routine name does not match saved - if (saved_name != routine_name) return; - - selected_routine = &selected; + for (rd::Selector::routine_t &r : routines) { + if (strcmp(r.first.c_str(), saved_name) == 0) selected_routine = &r; + } - // Update routine label - char label_str[sizeof(routine_name) + 20]; - sprintf(label_str, "Selected routine:\n%s", routine_name.c_str()); - lv_label_set_text(selected_label, label_str); - lv_obj_align(selected_label, LV_ALIGN_CENTER, 120, 0); + if (selected_routine != nullptr) { + // Update routine label + char label_str[sizeof(saved_name) + 20]; + sprintf(label_str, "Selected routine:\n%s", selected_routine->first.c_str()); + lv_label_set_text(selected_label, label_str); + lv_obj_align(selected_label, LV_ALIGN_CENTER, 120, 0); + } } // ============================== UI Callbacks ============================== // void r_select_act(lv_event_t *event) { - lv_obj_t *obj = lv_event_get_target(event); - Routine *routine = (Routine *)lv_event_get_user_data(event); + rd::Selector::routine_t *routine = (rd::Selector::routine_t *)lv_event_get_user_data(event); if (routine == nullptr) { lv_label_set_text(selected_label, "No routine\nselected"); lv_obj_align(selected_label, LV_ALIGN_CENTER, 120, 0); } else { - std::string routine_name = routine->name; + const char *routine_name = routine->first.c_str(); char label_str[sizeof(routine_name) + 20]; - sprintf(label_str, "Selected routine:\n%s", routine_name.c_str()); + sprintf(label_str, "Selected routine:\n%s", routine_name); lv_label_set_text(selected_label, label_str); lv_obj_align(selected_label, LV_ALIGN_CENTER, 120, 0); } @@ -120,22 +92,23 @@ void r_select_act(lv_event_t *event) { selected_routine = routine; } -void done_act(lv_event_t *event) { selection_done = true; } - void save_act(lv_event_t *event) { - sdconf_save(); + sd_save(); lv_obj_clear_flag(saved_toast, LV_OBJ_FLAG_HIDDEN); lv_anim_start(&anim_toast); } -// ============================= Core Functions ============================= // +// ============================== Constructor ============================== // + +rd::Selector::Selector(std::vector new_routines) { + + // ----------------------------- Create UI ----------------------------- // -rd::Selector::Selector() { this->view = rd_view_create("Auton Selector"); lv_obj_set_style_bg_color(view->obj, color_bg, 0); - routine_list = lv_list_create(view->obj); + lv_obj_t *routine_list = lv_list_create(view->obj); lv_obj_set_size(routine_list, 228, 192); lv_obj_align(routine_list, LV_ALIGN_BOTTOM_LEFT, 8, -8); lv_obj_add_style(routine_list, &style_list, 0); @@ -156,8 +129,6 @@ rd::Selector::Selector() { lv_obj_align(title, LV_ALIGN_TOP_LEFT, 8, 12); if (pros::usd::is_installed()) { - sdconf_load(); - saved_toast = lv_label_create(view->obj); lv_label_set_text(saved_toast, "Saved to SD"); lv_obj_add_style(saved_toast, &style_text_centered, 0); @@ -185,33 +156,28 @@ rd::Selector::Selector() { lv_anim_set_exec_cb(&anim_toast, &anim_text_opa_cb); lv_anim_set_deleted_cb(&anim_toast, &anim_del_cb); lv_anim_set_values(&anim_toast, 255, 0); -} -// ============================= Other Methods ============================= // + // ----------------------------- Add autons ----------------------------- // -void rd::Selector::add_autons(std::vector new_routines) { for (routine_t routine : new_routines) { - static int r_index = 0; - - Routine new_routine(r_index, routine.first, routine.second); - routines.push_back(new_routine); - - r_index++; + routines.push_back(routine); } - for (Routine &routine : routines) { - lv_obj_t *new_btn = lv_list_add_btn(routine_list, NULL, routine.name.c_str()); + for (routine_t &routine : routines) { + lv_obj_t *new_btn = lv_list_add_btn(routine_list, NULL, routine.first.c_str()); lv_obj_add_style(new_btn, &style_list_btn, 0); lv_obj_add_style(new_btn, &style_list_btn_pr, LV_STATE_PRESSED); lv_obj_add_event_cb(new_btn, &r_select_act, LV_EVENT_PRESSED, &routine); } - load_saved(); + if (pros::usd::is_installed()) sd_load(); } -void rd::Selector::do_auton() { +// ============================= Other Methods ============================= // + +void rd::Selector::run_auton() { if (selected_routine == nullptr) return; // If commanded to do nothing then return - selected_routine->action(); + selected_routine->second(); } void rd::Selector::focus() { rd_view_focus(this->view); } \ No newline at end of file