From: Clyne Sullivan Date: Wed, 10 Feb 2016 19:28:16 +0000 (-0500) Subject: revised everything X-Git-Url: https://code.bitgloo.com/?a=commitdiff_plain;h=c3b516ee1f6e0d317e629ba95abf4ac0cd94f534;p=abelleisle%2Fvex5106z.git revised everything --- diff --git a/.project b/.project index d3a012f..c5045bd 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - VEX_1516 + New diff --git a/Map.tiff b/Map.tiff deleted file mode 100644 index 8a69117..0000000 Binary files a/Map.tiff and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/.cproject b/Nate's Position Testing/Shooter Testing/.cproject deleted file mode 100644 index e2e54f6..0000000 --- a/Nate's Position Testing/Shooter Testing/.cproject +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - make - - upload - false - true - false - - - - diff --git a/Nate's Position Testing/Shooter Testing/.project b/Nate's Position Testing/Shooter Testing/.project deleted file mode 100644 index 36cbd3b..0000000 --- a/Nate's Position Testing/Shooter Testing/.project +++ /dev/null @@ -1,78 +0,0 @@ - - - Shooter Testing - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - ?name? - - - - org.eclipse.cdt.make.core.append_environment - true - - - org.eclipse.cdt.make.core.autoBuildTarget - all - - - org.eclipse.cdt.make.core.buildArguments - - - - org.eclipse.cdt.make.core.buildCommand - make - - - org.eclipse.cdt.make.core.cleanBuildTarget - clean - - - org.eclipse.cdt.make.core.contents - org.eclipse.cdt.make.core.activeConfigSettings - - - org.eclipse.cdt.make.core.enableAutoBuild - false - - - org.eclipse.cdt.make.core.enableCleanBuild - true - - - org.eclipse.cdt.make.core.enableFullBuild - true - - - org.eclipse.cdt.make.core.fullBuildTarget - all - - - org.eclipse.cdt.make.core.stopOnError - true - - - org.eclipse.cdt.make.core.useDefaultBuildCmd - true - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/Nate's Position Testing/Shooter Testing/Makefile b/Nate's Position Testing/Shooter Testing/Makefile deleted file mode 100644 index 5d6b7fc..0000000 --- a/Nate's Position Testing/Shooter Testing/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# Universal C Makefile for MCU targets - -# Path to project root (for top-level, so the project is in ./; first-level, ../; etc.) -ROOT=. -# Binary output directory -BINDIR=$(ROOT)/bin -# Subdirectories to include in the build -SUBDIRS=src - -# Nothing below here needs to be modified by typical users - -# Include common aspects of this project --include $(ROOT)/common.mk - -ASMSRC:=$(wildcard *.$(ASMEXT)) -ASMOBJ:=$(patsubst %.o,$(BINDIR)/%.o,$(ASMSRC:.$(ASMEXT)=.o)) -HEADERS:=$(wildcard *.$(HEXT)) -CSRC=$(wildcard *.$(CEXT)) -COBJ:=$(patsubst %.o,$(BINDIR)/%.o,$(CSRC:.$(CEXT)=.o)) -CPPSRC:=$(wildcard *.$(CPPEXT)) -CPPOBJ:=$(patsubst %.o,$(BINDIR)/%.o,$(CPPSRC:.$(CPPEXT)=.o)) -OUT:=$(BINDIR)/$(OUTNAME) - -.PHONY: all clean upload _force_look - -# By default, compile program -all: $(BINDIR) $(OUT) - -# Remove all intermediate object files (remove the binary directory) -clean: - -rm -f $(OUT) - -rm -rf $(BINDIR) - -# Uploads program to device -upload: all - $(UPLOAD) - -# Phony force-look target -_force_look: - @true - -# Looks in subdirectories for things to make -$(SUBDIRS): %: _force_look - @$(MAKE) --no-print-directory -C $@ - -# Ensure binary directory exists -$(BINDIR): - -@mkdir -p $(BINDIR) - -# Compile program -$(OUT): $(SUBDIRS) $(ASMOBJ) $(COBJ) $(CPPOBJ) - @echo LN $(BINDIR)/*.o $(LIBRARIES) to $@ - @$(CC) $(LDFLAGS) $(BINDIR)/*.o $(LIBRARIES) -o $@ - @$(MCUPREFIX)size $(SIZEFLAGS) $(OUT) - $(MCUPREPARE) - -# Assembly source file management -$(ASMOBJ): $(BINDIR)/%.o: %.$(ASMEXT) $(HEADERS) - @echo AS $< - @$(AS) $(AFLAGS) -o $@ $< - -# Object management -$(COBJ): $(BINDIR)/%.o: %.$(CEXT) $(HEADERS) - @echo CC $(INCLUDE) $< - @$(CC) $(INCLUDE) $(CFLAGS) -o $@ $< - -$(CPPOBJ): $(BINDIR)/%.o: %.$(CPPEXT) $(HEADERS) - @echo CPC $(INCLUDE) $< - @$(CPPCC) $(INCLUDE) $(CPPFLAGS) -o $@ $< diff --git a/Nate's Position Testing/Shooter Testing/bin/auto.o b/Nate's Position Testing/Shooter Testing/bin/auto.o deleted file mode 100644 index 689d59c..0000000 Binary files a/Nate's Position Testing/Shooter Testing/bin/auto.o and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/bin/init.o b/Nate's Position Testing/Shooter Testing/bin/init.o deleted file mode 100644 index 96666b7..0000000 Binary files a/Nate's Position Testing/Shooter Testing/bin/init.o and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/bin/opcontrol.o b/Nate's Position Testing/Shooter Testing/bin/opcontrol.o deleted file mode 100644 index 9a2d40f..0000000 Binary files a/Nate's Position Testing/Shooter Testing/bin/opcontrol.o and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/bin/output.bin b/Nate's Position Testing/Shooter Testing/bin/output.bin deleted file mode 100644 index 363b7a9..0000000 Binary files a/Nate's Position Testing/Shooter Testing/bin/output.bin and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/bin/output.elf b/Nate's Position Testing/Shooter Testing/bin/output.elf deleted file mode 100644 index 73c390b..0000000 Binary files a/Nate's Position Testing/Shooter Testing/bin/output.elf and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/common.mk b/Nate's Position Testing/Shooter Testing/common.mk deleted file mode 100644 index 58098f5..0000000 --- a/Nate's Position Testing/Shooter Testing/common.mk +++ /dev/null @@ -1,45 +0,0 @@ -# Universal C Makefile for MCU targets -# Top-level template file to configure build - -# Makefile for IFI VeX Cortex Microcontroller (STM32F103VD series) -DEVICE=VexCortex -# Libraries to include in the link (use -L and -l) e.g. -lm, -lmyLib -LIBRARIES=$(ROOT)/firmware/libccos.a -lgcc -lm -# Prefix for ARM tools (must be on the path) -MCUPREFIX=arm-none-eabi- -# Flags for the assembler -MCUAFLAGS=-mthumb -mcpu=cortex-m3 -mlittle-endian -# Flags for the compiler -MCUCFLAGS=-mthumb -mcpu=cortex-m3 -mlittle-endian -# Flags for the linker -MCULFLAGS=-nostartfiles -Wl,-static -Bfirmware -Wl,-u,VectorTable -Wl,-T -Xlinker firmware/cortex.ld -# Prepares the elf file by converting it to a binary that java can write -MCUPREPARE=$(OBJCOPY) $(OUT) -O binary $(BINDIR)/$(OUTBIN) -# Advanced sizing flags -SIZEFLAGS= -# Uploads program using java -UPLOAD=@java -jar firmware/uniflash.jar vex $(BINDIR)/$(OUTBIN) - -# Advanced options -ASMEXT=s -CEXT=c -CPPEXT=cpp -HEXT=h -INCLUDE=-I$(ROOT)/include -I$(ROOT)/src -OUTBIN=output.bin -OUTNAME=output.elf - -# Flags for programs -AFLAGS:=$(MCUAFLAGS) -ARFLAGS:=$(MCUCFLAGS) -CCFLAGS:=-c -Wall $(MCUCFLAGS) -Os -ffunction-sections -fsigned-char -fomit-frame-pointer -fsingle-precision-constant -CFLAGS:=$(CCFLAGS) -std=gnu99 -Werror=implicit-function-declaration -CPPFLAGS:=$(CCFLAGS) -fno-exceptions -fno-rtti -felide-constructors -LDFLAGS:=-Wall $(MCUCFLAGS) $(MCULFLAGS) -Wl,--gc-sections - -# Tools used in program -AR:=$(MCUPREFIX)ar -AS:=$(MCUPREFIX)as -CC:=$(MCUPREFIX)gcc -CPPCC:=$(MCUPREFIX)g++ -OBJCOPY:=$(MCUPREFIX)objcopy diff --git a/Nate's Position Testing/Shooter Testing/firmware/STM32F10x.ld b/Nate's Position Testing/Shooter Testing/firmware/STM32F10x.ld deleted file mode 100644 index e6caa0d..0000000 --- a/Nate's Position Testing/Shooter Testing/firmware/STM32F10x.ld +++ /dev/null @@ -1,100 +0,0 @@ -/* Memory space definitions */ -MEMORY { - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 384K -} - -/* Higher address of the user mode stack */ -EXTERN ( _estack ); -PROVIDE ( _estack = ORIGIN(RAM) + LENGTH(RAM) ); - -/* This sends all unreferenced IRQHandlers to reset. */ -PROVIDE ( ISR_SWI = 0 ); -PROVIDE ( ISR_IRQ = 0 ); -PROVIDE ( ISR_Prefetch = 0 ); -PROVIDE ( ISR_Abort = 0 ); -PROVIDE ( ISR_FIQ = 0 ); - -PROVIDE ( ISR_NMI = 0 ); -PROVIDE ( ISR_HardFault = 0 ); -PROVIDE ( ISR_MemManage = 0 ); -PROVIDE ( ISR_BusFault = 0 ); -PROVIDE ( ISR_UsageFault = 0 ); - -PROVIDE ( ISR_SVC = 0 ); -PROVIDE ( ISR_DebugMon = 0 ); -PROVIDE ( ISR_PendSV = 0 ); -PROVIDE ( ISR_SysTick = 0 ); - -PROVIDE ( ISR_WWDG = 0 ); -PROVIDE ( ISR_PVD = 0 ); -PROVIDE ( ISR_TAMPER = 0 ); -PROVIDE ( ISR_RTC = 0 ); -PROVIDE ( ISR_FLASH = 0 ); -PROVIDE ( ISR_RCC = 0 ); -PROVIDE ( ISR_EXTI0 = 0 ); -PROVIDE ( ISR_EXTI1 = 0 ); -PROVIDE ( ISR_EXTI2 = 0 ); -PROVIDE ( ISR_EXTI3 = 0 ); -PROVIDE ( ISR_EXTI4 = 0 ); -PROVIDE ( ISR_DMAChannel1 = 0 ); -PROVIDE ( ISR_DMAChannel2 = 0 ); -PROVIDE ( ISR_DMAChannel3 = 0 ); -PROVIDE ( ISR_DMAChannel4 = 0 ); -PROVIDE ( ISR_DMAChannel5 = 0 ); -PROVIDE ( ISR_DMAChannel6 = 0 ); -PROVIDE ( ISR_DMAChannel7 = 0 ); -PROVIDE ( ISR_DMA1_Channel1 = 0 ); -PROVIDE ( ISR_DMA1_Channel2 = 0 ); -PROVIDE ( ISR_DMA1_Channel3 = 0 ); -PROVIDE ( ISR_DMA1_Channel4 = 0 ); -PROVIDE ( ISR_DMA1_Channel5 = 0 ); -PROVIDE ( ISR_DMA1_Channel6 = 0 ); -PROVIDE ( ISR_DMA1_Channel7 = 0 ); -PROVIDE ( ISR_ADC = 0 ); -PROVIDE ( ISR_ADC1_2 = 0 ); -PROVIDE ( ISR_USB_HP_CAN_TX = 0 ); -PROVIDE ( ISR_USB_HP_CAN1_TX = 0 ); -PROVIDE ( ISR_USB_LP_CAN_RX0 = 0 ); -PROVIDE ( ISR_USB_LP_CAN1_RX0 = 0 ); -PROVIDE ( ISR_CAN_RX1 = 0 ); -PROVIDE ( ISR_CAN1_RX1 = 0 ); -PROVIDE ( ISR_CAN_SCE = 0 ); -PROVIDE ( ISR_CAN1_SCE = 0 ); -PROVIDE ( ISR_EXTI9_5 = 0 ); -PROVIDE ( ISR_TIM1_BRK = 0 ); -PROVIDE ( ISR_TIM1_UP = 0 ); -PROVIDE ( ISR_TIM1_TRG_COM = 0 ); -PROVIDE ( ISR_TIM1_CC = 0 ); -PROVIDE ( ISR_TIM2 = 0 ); -PROVIDE ( ISR_TIM3 = 0 ); -PROVIDE ( ISR_TIM4 = 0 ); -PROVIDE ( ISR_I2C1_EV = 0 ); -PROVIDE ( ISR_I2C1_ER = 0 ); -PROVIDE ( ISR_I2C2_EV = 0 ); -PROVIDE ( ISR_I2C2_ER = 0 ); -PROVIDE ( ISR_SPI1 = 0 ); -PROVIDE ( ISR_SPI2 = 0 ); -PROVIDE ( ISR_USART1 = 0 ); -PROVIDE ( ISR_USART2 = 0 ); -PROVIDE ( ISR_USART3 = 0 ); -PROVIDE ( ISR_EXTI15_10 = 0 ); -PROVIDE ( ISR_RTCAlarm = 0 ); -PROVIDE ( ISR_USBWakeUp = 0 ); -PROVIDE ( ISR_TIM8_BRK = 0 ); -PROVIDE ( ISR_TIM8_UP = 0 ); -PROVIDE ( ISR_TIM8_TRG_COM = 0 ); -PROVIDE ( ISR_TIM8_CC = 0 ); -PROVIDE ( ISR_ADC3 = 0 ); -PROVIDE ( ISR_FSMC = 0 ); -PROVIDE ( ISR_SDIO = 0 ); -PROVIDE ( ISR_TIM5 = 0 ); -PROVIDE ( ISR_SPI3 = 0 ); -PROVIDE ( ISR_UART4 = 0 ); -PROVIDE ( ISR_UART5 = 0 ); -PROVIDE ( ISR_TIM6 = 0 ); -PROVIDE ( ISR_TIM7 = 0 ); -PROVIDE ( ISR_DMA2_Channel1 = 0 ); -PROVIDE ( ISR_DMA2_Channel2 = 0 ); -PROVIDE ( ISR_DMA2_Channel3 = 0 ); -PROVIDE ( ISR_DMA2_Channel4_5 = 0 ); diff --git a/Nate's Position Testing/Shooter Testing/firmware/cortex.ld b/Nate's Position Testing/Shooter Testing/firmware/cortex.ld deleted file mode 100644 index 36d5aa5..0000000 --- a/Nate's Position Testing/Shooter Testing/firmware/cortex.ld +++ /dev/null @@ -1,123 +0,0 @@ -/* Include STM32F10X linker scripts */ -INCLUDE "STM32F10x.ld" - -EXTERN ( _heapbegin ); - -/* Section definitions for Cortex firmware flashing */ -SECTIONS { - .isr_vector : { - /* startup code, prevents garbage collection from eating everything */ - KEEP(*(.isr_vector)) - . = ALIGN(4); - } >FLASH - .text : { - . = ALIGN(4); - *(.text) - *(.text.*) - /* Preinit array of functions */ - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - . = ALIGN(4); - /* Init array of functions */ - KEEP(*(.init)) - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - . = ALIGN(4); - /* C++ constructors */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - . = ALIGN(4); - /* Finalizer array of functions */ - KEEP(*(.fini)) - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - . = ALIGN(4); - /* C++ destructors */ - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - _etext = .; - _srdata = .; - . = ALIGN(4); - *(.rodata) - *(.rodata*) - *(.glue_7) - *(.glue_7t) - . = ALIGN(4); - _erdata = .; - _sidata = .; - } >FLASH - /* The program executes knowing that the data is in the RAM, but the loader puts the - * initial values in the FLASH (inidata). The startup copies the initial values over */ - .data : AT ( _sidata ) { - . = ALIGN(4); - _sdata = .; - *(.data) - *(.data.*) - *(.RAMtext) - . = ALIGN(4); - _edata = .; - } >RAM - /* Uninitialized data (zero-fill) section */ - .bss : { - . = ALIGN(4); - _sbss = .; - *(.bss) - *(COMMON) - . = ALIGN(4); - _ebss = .; - . = ALIGN(8); - _heapbegin = .; - } >RAM - - /DISCARD/ : { - libc.a ( * ) - libg.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - libstdc++.a ( * ) - libsupc++.a ( * ) - } - /* ARM exception unwinding, mandated by ARM EABI C++ standard (with -fno-exceptions?) */ - .ARM.exidx 0 : { *(.ARM.exidx*) } - /* Stabs debugging sections */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} diff --git a/Nate's Position Testing/Shooter Testing/firmware/libccos.a b/Nate's Position Testing/Shooter Testing/firmware/libccos.a deleted file mode 100644 index 469b330..0000000 Binary files a/Nate's Position Testing/Shooter Testing/firmware/libccos.a and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/firmware/uniflash.jar b/Nate's Position Testing/Shooter Testing/firmware/uniflash.jar deleted file mode 100644 index a922ae9..0000000 Binary files a/Nate's Position Testing/Shooter Testing/firmware/uniflash.jar and /dev/null differ diff --git a/Nate's Position Testing/Shooter Testing/include/API.h b/Nate's Position Testing/Shooter Testing/include/API.h deleted file mode 100644 index 7de7889..0000000 --- a/Nate's Position Testing/Shooter Testing/include/API.h +++ /dev/null @@ -1,1553 +0,0 @@ -/** @file API.h - * @brief Provides the high-level user functionality intended for use by typical VEX Cortex - * programmers. - * - * This file should be included for you in the predefined stubs in each new VEX Cortex PROS - * project through the inclusion of "main.h". In any new C source file, it is advisable to - * include main.h instead of referencing API.h by name, to better handle any nomenclature - * changes to this file or its contents. - * - * Copyright (c) 2011-2014, Purdue University ACM SIG BOTS. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Purdue University ACM SIG BOTS nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL PURDUE UNIVERSITY ACM SIG BOTS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Purdue Robotics OS contains FreeRTOS (http://www.freertos.org) whose source code may be - * obtained from http://sourceforge.net/projects/freertos/files/ or on request. - */ - -#ifndef API_H_ -#define API_H_ - -// System includes -#include -#include -#include - -// Begin C++ extern to C -#ifdef __cplusplus -extern "C" { -#endif - -// -------------------- VEX competition functions -------------------- - -/** - * DOWN button (valid on channels 5, 6, 7, 8) - */ -#define JOY_DOWN 1 -/** - * LEFT button (valid on channels 7, 8) - */ -#define JOY_LEFT 2 -/** - * UP button (valid on channels 5, 6, 7, 8) - */ -#define JOY_UP 4 -/** - * RIGHT button (valid on channels 7, 8) - */ -#define JOY_RIGHT 8 -/** - * Analog axis for the X acceleration from the VEX Joystick. - */ -#define ACCEL_X 5 -/** - * Analog axis for the Y acceleration from the VEX Joystick. - */ -#define ACCEL_Y 6 - -/** - * Returns true if the robot is in autonomous mode, or false otherwise. - * - * While in autonomous mode, joystick inputs will return a neutral value, but serial port - * communications (even over VexNET) will still work properly. - */ -bool isAutonomous(); -/** - * Returns true if the robot is enabled, or false otherwise. - * - * While disabled via the VEX Competition Switch or VEX Field Controller, motors will not - * function. However, the digital I/O ports can still be changed, which may indirectly affect - * the robot state (e.g. solenoids). Avoid performing externally visible actions while - * disabled (the kernel should take care of this most of the time). - */ -bool isEnabled(); -/** - * Returns true if a joystick is connected to the specified slot number (1 or 2), or false - * otherwise. - * - * Useful for automatically merging joysticks for one operator, or splitting for two. This - * function does not work properly during initialize() or initializeIO() and can return false - * positives. It should be checked once and stored at the beginning of operatorControl(). - * - * @param joystick the joystick slot to check - */ -bool isJoystickConnected(unsigned char joystick); -/** - * Returns true if a VEX field controller or competition switch is connected, or false - * otherwise. - * - * When in online mode, the switching between autonomous() and operatorControl() tasks is - * managed by the PROS kernel. - */ -bool isOnline(); -/** - * Gets the value of a control axis on the VEX joystick. Returns the value from -127 to 127, - * or 0 if no joystick is connected to the requested slot. - * - * @param joystick the joystick slot to check - * @param axis one of 1, 2, 3, 4, ACCEL_X, or ACCEL_Y - */ -int joystickGetAnalog(unsigned char joystick, unsigned char axis); -/** - * Gets the value of a button on the VEX joystick. Returns true if that button is pressed, or - * false otherwise. If no joystick is connected to the requested slot, returns false. - * - * @param joystick the joystick slot to check - * @param buttonGroup one of 5, 6, 7, or 8 to request that button as labelled on the joystick - * @param button one of JOY_UP, JOY_DOWN, JOY_LEFT, or JOY_RIGHT; requesting JOY_LEFT or - * JOY_RIGHT for groups 5 or 6 will cause an undefined value to be returned - */ -bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup, - unsigned char button); -/** - * Returns the backup battery voltage in millivolts. - * - * If no backup battery is connected, returns 0. - */ -unsigned int powerLevelBackup(); -/** - * Returns the main battery voltage in millivolts. - * - * In rare circumstances, this method might return 0. Check the output value for reasonability - * before blindly blasting the user. - */ -unsigned int powerLevelMain(); -/** - * Sets the team name displayed to the VEX field control and VEX Firmware Upgrade. - * - * @param name a string containing the team name; only the first eight characters will be shown - */ -void setTeamName(const char *name); - -// -------------------- Pin control functions -------------------- - -/** - * There are 8 available analog I/O on the Cortex. - */ -#define BOARD_NR_ADC_PINS 8 -/** - * There are 27 available I/O on the Cortex that can be used for digital communication. - * - * This excludes the crystal ports but includes the Communications, Speaker, and Analog ports. - * - * The motor ports are not on the Cortex and are thus excluded from this count. Pin 0 is the - * Speaker port, pins 1-12 are the standard Digital I/O, 13-20 are the Analog I/O, 21+22 are - * UART1, 23+24 are UART2, and 25+26 are the I2C port. - */ -#define BOARD_NR_GPIO_PINS 27 -/** - * Used for digitalWrite() 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 digitalWrite() 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 - -/** - * pinMode() state for digital input, with pullup. - * - * This is the default state for the 12 Digital pins. The pullup causes the input to read as - * "HIGH" when unplugged, but is fairly weak and can safely be driven by most sources. Many VEX - * digital sensors rely on this behavior and cannot be used with INPUT_FLOATING. - */ -#define INPUT 0x0A -/** - * pinMode() state for analog inputs. - * - * This is the default state for the 8 Analog pins and the Speaker port. This only works on - * pins with analog input capabilities; use anywhere else results in undefined behavior. - */ -#define INPUT_ANALOG 0x00 -/** - * pinMode() state for digital input, without pullup. - * - * Beware of power consumption, as digital inputs left "floating" may switch back and forth - * and cause spurious interrupts. - */ -#define INPUT_FLOATING 0x04 -/** - * pinMode() state for digital output, push-pull. - * - * This is the mode which should be used to output a digital HIGH or LOW value from the Cortex. - * This mode is useful for pneumatic solenoid valves and VEX LEDs. - */ -#define OUTPUT 0x01 -/** - * pinMode() state for open-drain outputs. - * - * This is useful in a few cases for external electronics and should not be used for the VEX - * solenoid or LEDs. - */ -#define OUTPUT_OD 0x05 - -/** - * Calibrates the analog sensor on the specified channel. - * - * 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 - * analogReadCalibrated() and analogReadCalibratedHR() functions. These functions will return - * the difference between this value and the current sensor value when called. - * - * Do not use this function in initializeIO(), or when the sensor value might be unstable - * (gyro rotation, accelerometer movement). - * - * This function may not work properly if the VEX Cortex is tethered to a PC using the orange - * USB A to A cable and has no VEX 7.2V Battery connected and powered on, as the VEX Battery - * provides power to sensors. - * - * @param channel the channel to calibrate from 1-8 - * @return the average sensor value computed by this function - */ -int analogCalibrate(unsigned char channel); -/** - * Reads an analog input channel and returns the 12-bit value. - * - * The value returned is undefined if the analog pin has been switched to a different mode. - * This function is Wiring-compatible with the exception of the larger output range. The - * meaning of the returned value varies depending on the sensor attached. - * - * This function may not work properly if the VEX Cortex is tethered to a PC using the orange - * USB A to A cable and has no VEX 7.2V Battery connected and powered on, as the VEX Battery - * provides power to sensors. - * - * @param channel the channel to read from 1-8 - * @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 - */ -int analogRead(unsigned char channel); -/** - * Reads the calibrated value of an analog input channel. - * - * The analogCalibrate() function must be run first on that channel. This function is - * inappropriate for sensor values intended for integration, as round-off error can accumulate - * causing drift over time. Use analogReadCalibratedHR() instead. - * - * This function may not work properly if the VEX Cortex is tethered to a PC using the orange - * USB A to A cable and has no VEX 7.2V Battery connected and powered on, as the VEX Battery - * provides power to sensors. - * - * @param channel the channel to read from 1-8 - * @return the difference of the sensor value from its calibrated default from -4095 to 4095 - */ -int analogReadCalibrated(unsigned char channel); -/** - * Reads the calibrated value of an analog input channel 1-8 with enhanced precision. - * - * The analogCalibrate() 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 errors induced by the average value being between two values come out - * in the wash when integrated over time. Think of the value as the true value times 16. - * - * This function may not work properly if the VEX Cortex is tethered to a PC using the orange - * USB A to A cable and has no VEX 7.2V Battery connected and powered on, as the VEX Battery - * provides power to sensors. - * - * @param channel the channel to read from 1-8 - * @return the difference of the sensor value from its calibrated default from -16384 to 16384 - */ -int analogReadCalibratedHR(unsigned char channel); -/** - * Gets the digital value (1 or 0) of a pin configured as a digital input. - * - * If the pin is configured as some other mode, the digital value which reflects the current - * state of the pin is returned, which may or may not differ from the currently set value. The - * return value is undefined for pins configured as Analog inputs, or for ports in use by a - * Communications interface. This function is Wiring-compatible. - * - * This function may not work properly if the VEX Cortex is tethered to a PC using the orange - * USB A to A cable and has no VEX 7.2V Battery connected and powered on, as the VEX Battery - * provides power to sensors. - * - * @param pin the pin to read from 1-26 - * @return true if the pin is HIGH, or false if it is LOW - */ -bool digitalRead(unsigned char pin); -/** - * Sets the digital value (1 or 0) of a pin configured as a digital output. - * - * If the pin is configured as some other mode, behavior is undefined. This function is - * Wiring-compatible. - * - * @param pin the pin to write from 1-26 - * @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 - */ -void digitalWrite(unsigned char pin, bool value); -/** - * Configures the pin as an input or output with a variety of settings. - * - * Do note that INPUT by default turns on the pull-up resistor, as most VEX sensors are - * open-drain active low. It should not be a big deal for most push-pull sources. This function - * is Wiring-compatible. - * - * @param pin the pin to modify from 1-26 - * @param mode one of INPUT, INPUT_ANALOG, INPUT_FLOATING, OUTPUT, or OUTPUT_OD - */ -void pinMode(unsigned char pin, unsigned char mode); - -/* - * Digital port 10 cannot be used as an interrupt port, or for an encoder. Plan accordingly. - */ - -/** - * When used in ioSetInterrupt(), triggers an interrupt on rising edges (LOW to HIGH). - */ -#define INTERRUPT_EDGE_RISING 1 -/** - * When used in ioSetInterrupt(), triggers an interrupt on falling edges (HIGH to LOW). - */ -#define INTERRUPT_EDGE_FALLING 2 -/** - * When used in ioSetInterrupt(), triggers an interrupt on both rising and falling edges - * (LOW to HIGH or HIGH to LOW). - */ -#define INTERRUPT_EDGE_BOTH 3 -/** - * Type definition for interrupt handlers. Such functions must accept one argument indicating - * the pin which changed. - */ -typedef void (*InterruptHandler)(unsigned char pin); - -/** - * Disables interrupts on the specified pin. - * - * Disabling interrupts on interrupt pins which are not in use conserves processing time. - * - * @param pin the pin on which to reset interrupts from 1-9,11-12 - */ -void ioClearInterrupt(unsigned char pin); -/** - * Sets up an interrupt to occur on the specified pin, and resets any counters or timers - * associated with the pin. - * - * Each time the specified change occurs, the function pointer passed in will be called with - * the pin that changed as an argument. Enabling pin-change interrupts consumes processing - * time, so it is best to only enable necessary interrupts and to keep the InterruptHandler - * function short. Pin change interrupts can only be enabled on pins 1-9 and 11-12. - * - * Do not use API functions such as delay() inside the handler function, as the function will - * run in an ISR where the scheduler is paused and no other interrupts can execute. It is best - * to quickly update some state and allow a task to perform the work. - * - * Do not use this function on pins that are also being used by the built-in ultrasonic or - * shaft encoder drivers, or on pins which have been switched to output mode. - * - * @param pin the pin on which to enable interrupts from 1-9,11-12 - * @param edges one of INTERRUPT_EDGE_RISING, INTERRUPT_EDGE_FALLING, or INTERRUPT_EDGE_BOTH - * @param handler the function to call when the condition is satisfied - */ -void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler); - -// -------------------- Physical output control functions -------------------- - -/** - * Gets the last set speed of the specified motor channel. - * - * This speed may have been set by any task or the PROS kernel itself. This is not guaranteed - * to be the speed that the motor is actually running at, or even the speed currently being - * sent to the motor, due to latency in the Motor Controller 29 protocol and physical loading. - * To measure actual motor shaft revolution speed, attach a VEX Integrated Motor Encoder or - * VEX Quadrature Encoder and use the velocity functions associated with each. - * - * @param channel the motor channel to fetch from 1-10 - * @return the speed last sent to this channel; -127 is full reverse and 127 is full forward, - * with 0 being off - */ -int motorGet(unsigned char channel); -/** - * Sets the speed of the specified motor channel. - * - * Do not use motorSet() with the same channel argument from two different tasks. It is safe to - * use motorSet() with different channel arguments from different tasks. - * - * @param channel the motor channel to modify from 1-10 - * @param speed the new signed speed; -127 is full reverse and 127 is full forward, with 0 - * being off - */ -void motorSet(unsigned char channel, int speed); -/** - * Stops the motor on the specified channel, equivalent to calling motorSet() with an argument - * of zero. - * - * This performs a coasting stop, not an active brake. Since motorStop is similar to - * motorSet(0), see the note for motorSet() about use from multiple tasks. - * - * @param channel the motor channel to stop from 1-10 - */ -void motorStop(unsigned char channel); -/** - * Stops all motors; significantly faster than looping through all motor ports and calling - * motorSet(channel, 0) on each one. - */ -void motorStopAll(); - -/** - * Initializes VEX speaker support. - * - * The VEX speaker is not thread safe; it can only be used from one task at a time. Using the - * VEX speaker may impact robot performance. Teams may benefit from an if statement that only - * enables sound if isOnline() returns false. - */ -void speakerInit(); -/** - * Plays up to three RTTTL (Ring Tone Text Transfer Language) songs simultaneously over the - * VEX speaker. The audio is mixed to allow polyphonic sound to be played. Many simple songs - * are available in RTTTL format online, or compose your own. - * - * The song must not be NULL, but unused tracks within the song can be set to NULL. If any of - * the three song tracks is invalid, the result of this function is undefined. - * - * The VEX speaker is not thread safe; it can only be used from one task at a time. Using the - * VEX speaker may impact robot performance. Teams may benefit from an if statement that only - * enables sound if isOnline() returns false. - * - * @param songs an array of up to three (3) RTTTL songs as string values to play - */ -void speakerPlayArray(const char * * songs); -/** - * Plays an RTTTL (Ring Tone Text Transfer Language) song over the VEX speaker. Many simple - * songs are available in RTTTL format online, or compose your own. - * - * The song must not be NULL. If an invalid song is specified, the result of this function is - * undefined. - * - * The VEX speaker is not thread safe; it can only be used from one task at a time. Using the - * VEX speaker may impact robot performance. Teams may benefit from an if statement that only - * enables sound if isOnline() returns false. - * - * @param song the RTTTL song as a string value to play - */ -void speakerPlayRtttl(const char *song); -/** - * Powers down and disables the VEX speaker. - * - * If a song is currently being played in another task, the behavior of this function is - * undefined, since the VEX speaker is not thread safe. - */ -void speakerShutdown(); - -// -------------------- VEX sensor control functions -------------------- - -/** - * IME addresses end at 0x1F. Actually using more than 10 (address 0x1A) encoders will cause - * unreliable communications. - */ -#define IME_ADDR_MAX 0x1F - -/** - * Initializes all IMEs. - * - * IMEs are assigned sequential incrementing addresses, beginning with the first IME on the - * chain (closest to the VEX Cortex I2C port). Therefore, a given configuration of IMEs will - * always have the same ID assigned to each encoder. The addresses range from 0 to - * IME_ADDR_MAX, so the first encoder gets 0, the second gets 1, ... - * - * This function should most likely be used in initialize(). Do not use it in initializeIO() or - * at any other time when the scheduler is paused (like an interrupt). Checking the return - * value of this function is important to ensure that all IMEs are plugged in and responding as - * expected. - * - * This function, unlike the other IME functions, is not thread safe. If using imeInitializeAll - * to re-initialize encoders, calls to other IME functions might behave unpredictably during - * this function's execution. - * - * @return the number of IMEs successfully initialized. - */ -unsigned int imeInitializeAll(); -/** - * Gets the current 32-bit count of the specified IME. - * - * Much like the count for a quadrature encoder, the tick count is signed and cumulative. - * The value reflects total counts since the last reset. Different VEX Motor Encoders have a - * different number of counts per revolution: - * - * * \c 240.448 for the 269 IME - * * \c 627.2 for the 393 IME in high torque mode (factory default) - * * \c 392 for the 393 IME in high speed mode - * - * If the IME address is invalid, or the IME has not been reset or initialized, the value - * stored in *value is undefined. - * - * @param address the IME address to fetch from 0 to IME_ADDR_MAX - * @param value a pointer to the location where the value will be stored (obtained using the - * "&" operator on the target variable name e.g. imeGet(2, &counts)) - * @return true if the count was successfully read and the value stored in *value is valid; - * false otherwise - */ -bool imeGet(unsigned char address, int *value); -/** - * Gets the current rotational velocity of the specified IME. - * - * In this version of PROS, the velocity is positive if the IME count is increasing and - * negative if the IME count is decreasing. The velocity is in RPM of the internal encoder - * wheel. Since checking the IME for its type cannot reveal whether the motor gearing is - * high speed or high torque (in the 2-Wire Motor 393 case), the user must divide the return - * value by the number of output revolutions per encoder revolution: - * - * * \c 30.056 for the 269 IME - * * \c 39.2 for the 393 IME in high torque mode (factory default) - * * \c 24.5 for the 393 IME in high speed mode - * - * If the IME address is invalid, or the IME has not been reset or initialized, the value - * stored in *value is undefined. - * - * @param address the IME address to fetch from 0 to IME_ADDR_MAX - * @param value a pointer to the location where the value will be stored (obtained using the - * "&" operator on the target variable name e.g. imeGetVelocity(2, &counts)) - * @return true if the velocity was successfully read and the value stored in *value is valid; - * false otherwise - */ -bool imeGetVelocity(unsigned char address, int *value); -/** - * Resets the specified IME's counters to zero. - * - * This method can be used while the IME is rotating. - * - * @param address the IME address to reset from 0 to IME_ADDR_MAX - * @return true if the reset succeeded; false otherwise - */ -bool imeReset(unsigned char address); -/** - * Shuts down all IMEs on the chain; their addresses return to the default and the stored - * counts and velocities are lost. This function, unlike the other IME functions, is not - * thread safe. - * - * To use the IME chain again, wait at least 0.25 seconds before using imeInitializeAll again. - */ -void imeShutdown(); - -/** - * Reference type for an initialized gyro. - * - * Gyro information is stored as an opaque pointer to a structure in memory; as this is a - * pointer type, it can be safely passed or stored by value. - */ -typedef void * Gyro; - -/** - * Gets the current gyro angle in degrees, rounded to the nearest degree. - * - * There are 360 degrees in a circle. - * - * @param gyro the Gyro object from gyroInit() to read - * @return the signed and cumulative number of degrees rotated around the gyro's vertical axis - * since the last start or reset - */ -int gyroGet(Gyro gyro); -/** - * Initializes and enables a gyro on an analog port. - * - * NULL will be returned if the port is invalid or the gyro is already in use. Initializing a - * gyro implicitly calibrates it and resets its count. Do not move the robot while the gyro is - * being calibrated. It is suggested to call this function in initialize() and to place the - * robot in its final position before powering it on. - * - * The multiplier parameter can tune the gyro to adapt to specific sensors. The default value - * at this time is 196; higher values will increase the number of degrees reported for a fixed - * actual rotation, while lower values will decrease the number of degrees reported. If your - * robot is consistently turning too far, increase the multiplier, and if it is not turning - * far enough, decrease the multiplier. - * - * @param port the analog port to use from 1-8 - * @param multiplier an optional constant to tune the gyro readings; use 0 for the default - * value - * @return a Gyro object to be stored and used for later calls to gyro functions - */ -Gyro gyroInit(unsigned char port, unsigned short multiplier); -/** - * Resets the gyro to zero. - * - * It is safe to use this method while a gyro is enabled. It is not necessary to call this - * method before stopping or starting a gyro. - * - * @param gyro the Gyro object from gyroInit() to reset - */ -void gyroReset(Gyro gyro); -/** - * Stops and disables the gyro. - * - * Gyros use processing power, so disabling unused gyros increases code performance. - * The gyro's position will be retained. - * - * @param gyro the Gyro object from gyroInit() to stop - */ -void gyroShutdown(Gyro gyro); - -/** - * Reference type for an initialized encoder. - * - * Encoder information is stored as an opaque pointer to a structure in memory; as this is a - * pointer type, it can be safely passed or stored by value. - */ -typedef void * Encoder; -/** - * Gets the number of ticks recorded by the encoder. - * - * There are 360 ticks in one revolution. - * - * @param enc the Encoder object from encoderInit() to read - * @return the signed and cumulative number of counts since the last start or reset - */ -int encoderGet(Encoder enc); -/** - * Initializes and enables a quadrature encoder on two digital ports. - * - * Neither the top port nor the bottom port can be digital port 10. NULL will be returned if - * either port is invalid or the encoder is already in use. Initializing an encoder implicitly - * resets its count. - * - * @param portTop the "top" wire from the encoder sensor with the removable cover side UP - * @param portBottom the "bottom" wire from the encoder sensor - * @param reverse if "true", the sensor will count in the opposite direction - * @return an Encoder object to be stored and used for later calls to encoder functions - */ -Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse); -/** - * Resets the encoder 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. - * - * @param enc the Encoder object from encoderInit() to reset - */ -void encoderReset(Encoder enc); -/** - * Stops and disables the encoder. - * - * Encoders use processing power, so disabling unused encoders increases code performance. - * The encoder's count will be retained. - * - * @param enc the Encoder object from encoderInit() to stop - */ -void encoderShutdown(Encoder enc); - -/** - * Reference type for an initialized ultrasonic sensor. - * - * Ultrasonic information is stored as an opaque pointer to a structure in memory; as this is a - * pointer type, it can be safely passed or stored by value. - */ -typedef void * Ultrasonic; -/** - * 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. - * - * @param ult the Ultrasonic object from ultrasonicInit() to read - * @return the distance to the nearest object in centimeters - */ -int ultrasonicGet(Ultrasonic ult); -/** - * Initializes an ultrasonic sensor on the specified digital ports. - * - * The ultrasonic sensor will be polled in the background in concert with the other sensors - * registered using this method. NULL will be returned if either port is invalid or the - * ultrasonic sensor port is already in use. - * - * @param portEcho the port connected to the orange cable from 1-9,11-12 - * @param portPing the port connected to the yellow cable from 1-12 - * @return an Ultrasonic object to be stored and used for later calls to ultrasonic functions - */ -Ultrasonic ultrasonicInit(unsigned char portEcho, unsigned char portPing); -/** - * Stops and disables the ultrasonic sensor. - * - * The last distance it had before stopping will be retained. One more ping operation may occur - * before the sensor is fully disabled. - * - * @param ult the Ultrasonic object from ultrasonicInit() to stop - */ -void ultrasonicShutdown(Ultrasonic ult); - -/** - * FILE is an integer referring to a stream for the standard I/O functions. - * - * FILE * is the standard library method of referring to a file pointer, even though there is - * actually nothing there. - */ -typedef int FILE; -/** - * Bit mask for usartInit() for 8 data bits (typical) - */ -#define SERIAL_DATABITS_8 0x0000 -/** - * Bit mask for usartInit() for 9 data bits - */ -#define SERIAL_DATABITS_9 0x1000 -/** - * Bit mask for usartInit() for 1 stop bit (typical) - */ -#define SERIAL_STOPBITS_1 0x0000 -/** - * Bit mask for usartInit() for 2 stop bits - */ -#define SERIAL_STOPBITS_2 0x2000 -/** - * Bit mask for usartInit() for No parity (typical) - */ -#define SERIAL_PARITY_NONE 0x0000 -/** - * Bit mask for usartInit() for Even parity - */ -#define SERIAL_PARITY_EVEN 0x0400 -/** - * Bit mask for usartInit() for Odd parity - */ -#define SERIAL_PARITY_ODD 0x0600 -/** - * Specifies the default serial settings when used in usartInit() - */ -#define SERIAL_8N1 0x0000 - -/** - * Initialize the specified serial interface with the given connection parameters. - * - * I/O to the port is accomplished using the "standard" I/O functions such as fputs(), - * fprintf(), and fputc(). - * - * Re-initializing an open port may cause loss of data in the buffers. This routine may be - * safely called from initializeIO() or when the scheduler is paused. If I/O is attempted on a - * serial port which has never been opened, the behavior will be the same as if the port had - * been disabled. - * - * @param usart the port to open, either "uart1" or "uart2" - * @param baud the baud rate to use from 2400 to 1000000 baud - * @param flags a bit mask combination of the SERIAL_* flags specifying parity, stop, and data - * bits - */ -void usartInit(FILE *usart, unsigned int baud, unsigned int flags); -/** - * Disables the specified USART interface. - * - * Any data in the transmit and receive buffers will be lost. Attempts to read from the port - * when it is disabled will deadlock, and attempts to write to it may deadlock depending on - * the state of the buffer. - * - * @param usart the port to close, either "uart1" or "uart2" - */ -void usartShutdown(FILE *usart); - -// -------------------- Character input and output -------------------- - -/** - * The standard output stream uses the PC debug terminal. - */ -#define stdout ((FILE *)3) -/** - * The standard input stream uses the PC debug terminal. - */ -#define stdin ((FILE *)3) -/** - * UART 1 on the Cortex; must be opened first using usartInit(). - */ -#define uart1 ((FILE *)1) -/** - * UART 2 on the Cortex; must be opened first using usartInit(). - */ -#define uart2 ((FILE *)2) - -#ifndef EOF -/** - * EOF is a value evaluating to -1. - */ -#define EOF ((int)-1) -#endif - -#ifndef SEEK_SET -/** - * SEEK_SET is used in fseek() to denote an absolute position in bytes from the start of the - * file. - */ -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -/** - * SEEK_CUR is used in fseek() to denote an relative position in bytes from the current file - * location. - */ -#define SEEK_CUR 1 -#endif -#ifndef SEEK_END -/** - * SEEK_END is used in fseek() to denote an absolute position in bytes from the end of the - * file. The offset will most likely be negative in this case. - */ -#define SEEK_END 2 -#endif - -/** - * Closes the specified file descriptor. This function does not work on communication ports; - * use usartShutdown() instead. - * - * @param stream the file descriptor to close from fopen() - */ -void fclose(FILE *stream); -/** - * Returns the number of characters that can be read without blocking (the number of - * characters available) from the specified stream. This only works for communication ports and - * files in Read mode; for files in Write mode, 0 is always returned. - * - * This function may underestimate, but will not overestimate, the number of characters which - * meet this criterion. - * - * @param stream the stream to read (stdin, uart1, uart2, or an open file in Read mode) - * @return the number of characters which meet this criterion; if this number cannot be - * determined, returns 0 - */ -int fcount(FILE *stream); -/** - * Delete the specified file if it exists and is not currently open. - * - * The file will actually be erased from memory on the next re-boot. A physical power cycle is - * required to purge deleted files and free their allocated space for new files to be written. - * Deleted files are still considered inaccessible to fopen() in Read mode. - * - * @param file the file name to erase - * @return 0 if the file was deleted, or 1 if the file could not be found - */ -int fdelete(const char *file); -/** - * Checks to see if the specified stream is at its end. This only works for communication ports - * and files in Read mode; for files in Write mode, 1 is always returned. - * - * @param stream the channel to check (stdin, uart1, uart2, or an open file in Read mode) - * @return 0 if the stream is not at EOF, or 1 otherwise. - */ -int feof(FILE *stream); -/** - * Flushes the data on the specified file channel open in Write mode. This function has no - * effect on a communication port or a file in Read mode, as these streams are always flushed as - * quickly as possible by the kernel. - * - * Successful completion of an fflush function on a file in Write mode cannot guarantee that - * the file is vaild until fclose() is used on that file descriptor. - * - * @param stream the channel to flush (an open file in Write mode) - * @return 0 if the data was successfully flushed, EOF otherwise - */ -int fflush(FILE *stream); -/** - * Reads and returns one character from the specified stream, blocking until complete. - * - * Do not use fgetc() on a VEX LCD port; deadlock may occur. - * - * @param stream the stream to read (stdin, uart1, uart2, or an open file in Read mode) - * @return the next character from 0 to 255, or -1 if no character can be read - */ -int fgetc(FILE *stream); -/** - * Reads a string from the specified stream, storing the characters into the memory at str. - * Characters will be read until the specified limit is reached, a new line is found, or the - * end of file is reached. - * - * If the stream is already at end of file (for files in Read mode), NULL will be returned; - * otherwise, at least one character will be read and stored into str. - * - * @param str the location where the characters read will be stored - * @param num the maximum number of characters to store; at most (num - 1) characters will be - * read, with a null terminator ('\0') automatically appended - * @param stream the channel to read (stdin, uart1, uart2, or an open file in Read mode) - * @return str, or NULL if zero characters could be read - */ -char* fgets(char *str, int num, FILE *stream); -/** - * Opens the given file in the specified mode. The file name is truncated to eight characters. - * Only four files can be in use simultaneously in any given time, with at most one of those - * files in Write mode. This function does not work on communication ports; use usartInit() - * instead. - * - * mode can be "r" or "w". Due to the nature of the VEX Cortex memory, the "r+", "w+", and "a" - * modes are not supported by the file system. - * - * Opening a file that does not exist in Read mode will fail and return NULL, but opening a new - * file in Write mode will create it if there is space. Opening a file that already exists in - * Write mode will destroy the contents and create a new blank file if space is available. - * - * There are important considerations when using of the file system on the VEX Cortex. Reading - * from files is safe, but writing to files should only be performed when robot actuators have - * been stopped. PROS will attempt to continue to handle events during file writes, but most - * user tasks cannot execute during file writing. Powering down the VEX Cortex mid-write may - * cause file system corruption. - * - * @param file the file name - * @param mode the file mode - * @return a file descriptor pointing to the new file, or NULL if the file could not be opened - */ -FILE * fopen(const char *file, const char *mode); -/** - * Prints the simple string to the specified stream. - * - * This method is much, much faster than fprintf() and does not add a new line like fputs(). - * Do not use fprint() on a VEX LCD port. Use lcdSetText() instead. - * - * @param string the string to write - * @param stream the stream to write (stdout, uart1, uart2, or an open file in Write mode) - */ -void fprint(const char *string, FILE *stream); -/** - * Writes one character to the specified stream. - * - * Do not use fputc() on a VEX LCD port. Use lcdSetText() instead. - * - * @param value the character to write (a value of type "char" can be used) - * @param stream the stream to write (stdout, uart1, uart2, or an open file in Write mode) - * @return the character written - */ -int fputc(int value, FILE *stream); -/** - * Behaves the same as the "fprint" function, and appends a trailing newline ("\n"). - * - * Do not use fputs() on a VEX LCD port. Use lcdSetText() instead. - * - * @param string the string to write - * @param stream the stream to write (stdout, uart1, uart2, or an open file in Write mode) - * @return the number of characters written, excluding the new line - */ -int fputs(const char *string, FILE *stream); -/** - * Reads data from a stream into memory. Returns the number of bytes thus read. - * - * If the memory at ptr cannot store (size * count) bytes, undefined behavior occurs. - * - * @param ptr a pointer to where the data will be stored - * @param size the size of each data element to read in bytes - * @param count the number of data elements to read - * @param stream the stream to read (stdout, uart1, uart2, or an open file in Read mode) - * @return the number of bytes successfully read - */ -size_t fread(void *ptr, size_t size, size_t count, FILE *stream); -/** - * Seeks within a file open in Read mode. This function will fail when used on a file in Write - * mode or on any communications port. - * - * @param stream the stream to seek within - * @param offset the location within the stream to seek - * @param origin the reference location for offset: SEEK_CUR, SEEK_SET, or SEEK_END - * @return 0 if the seek was successful, or 1 otherwise - */ -int fseek(FILE *stream, long int offset, int origin); -/** - * Returns the current position of the stream. This function works on files in either Read or - * Write mode, but will fail on communications ports. - * - * @param stream the stream to check - * @return the offset of the stream, or -1 if the offset could not be determined - */ -long int ftell(FILE *stream); -/** - * Writes data from memory to a stream. Returns the number of bytes thus written. - * - * If the memory at ptr is not as long as (size * count) bytes, undefined behavior occurs. - * - * @param ptr a pointer to the data to write - * @param size the size of each data element to write in bytes - * @param count the number of data elements to write - * @param stream the stream to write (stdout, uart1, uart2, or an open file in Write mode) - * @return the number of bytes successfully written - */ -size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream); -/** - * Reads and returns one character from "stdin", which is the PC debug terminal. - * - * @return the next character from 0 to 255, or -1 if no character can be read - */ -int getchar(); -/** - * Prints the simple string to the debug terminal without formatting. - * - * This method is much, much faster than printf(). - * - * @param string the string to write - */ -void print(const char *string); -/** - * Writes one character to "stdout", which is the PC debug terminal, and returns the input - * value. - * - * When using a wireless connection, one may need to press the spacebar before the input is - * visible on the terminal. - * - * @param value the character to write (a value of type "char" can be used) - * @return the character written - */ -int putchar(int value); -/** - * Behaves the same as the "print" function, and appends a trailing newline ("\n"). - * - * @param string the string to write - * @return the number of characters written, excluding the new line - */ -int puts(const char *string); - -/** - * Prints the formatted string to the specified output stream. - * - * The specifiers supported by this minimalistic printf() function are: - * * @c \%d: Signed integer in base 10 (int) - * * @c \%u: Unsigned integer in base 10 (unsigned int) - * * @c \%x, @c \%X: Integer in base 16 (unsigned int, int) - * * @c \%p: Pointer (void *, int *, ...) - * * @c \%c: Character (char) - * * @c \%s: Null-terminated string (char *) - * * @c \%%: Single literal percent sign - * * @c \%f: Floating-point number - * - * Specifiers can be modified with: - * * @c 0: Zero-pad, instead of space-pad - * * @c a.b: Make the field at least "a" characters wide. If "b" is specified for "%f", changes the - * number of digits after the decimal point - * * @c -: Left-align, instead of right-align - * * @c +: Always display the sign character (displays a leading "+" for positive numbers) - * * @c l: Ignored for compatibility - * - * Invalid format specifiers, or mismatched parameters to specifiers, cause undefined behavior. - * Other characters are written out verbatim. Do not use fprintf() on a VEX LCD port. - * Use lcdPrint() instead. - * - * @param stream the stream to write (stdout, uart1, or uart2) - * @param formatString the format string as specified above - * @return the number of characters written - */ -int fprintf(FILE *stream, const char *formatString, ...); -/** - * Prints the formatted string to the debug stream (the PC terminal). - * - * @param formatString the format string as specified in fprintf() - * @return the number of characters written - */ -int printf(const char *formatString, ...); -/** - * Prints the formatted string to the string buffer with the specified length limit. - * - * The length limit, as per the C standard, includes the trailing null character, so an - * argument of 256 will cause a maximum of 255 non-null characters to be printed, and one null - * terminator in all cases. - * - * @param buffer the string buffer where characters can be placed - * @param limit the maximum number of characters to write - * @param formatString the format string as specified in fprintf() - * @return the number of characters stored - */ -int snprintf(char *buffer, size_t limit, const char *formatString, ...); -/** - * Prints the formatted string to the string buffer. - * - * If the buffer is not big enough to contain the complete formatted output, undefined behavior - * occurs. See snprintf() for a safer version of this function. - * - * @param buffer the string buffer where characters can be placed - * @param formatString the format string as specified in fprintf() - * @return the number of characters stored - */ -int sprintf(char *buffer, const char *formatString, ...); - -/** - * LEFT button on LCD for use with lcdReadButtons() - */ -#define LCD_BTN_LEFT 1 -/** - * CENTER button on LCD for use with lcdReadButtons() - */ -#define LCD_BTN_CENTER 2 -/** - * RIGHT button on LCD for use with lcdReadButtons() - */ -#define LCD_BTN_RIGHT 4 - -/** - * Clears the LCD screen on the specified port. - * - * Printing to a line implicitly overwrites the contents, so clearing should only be required - * at startup. - * - * @param lcdPort the LCD to clear, either uart1 or uart2 - */ -void lcdClear(FILE *lcdPort); -/** - * Initializes the LCD port, but does not change the text or settings. - * - * If the LCD was not initialized before, the text currently on the screen will be undefined. - * The port will not be usable with standard serial port functions until the LCD is stopped. - * - * @param lcdPort the LCD to initialize, either uart1 or uart2 - */ -void lcdInit(FILE *lcdPort); -/** - * Prints the formatted string to the attached LCD. - * - * The output string will be truncated as necessary to fit on the LCD screen, 16 characters - * wide. It is probably better to generate the string in a local buffer and use lcdSetText() - * but this method is provided for convenience. - * - * @param lcdPort the LCD to write, either uart1 or uart2 - * @param line the LCD line to write, either 1 or 2 - * @param formatString the format string as specified in fprintf() - */ -#ifdef DOXYGEN -void lcdPrint(FILE *lcdPort, unsigned char line, const char *formatString, ...); -#else -void __attribute__ ((format (printf, 3, 4))) lcdPrint(FILE *lcdPort, unsigned char line, - const char *formatString, ...); -#endif -/** - * Reads the user button status from the LCD display. - * - * For example, if the left and right buttons are pushed, (1 | 4) = 5 will be returned. 0 is - * returned if no buttons are pushed. - * - * @param lcdPort the LCD to poll, either uart1 or uart2 - * @return the buttons pressed as a bit mask - */ -unsigned int lcdReadButtons(FILE *lcdPort); -/** - * Sets the specified LCD backlight to be on or off. - * - * Turning it off will save power but may make it more difficult to read in dim conditions. - * - * @param lcdPort the LCD to adjust, either uart1 or uart2 - * @param backlight true to turn the backlight on, or false to turn it off - */ -void lcdSetBacklight(FILE *lcdPort, bool backlight); -/** - * Prints the string buffer to the attached LCD. - * - * The output string will be truncated as necessary to fit on the LCD screen, 16 characters - * wide. This function, like fprint(), is much, much faster than a formatted routine such as - * lcdPrint() and consumes less memory. - * - * @param lcdPort the LCD to write, either uart1 or uart2 - * @param line the LCD line to write, either 1 or 2 - * @param buffer the string to write - */ -void lcdSetText(FILE *lcdPort, unsigned char line, const char *buffer); -/** - * Shut down the specified LCD port. - * - * @param lcdPort the LCD to stop, either uart1 or uart2 - */ -void lcdShutdown(FILE *lcdPort); - -// -------------------- Real-time scheduler functions -------------------- -/** - * Only this many tasks can exist at once. Attempts to create further tasks will not succeed - * until tasks end or are destroyed, AND the idle task cleans them up. - * - * Changing this value will not change the limit without a kernel recompile. The idle task - * and VEX daemon task count against the limit. The user autonomous() or teleop() also counts - * against the limit, so 12 tasks usually remain for other uses. - */ -#define TASK_MAX 16 -/** - * The maximum number of available task priorities, which run from 0 to 5. - * - * Changing this value will not change the priority count without a kernel recompile. - */ -#define TASK_MAX_PRIORITIES 6 -/** - * The lowest priority that can be assigned to a task, which puts it on a level with the idle - * task. This may cause severe performance problems and is generally not recommended. - */ -#define TASK_PRIORITY_LOWEST 0 -/** - * The default task priority, which should be used for most tasks. - * - * Default tasks such as autonomous() inherit this priority. - */ -#define TASK_PRIORITY_DEFAULT 2 -/** - * The highest priority that can be assigned to a task. Unlike the lowest priority, this - * priority can be safely used without hampering interrupts. Beware of deadlock. - */ -#define TASK_PRIORITY_HIGHEST (TASK_MAX_PRIORITIES - 1) -/** - * The recommended stack size for a new task that does an average amount of work. This stack - * size is used for default tasks such as autonomous(). - * - * This is probably OK for 4-5 levels of function calls and the use of printf() with several - * arguments. Tasks requiring deep recursion or large local buffers will need a bigger stack. - */ -#define TASK_DEFAULT_STACK_SIZE 512 -/** - * The minimum stack depth for a task. Scheduler state is stored on the stack, so even if the - * task never uses the stack, at least this much space must be allocated. - * - * Function calls and other seemingly innocent constructs may place information on the stack. - * Err on the side of a larger stack when possible. - */ -#define TASK_MINIMAL_STACK_SIZE 64 - -/** - * Constant returned from taskGetState() when the task is dead or nonexistant. - */ -#define TASK_DEAD 0 -/** - * Constant returned from taskGetState() when the task is actively executing. - */ -#define TASK_RUNNING 1 -/** - * Constant returned from taskGetState() when the task is exists and is available to run, but - * not currently running. - */ -#define TASK_RUNNABLE 2 -/** - * Constant returned from taskGetState() when the task is delayed or blocked waiting for a - * semaphore, mutex, or I/O operation. - */ -#define TASK_SLEEPING 3 -/** - * Constant returned from taskGetState() when the task is suspended using taskSuspend(). - */ -#define TASK_SUSPENDED 4 - -/** - * Type by which tasks are referenced. - * - * As this is a pointer type, it can be safely passed or stored by value. - */ -typedef void * TaskHandle; -/** - * Type by which mutexes are referenced. - * - * As this is a pointer type, it can be safely passed or stored by value. - */ -typedef void * Mutex; -/** - * Type by which semaphores are referenced. - * - * As this is a pointer type, it can be safely passed or stored by value. - */ -typedef void * Semaphore; -/** - * Type for defining task functions. Task functions must accept one parameter of type - * "void *"; they need not use it. - * - * For example: - * - * void MyTask(void *ignore) { - * while (1); - * } - */ -typedef void (*TaskCode)(void *); - -/** - * Creates a new task and add it to the list of tasks that are ready to run. - * - * @param taskCode the function to execute in its own task - * @param stackDepth the number of variables available on the stack (4 * stackDepth bytes will - * be allocated on the Cortex) - * @param parameters an argument passed to the taskCode function - * @param priority a value from TASK_PRIORITY_LOWEST to TASK_PRIORITY_HIGHEST determining the - * initial priority of the task - * @return a handle to the created task, or NULL if an error occurred - */ -TaskHandle taskCreate(TaskCode taskCode, const unsigned int stackDepth, void *parameters, - const unsigned int priority); -/** - * Delays the current task for a given number of milliseconds. - * - * Delaying for a period of zero will force a reschedule, where tasks of equal priority may be - * scheduled if available. The calling task will still be available for immediate rescheduling - * once the other tasks have had their turn or if nothing of equal or higher priority is - * available to be scheduled. - * - * 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 - * taskDelayUntil(). - * - * @param msToDelay the number of milliseconds to wait, with 1000 milliseconds per second - */ -void taskDelay(const unsigned long msToDelay); -/** - * Delays the current task until a specified time. The task will be unblocked - * at the time *previousWakeTime + cycleTime, and *previousWakeTime will be changed to reflect - * the time at which the task will unblock. - * - * If the target time is in the past, no delay occurs, but a reschedule is forced, as if - * taskDelay() was called with an argument of zero. If the sum of cycleTime and - * *previousWakeTime overflows or underflows, undefined behavior occurs. - * - * This function should be used by cyclical tasks to ensure a constant execution frequency. - * While taskDelay() specifies a wake time relative to the time at which the function is - * called, taskDelayUntil() specifies the absolute future time at which it wishes to unblock. - * Calling taskDelayUntil with the same cycleTime parameter value in a loop, with - * previousWakeTime referring to a local variable initialized to millis(), will cause the - * loop to execute with a fixed period. - * - * @param previousWakeTime a pointer to the location storing the last unblock time, obtained - * by using the "&" operator on a variable (e.g. "taskDelayUntil(&now, 50);") - * @param cycleTime the number of milliseconds to wait, with 1000 milliseconds per second - */ -void taskDelayUntil(unsigned long *previousWakeTime, const unsigned long cycleTime); -/** - * Kills and removes the specified task from the kernel task list. - * - * Deleting the last task will end the program, possibly leading to undesirable states as - * some outputs may remain in their last set configuration. - * - * NOTE: The idle task is responsible for freeing the kernel allocated memory from tasks that - * have been deleted. It is therefore important that the idle task is not starved of - * processing time. Memory allocated by the task code is not automatically freed, and should be - * freed before the task is deleted. - * - * @param taskToDelete the task to kill; passing NULL kills the current task - */ -void taskDelete(TaskHandle taskToDelete); -/** - * Determines the number of tasks that are currently being managed. - * - * This includes all ready, blocked and suspended tasks. A task that has been deleted but not - * yet freed 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 running, waiting, or suspended - */ -unsigned int taskGetCount(); -/** - * Retrieves the state of the specified task. Note that the state of tasks which have died may - * be re-used for future tasks, causing the value returned by this function to reflect a - * different task than possibly intended in this case. - * - * @param task Handle to the task to query. Passing NULL will query the current task status - * (which will, by definition, be TASK_RUNNING if this call returns) - * - * @return A value reflecting the task's status, one of the constants TASK_DEAD, TASK_RUNNING, - * TASK_RUNNABLE, TASK_SLEEPING, or TASK_SUSPENDED - */ -unsigned int taskGetState(TaskHandle task); -/** - * Obtains the priority of the specified task. - * - * @param task the task to check; passing NULL checks the current task - * @return the priority of that task from 0 to TASK_MAX_PRIORITIES - */ -unsigned int taskPriorityGet(const TaskHandle task); -/** - * Sets the priority of the specified task. - * - * A context switch may occur before the function returns if the priority being set is higher - * than the currently executing task and the task being mutated is available to be scheduled. - * - * @param task the task to change; passing NULL changes the current task - * @param newPriority a value between TASK_PRIORITY_LOWEST and TASK_PRIORITY_HIGHEST inclusive - * indicating the new task priority - */ -void taskPrioritySet(TaskHandle task, const unsigned int newPriority); -/** - * Resumes the specified task. - * - * A task that has been suspended by one or more calls to taskSuspend() will be made available - * for scheduling again by a call to taskResume(). If the task was not suspended at the time - * of the call to taskResume(), undefined behavior occurs. - * - * @param taskToResume the task to change; passing NULL is not allowed as the current task - * cannot be suspended (it is obviously running if this function is called) - */ -void taskResume(TaskHandle taskToResume); -/** - * Starts a task which will periodically call the specified function. - * - * Intended for use as a quick-start skeleton for cyclic tasks with higher priority than the - * "main" tasks. The created task will have priority TASK_PRIORITY_DEFAULT + 1 with the default - * stack size. To customize behavior, create a task manually with the specified function. - * - * This task will automatically terminate after one further function invocation when the robot - * is disabled or when the robot mode is switched. - * - * @param fn the function to call in this loop - * @param increment the delay between successive calls in milliseconds; the taskDelayUntil() - * function is used for accurate cycle timing - * @return a handle to the task, or NULL if an error occurred - */ -TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment); -/** - * Suspends the specified task. - * - * When suspended a task will not be scheduled, regardless of whether it might be otherwise - * available to run. - * - * @param taskToSuspend the task to suspend; passing NULL suspends the current task - */ -void taskSuspend(TaskHandle taskToSuspend); - -/** - * Creates a semaphore intended for synchronizing tasks. To prevent some critical code from - * simultaneously modifying a shared resource, use mutexes instead. - * - * Semaphores created using this function can be accessed using the semaphoreTake() and - * semaphoreGive() functions. The mutex functions must not be used on objects of this type. - * - * This type of object does not need to have balanced take and give calls, so priority - * inheritance is not used. Semaphores can be signalled by an interrupt routine. - * - * @return a handle to the created semaphore - */ -Semaphore semaphoreCreate(); -/** - * Signals a semaphore. Tasks waiting for a signal using semaphoreTake() will be unblocked by - * this call and can continue execution. - * - * Slow processes can give semaphores when ready, and fast processes waiting to take the - * semaphore will continue at that point. - * - * @param semaphore the semaphore to signal - * @return true if the semaphore was successfully given, or false if the semaphore was not - * taken since the last give - */ -bool semaphoreGive(Semaphore semaphore); -/** - * Waits on a semaphore. If the semaphore is already in the "taken" state, the current task - * will wait for the semaphore to be signaled. Other tasks can run during this time. - * - * @param semaphore the semaphore to wait - * @param blockTime the maximum time to wait for the semaphore to be given, where -1 - * specifies an infinite timeout - * @return true if the semaphore was successfully taken, or false if the timeout expired - */ -bool semaphoreTake(Semaphore semaphore, const unsigned long blockTime); -/** - * Deletes the specified semaphore. This function can be dangerous; deleting semaphores being - * waited on by a task may cause deadlock or a crash. - * - * @param semaphore the semaphore to destroy - */ -void semaphoreDelete(Semaphore semaphore); - -/** - * Creates a mutex intended to allow only one task to use a resource at a time. For signalling - * and synchronization, try using semaphores. - * - * Mutexes created using this function can be accessed using the mutexTake() and mutexGive() - * functions. The semaphore functions must not be used on objects of this type. - * - * This type of object uses a priority inheritance mechanism so a task 'taking' a mutex MUST - * ALWAYS 'give' the mutex back once the mutex is no longer required. - * - * @return a handle to the created mutex - */ -Mutex mutexCreate(); -/** - * Relinquishes a mutex so that other tasks can use the resource it guards. The mutex must be - * held by the current task using a corresponding call to mutexTake. - * - * @param mutex the mutex to release - * @return true if the mutex was released, or false if the mutex was not already held - */ -bool mutexGive(Mutex mutex); -/** - * Requests a mutex so that other tasks cannot simultaneously use the resource it guards. - * The mutex must not already be held by the current task. If another task already - * holds the mutex, the function will wait for the mutex to be released. Other tasks can run - * during this time. - * - * @param mutex the mutex to request - * @param blockTime the maximum time to wait for the mutex to be available, where -1 - * specifies an infinite timeout - * @return true if the mutex was successfully taken, or false if the timeout expired - */ -bool mutexTake(Mutex mutex, const unsigned long blockTime); -/** - * Deletes the specified mutex. This function can be dangerous; deleting semaphores being - * waited on by a task may cause deadlock or a crash. - * - * @param mutex the mutex to destroy - */ -void mutexDelete(Mutex mutex); - -/** - * Wiring-compatible alias of taskDelay(). - * - * @param time the duration of the delay in milliseconds (1 000 milliseconds per second) - */ -void delay(const unsigned long time); -/** - * Wait for approximately the given number of microseconds. - * - * The method used for delaying this length of time may vary depending on the argument. - * The current task will always be delayed by at least the specified period, but possibly much - * more depending on CPU load. In general, this function is less reliable than delay(). Using - * this function in a loop may hog processing time from other tasks. - * - * @param us the duration of the delay in microseconds (1 000 000 microseconds per second) - */ -void delayMicroseconds(const unsigned long us); -/** - * Returns the number of microseconds since Cortex power-up. There are 10^6 microseconds in a - * second, so as a 32-bit integer, this will overflow and wrap back to zero every two hours or - * so. - * - * This function is Wiring-compatible. - * - * @return the number of microseconds since the Cortex was turned on or the last overflow - */ -unsigned long micros(); -/** - * Returns the number of milliseconds since Cortex power-up. There are 1000 milliseconds in a - * second, so as a 32-bit integer, this will not overflow for 50 days. - * - * This function is Wiring-compatible. - * - * @return the number of milliseconds since the Cortex was turned on - */ -unsigned long millis(); -/** - * Alias of taskDelay() intended to help EasyC users. - * - * @param time the duration of the delay in milliseconds (1 000 milliseconds per second) - */ -void wait(const unsigned long time); -/** - * Alias of taskDelayUntil() intended to help EasyC users. - * - * @param previousWakeTime a pointer to the last wakeup time - * @param time the duration of the delay in milliseconds (1 000 milliseconds per second) - */ -void waitUntil(unsigned long *previousWakeTime, const unsigned long time); - -// End C++ extern to C -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Nate's Position Testing/Shooter Testing/include/main.h b/Nate's Position Testing/Shooter Testing/include/main.h deleted file mode 100644 index b6da316..0000000 --- a/Nate's Position Testing/Shooter Testing/include/main.h +++ /dev/null @@ -1,119 +0,0 @@ -/** @file main.h - * @brief Header file for global functions - * - * Any experienced C or C++ programmer knows the importance of header files. For those who - * do not, a header file allows multiple files to reference functions in other files without - * necessarily having to see the code (and therefore causing a multiple definition). To make - * a function in "opcontrol.c", "auto.c", "main.c", or any other C file visible to the core - * implementation files, prototype it here. - * - * This file is included by default in the predefined stubs in each VEX Cortex PROS Project. - * - * Copyright (c) 2011-2014, Purdue University ACM SIG BOTS. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Purdue University ACM SIG BOTS nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL PURDUE UNIVERSITY ACM SIG BOTS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Purdue Robotics OS contains FreeRTOS (http://www.freertos.org) whose source code may be - * obtained from http://sourceforge.net/projects/freertos/files/ or on request. - */ -#ifndef MAIN_H_ - -// This prevents multiple inclusion, which isn't bad for this file but is good practice -#define MAIN_H_ - -#include - -// Allow usage of this file in C++ programs -#ifdef __cplusplus -extern "C" { -#endif -// A function prototype looks exactly like its declaration, but with a semicolon instead of -// actual code. If a function does not match a prototype, compile errors will occur. - -// Prototypes for initialization, operator control and autonomous - -/** - * Runs the user autonomous code. This function will be started in its own task with the default - * priority and stack size whenever the robot is enabled via the Field Management System or the - * VEX Competition Switch in the autonomous mode. If the robot is disabled or communications is - * lost, the autonomous task will be stopped by the kernel. Re-enabling the robot will restart - * the task, not re-start it from where it left off. - * - * Code running in the autonomous task cannot access information from the VEX Joystick. However, - * the autonomous function can be invoked from another task if a VEX Competition Switch is not - * available, and it can access joystick information if called in this way. - * - * The autonomous task may exit, unlike operatorControl() which should never exit. If it does - * so, the robot will await a switch to another mode or disable/enable cycle. - */ -void autonomous(); -/** - * Runs pre-initialization code. This function will be started in kernel mode one time while the - * VEX Cortex is starting up. As the scheduler is still paused, most API functions will fail. - * - * The purpose of this function is solely to set the default pin modes (pinMode()) and port - * states (digitalWrite()) of limit switches, push buttons, and solenoids. It can also safely - * configure a UART port (usartOpen()) but cannot set up an LCD (lcdInit()). - */ -void initializeIO(); -/** - * Runs user initialization code. This function will be started in its own task with the default - * priority and stack size once when the robot is starting up. It is possible that the VEXnet - * communication link may not be fully established at this time, so reading from the VEX - * Joystick may fail. - * - * This function should initialize most sensors (gyro, encoders, ultrasonics), LCDs, global - * variables, and IMEs. - * - * This function must exit relatively promptly, or the operatorControl() and autonomous() tasks - * will not start. An autonomous mode selection menu like the pre_auton() in other environments - * can be implemented in this task if desired. - */ -void initialize(); -/** - * Runs the user operator control code. This function will be started in its own task with the - * default priority and stack size whenever the robot is enabled via the Field Management System - * or the VEX Competition Switch in the operator control mode. If the robot is disabled or - * communications is lost, the operator control task will be stopped by the kernel. Re-enabling - * the robot will restart the task, not resume it from where it left off. - * - * If no VEX Competition Switch or Field Management system is plugged in, the VEX Cortex will - * run the operator control task. Be warned that this will also occur if the VEX Cortex is - * tethered directly to a computer via the USB A to A cable without any VEX Joystick attached. - * - * Code running in this task can take almost any action, as the VEX Joystick is available and - * the scheduler is operational. However, proper use of delay() or taskDelayUntil() is highly - * recommended to give other tasks (including system tasks such as updating LCDs) time to run. - * - * This task should never exit; it should end with some kind of infinite loop, even if empty. - */ -extern Encoder encoder1,encoder2; -void operatorControl(); - -// End C++ export structure -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Nate's Position Testing/Shooter Testing/src/Makefile b/Nate's Position Testing/Shooter Testing/src/Makefile deleted file mode 100644 index 865f1e7..0000000 --- a/Nate's Position Testing/Shooter Testing/src/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# Makefile for compiling PROS projects - -# Path to project root (NO trailing slash!) -ROOT=.. -# Binary output directory -BINDIR=$(ROOT)/bin - -# Nothing below here needs to be modified by typical users - -# Include common aspects of this project --include $(ROOT)/common.mk - -ASMSRC:=$(wildcard *.$(ASMEXT)) -ASMOBJ:=$(patsubst %.o,$(BINDIR)/%.o,$(ASMSRC:.$(ASMEXT)=.o)) -HEADERS:=$(wildcard *.$(HEXT)) -### Special section for Cortex projects ### -HEADERS_2:=$(wildcard ../include/*.$(HEXT)) -### End special section ### -CSRC=$(wildcard *.$(CEXT)) -COBJ:=$(patsubst %.o,$(BINDIR)/%.o,$(CSRC:.$(CEXT)=.o)) -CPPSRC:=$(wildcard *.$(CPPEXT)) -CPPOBJ:=$(patsubst %.o,$(BINDIR)/%.o,$(CPPSRC:.$(CPPEXT)=.o)) -OUT:=$(BINDIR)/$(OUTNAME) - -.PHONY: all - -# By default, compile program -all: . - -# Compiles the program if anything is changed -.: $(ASMOBJ) $(COBJ) $(CPPOBJ) - @touch . - -# Assembly source file management -$(ASMOBJ): $(BINDIR)/%.o: %.$(ASMEXT) - @echo AS $< - @$(AS) $(AFLAGS) -o $@ $< - -### Special section for Cortex projects ### - -# Object management -$(COBJ): $(BINDIR)/%.o: %.$(CEXT) $(HEADERS) $(HEADERS_2) - @echo CC $(INCLUDE) $< - @$(CC) $(INCLUDE) $(CFLAGS) -o $@ $< - -$(CPPOBJ): $(BINDIR)/%.o: %.$(CPPEXT) $(HEADERS) $(HEADERS_2) - @echo CPC $(INCLUDE) $< - @$(CPPCC) $(INCLUDE) $(CPPFLAGS) -o $@ $< - -### End special section ### diff --git a/Nate's Position Testing/Shooter Testing/src/auto.c b/Nate's Position Testing/Shooter Testing/src/auto.c deleted file mode 100644 index 9df57af..0000000 --- a/Nate's Position Testing/Shooter Testing/src/auto.c +++ /dev/null @@ -1,52 +0,0 @@ -/** @file auto.c - * @brief File for autonomous code - * - * This file should contain the user autonomous() function and any functions related to it. - * - * Copyright (c) 2011-2014, Purdue University ACM SIG BOTS. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Purdue University ACM SIG BOTS nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL PURDUE UNIVERSITY ACM SIG BOTS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Purdue Robotics OS contains FreeRTOS (http://www.freertos.org) whose source code may be - * obtained from http://sourceforge.net/projects/freertos/files/ or on request. - */ - -#include "main.h" - -/* - * Runs the user autonomous code. This function will be started in its own task with the default - * priority and stack size whenever the robot is enabled via the Field Management System or the - * VEX Competition Switch in the autonomous mode. If the robot is disabled or communications is - * lost, the autonomous task will be stopped by the kernel. Re-enabling the robot will restart - * the task, not re-start it from where it left off. - * - * Code running in the autonomous task cannot access information from the VEX Joystick. However, - * the autonomous function can be invoked from another task if a VEX Competition Switch is not - * available, and it can access joystick information if called in this way. - * - * The autonomous task may exit, unlike operatorControl() which should never exit. If it does - * so, the robot will await a switch to another mode or disable/enable cycle. - */ -void autonomous() { -} diff --git a/Nate's Position Testing/Shooter Testing/src/init.c b/Nate's Position Testing/Shooter Testing/src/init.c deleted file mode 100644 index fd9eeb4..0000000 --- a/Nate's Position Testing/Shooter Testing/src/init.c +++ /dev/null @@ -1,84 +0,0 @@ -/** @file init.c - * @brief File for initialization code - * - * This file should contain the user initialize() function and any functions related to it. - * - * Copyright (c) 2011-2014, Purdue University ACM SIG BOTS. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Purdue University ACM SIG BOTS nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL PURDUE UNIVERSITY ACM SIG BOTS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Purdue Robotics OS contains FreeRTOS (http://www.freertos.org) whose source code may be - * obtained from http://sourceforge.net/projects/freertos/files/ or on request. - */ - -#include "main.h" -Encoder encoder1,encoder2; -/* - * Runs pre-initialization code. This function will be started in kernel mode one time while the - * VEX Cortex is starting up. As the scheduler is still paused, most API functions will fail. - * - * The purpose of this function is solely to set the default pin modes (pinMode()) and port - * states (digitalWrite()) of limit switches, push buttons, and solenoids. It can also safely - * configure a UART port (usartOpen()) but cannot set up an LCD (lcdInit()). - */ -void initializeIO() { - - - pinMode(1,INPUT); - pinMode(2,INPUT); - pinMode(3,INPUT); - pinMode(4,INPUT); - pinMode(5,INPUT); - pinMode(6,INPUT); - pinMode(7,INPUT); - pinMode(8,INPUT); - - - - -// Setup sensors. - - - - -}/* - * Runs user initialization code. This function will be started in its own task with the default - * priority and stack size once when the robot is starting up. It is possible that the VEXnet - * communication link may not be fully established at this time, so reading from the VEX - * Joystick may fail. - * - * This function should initialize most sensors (gyro, encoders, ultrasonics), LCDs, global - * variables, and IMEs. - * - * This function must exit relatively promptly, or the operatorControl() and autonomous() tasks - * will not start. An autonomous mode selection menu like the pre_auton() in other environments - * can be implemented in this task if desired. - */ -void initialize() { - lcdInit(uart2); - lcdClear(uart2); - lcdSetBacklight(uart2,1); - encoder1 = encoderInit(3,4,true); - encoder2 = encoderInit(5,6,true); -} diff --git a/Nate's Position Testing/Shooter Testing/src/opcontrol.c b/Nate's Position Testing/Shooter Testing/src/opcontrol.c deleted file mode 100644 index df21076..0000000 --- a/Nate's Position Testing/Shooter Testing/src/opcontrol.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "main.h" - -#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) -#define PI =3.14159 -/* - * Runs the user operator control code. This function will be started in its own task with the - * default priority and stack size whenever the robot is enabled via the Field Management System - * or the VEX Competition Switch in the operator control mode. If the robot is disabled or - * communications is lost, the operator control task will be stopped by the kernel. Re-enabling - * the robot will restart the task, not resume it from where it left off. - * - * If no VEX Competition Switch or Field Management system is plugged in, the VEX Cortex will - * run the operator control task. Be warned that this will also occur if the VEX Cortex is - * tethered directly to a computer via the USB A to A cable without any VEX Joystick attached. - * - * Code running in this task can take almost any action, as the VEX Joystick is available and - * the scheduler is operational. However, proper use of delay() or taskDelayUntil() is highly - * recommended to give other tasks (including system tasks such as updating LCDs) time to run. - * - * This task should never exit; it should end with some kind of infinite loop, even if empty. - * -*/ - -/* notes for Clyne: - * Other processes should not interupt the collection of data: - * rotation calculation should be and data collection should be a high priority/primary task - * Main task= manages tasks, init variables, reset functions (sensors, etc) - * Primary = sensor data collections and calculations - * Secondary = drive tasks - * - * - * - */ -static long lVel,rVel,deltaPos,deltaTime,startTheta, - heading,lDist,rDist,xPos,yPos, - track=15; -void operatorControl() { - heading=startTheta; - while (1) { - - //get time 1 the first time - heading=((lDist-rDist)/(track*2*PI))*360+startTheta;//heading in degrees. might need to be radians for cosine functions - //get time 2 - deltaPos=(lVel+rVel)/2*deltaTime; - xPos+=cos(heading)*deltaPos; - yPos+=sin(heading)*deltaPos; - //get time 1 - delay(20); - - } -} diff --git a/Position Calculator.numbers b/Position Calculator.numbers deleted file mode 100644 index d3f9e9b..0000000 Binary files a/Position Calculator.numbers and /dev/null differ diff --git a/Positioning or something.numbers b/Positioning or something.numbers deleted file mode 100644 index 79a1665..0000000 Binary files a/Positioning or something.numbers and /dev/null differ diff --git a/To Do:Read.rtf b/To Do:Read.rtf deleted file mode 100644 index a5f9208..0000000 --- a/To Do:Read.rtf +++ /dev/null @@ -1,8 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf130 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\margl1440\margr1440\vieww10800\viewh8400\viewkind0 -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 - -\f0\fs24 \cf0 Articles/PDFs to Read:\ -{\field{\*\fldinst{HYPERLINK "http://www.ridgesoft.com/articles/trackingposition/TrackingPosition.pdf"}}{\fldrslt http://www.ridgesoft.com/articles/trackingposition/TrackingPosition.pdf}}} \ No newline at end of file diff --git a/common.mk b/common.mk index a552764..58098f5 100644 --- a/common.mk +++ b/common.mk @@ -32,7 +32,7 @@ OUTNAME=output.elf # Flags for programs AFLAGS:=$(MCUAFLAGS) ARFLAGS:=$(MCUCFLAGS) -CCFLAGS:=-s -c -Wall $(MCUCFLAGS) -Os -ffunction-sections -fsigned-char -fomit-frame-pointer -fsingle-precision-constant +CCFLAGS:=-c -Wall $(MCUCFLAGS) -Os -ffunction-sections -fsigned-char -fomit-frame-pointer -fsingle-precision-constant CFLAGS:=$(CCFLAGS) -std=gnu99 -Werror=implicit-function-declaration CPPFLAGS:=$(CCFLAGS) -fno-exceptions -fno-rtti -felide-constructors LDFLAGS:=-Wall $(MCUCFLAGS) $(MCULFLAGS) -Wl,--gc-sections diff --git a/include/API.h b/include/API.h index 32d8686..7de7889 100644 --- a/include/API.h +++ b/include/API.h @@ -504,7 +504,6 @@ unsigned int imeInitializeAll(); * * \c 240.448 for the 269 IME * * \c 627.2 for the 393 IME in high torque mode (factory default) * * \c 392 for the 393 IME in high speed mode - * * \c 261.333 for the 393 IME in turbo speed mode * * If the IME address is invalid, or the IME has not been reset or initialized, the value * stored in *value is undefined. @@ -528,7 +527,6 @@ bool imeGet(unsigned char address, int *value); * * \c 30.056 for the 269 IME * * \c 39.2 for the 393 IME in high torque mode (factory default) * * \c 24.5 for the 393 IME in high speed mode - * * \c 16.3333125 for the 393 IME in turbo speed mode * * If the IME address is invalid, or the IME has not been reset or initialized, the value * stored in *value is undefined. diff --git a/include/main.h b/include/main.h index 7022f11..cc616d8 100644 --- a/include/main.h +++ b/include/main.h @@ -2,12 +2,143 @@ #define MAIN_H_ #include -#include +#include + +typedef struct{ + int x; + int y; +}vec2; + +typedef enum { + UP, + DOWN, + KEY_UP +} Button; + +typedef struct { + unsigned int num; + struct Side { + struct Group { + Button l; + Button r; + Button u; + Button d; + } front, back; + vec2 stick; + } left, right; +} Controller; + +typedef struct { + enum type { + DIGITAL, + ANALOG, + GYRO, + ULTRASONIC + } type; + union data { + Gyro gyro; + Ultrasonic sonic; + } data; + unsigned int port; + int value; + int initial; +} Sensor; + +typedef struct { + bool kill_req; + bool exiting; + TaskCode code; + TaskHandle handle; + void *param; +} Process; #ifdef __cplusplus extern "C" { #endif +#define DEFAULT_TRPM trpm = 1850; +#define EXTRA_TRPM trpm = 1900; + +#define PI 3.14159265L + +#define LCD_PORT uart2 + +/** + * Be sure that getIMEPort() matches these values (see sensor.c). + */ + +enum MOTOR_MAP { + CANNON_LEFT = 1, + CANNON_RIGHT, + LIFT_PUSHER, + INTAKE_1, + INTAKE_2, + DRIVE_RIGHT, + DRIVE_LEFT, + LIFT_1, + LIFT_2, + LIFT_ROTATER +}; + +enum MOTOR_IME_MAP { + DRIVE_RIGHT_IME = 0, + DRIVE_LEFT_IME, + LIFT_ROTATER_IME, + LIFT_1_IME, + LIFT_2_IME, + CANNON_LEFT_IME, + CANNON_RIGHT_IME +}; + +extern unsigned char MOTOR_USE_MAP[10]; + +#define motorTake(p,k) MOTOR_USE_MAP[p-1] = k; +#define motorFree(p) MOTOR_USE_MAP[p-1] = 0; +#define motorSetK(p,s,k) if(!MOTOR_USE_MAP[p-1] || MOTOR_USE_MAP[p-1] == k){ motorSet(p,s); } +#define motorSetN(p,s) motorSetK(p,s,0) + +int getIMEPort(unsigned int port); +int getIME(unsigned int port); +int getIMEVelocity(unsigned int port); + +/** + * Controller library functions + */ + +#define keyUp(b) (b == KEY_UP) +#define keyDown(b) (b == DOWN) + +void setEvent(Controller *c); + +/** + * Sensor library functions + */ + +#define LIGHT_THRESH_DEFAULT 50 +#define SONIC_THRESH_DEFAULT 8 + +#define initUltrasonic(p1,p2) initSensor((p2<<16)|p1,ULTRASONIC) +Sensor initSensor(uint32_t port,unsigned char type); + +#define getSensor(s) (s.value) +int readSensor(Sensor *s); + +#define diffSensor(s) (s.value - s.initial) +#define underSensor(s,t) (diffSensor(s) < -t) +#define overSensor(s,t) (diffSensor(s) > t) + +/** + * Process library functions + */ + +#define taskInit(h,p) if(!h) h = taskCreate(h##Code,TASK_DEFAULT_STACK_SIZE,p,TASK_PRIORITY_DEFAULT); + +/** + * Main function declarations + */ + +extern void softwareReset(void); + void autonomous(); void initializeIO(); void initialize(); diff --git a/include/zephyr.h b/include/zephyr.h deleted file mode 100644 index 11f922f..0000000 --- a/include/zephyr.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef ZEPHYR_H_ -#define ZEPHYR_H_ - -#include - -#define PI 3.14159265L - -#define APPLY_THRESH(n,t) if(n < t && n > -t){ n = 0;} - -/* - * Comment to disable LCD support. -*/ - -#define LCD_PORT uart1 - -#define LCD_RATE 500 - -#ifdef LCD_PORT -#endif // LCD_PORT - -/* - * Comment to disable gyro support. -*/ - -#define GYRO_PORT 2 - -#ifdef GYRO_PORT - -void zGyroInit(void); -int zGyroGet(void); -void zGyroReset(void); - -#endif // GYRO_PORT - -/* - * Comment to disable IME support. -*/ - -#define IME_ENABLE - -#ifdef IME_ENABLE - -void zIMEInit(void); - -#endif // IME_ENABLE - -/* - * DRIVE_NORMAL will override tank drive options. -*/ - -#define DRIVE_JOY 1 -#define DRIVE_THRESHOLD 10 - -#define DRIVE_NORMAL 3 - -//#define DRIVE_TANK_LEFT 3 -//#define DRIVE_TANK_RIGHT 2 - -#define zJoyDigital(j,g,b) joystickGetDigital(j,g,b) -#define zJoyAnalog(j,a) joystickGetAnalog(j,a) - -void zMotorSet(const char *, // Motor Name - int, // Desired Speed - unsigned int // Caller ID - ); -char zMotorGet(const char *); // Motor Name - -void zMotorTake(const char *,unsigned int); -void zMotorReturn(const char *); - -#ifdef IME_ENABLE - -int zMotorIMEGet(const char *); // Motor Name -int zMotorIMEGetVelocity(const char *); // Motor Name -bool zMotorIMEReset(const char *motor); - -#endif // IME_ENABLE - -void zDriveUpdate(void); - -char zGetDigitalMotorSpeed(unsigned char, // Joystick No. - unsigned char, // Button Group - unsigned char, // Positive Button - unsigned char, // Negative Button - char // Desired Speed - ); - -#endif // ZEPHYR_H_ diff --git a/src/auto.c b/src/auto.c deleted file mode 100644 index c26bfd9..0000000 --- a/src/auto.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -//#define TARGET_RPM 1700 - -/*void autonomous(){ - static double cl,cr,ca; - static char speed; - - speed = 30; - - do{ - speed += 10; - zMotorSet("Left cannon",-speed); - zMotorSet("Right cannon",speed); - delay(800); - cl = zMotorIMEGetVelocity("Left cannon") / 16.3333125L * 9; - cr = -zMotorIMEGetVelocity("Right cannon") / 16.3333125L * 9; - ca = (cl + cr) / 2; - }while(ca < TARGET_RPM); - - zMotorSet("Misc",127); - delay(900); - zMotorSet("Misc",-127); - delay(900); - zMotorSet("Misc",0); - - motorStopAll(); -}*/ diff --git a/src/control.c b/src/control.c new file mode 100644 index 0000000..0ca6026 --- /dev/null +++ b/src/control.c @@ -0,0 +1,72 @@ +#include + +void setEvent(Controller *c){ + c->left.stick.x = joystickGetAnalog(c->num, 4); + c->left.stick.y = joystickGetAnalog(c->num, 3); + + c->right.stick.x = joystickGetAnalog(c->num, 1); + c->right.stick.y = joystickGetAnalog(c->num, 2); + + /** + * BACK RIGHT BUTTONS + */ + + if(c->right.back.d == KEY_UP)c->right.back.d = UP; + else if(c->right.back.d == DOWN && !joystickGetDigital(c->num, 6, JOY_DOWN))c->right.back.d = KEY_UP; + else c->right.back.d = joystickGetDigital(c->num, 6, JOY_DOWN); + + if(c->right.back.u == KEY_UP)c->right.back.u = UP; + else if(c->right.back.u == DOWN && !joystickGetDigital(c->num, 6, JOY_UP))c->right.back.u = KEY_UP; + else c->right.back.u = joystickGetDigital(c->num, 6, JOY_UP); + + + /* + * BACK LEFT BUTTONS + */ + if(c->left.back.d == KEY_UP)c->left.back.d = UP; + else if(c->left.back.d == DOWN && !joystickGetDigital(c->num, 5, JOY_DOWN))c->left.back.d = KEY_UP; + else c->left.back.d = joystickGetDigital(c->num, 5, JOY_DOWN); + + if(c->left.back.u == KEY_UP)c->left.back.u = UP; + else if(c->left.back.u == DOWN && !joystickGetDigital(c->num, 5, JOY_UP))c->left.back.u = KEY_UP; + else c->left.back.u = joystickGetDigital(c->num, 5, JOY_UP); + + + /* + * LEFT FRONT BUTTONS + */ + if(c->left.front.l == KEY_UP)c->left.front.l = UP; + else if(c->left.front.l == DOWN && !joystickGetDigital(c->num, 7, JOY_LEFT))c->left.front.l = KEY_UP; + else c->left.front.l = joystickGetDigital(c->num, 7, JOY_LEFT); + + if(c->left.front.r == KEY_UP)c->left.front.r = UP; + else if(c->left.front.r == DOWN && !joystickGetDigital(c->num, 7, JOY_RIGHT))c->left.front.r = KEY_UP; + else c->left.front.r = joystickGetDigital(c->num, 7, JOY_RIGHT); + + if(c->left.front.u == KEY_UP)c->left.front.u = UP; + else if(c->left.front.u == DOWN && !joystickGetDigital(c->num, 7, JOY_UP))c->left.front.u = KEY_UP; + else c->left.front.u = joystickGetDigital(c->num, 7, JOY_UP); + + if(c->left.front.d == KEY_UP)c->left.front.d = UP; + else if(c->left.front.d == DOWN && !joystickGetDigital(c->num, 7, JOY_DOWN))c->left.front.d = KEY_UP; + else c->left.front.d = joystickGetDigital(c->num, 7, JOY_DOWN); + + /* + * RIGHT FRONT BUTTONS + */ + if(c->right.front.d == KEY_UP)c->right.front.d = UP; + else if(c->right.front.d == DOWN && !joystickGetDigital(c->num, 8, JOY_DOWN))c->right.front.d = KEY_UP; + else c->right.front.d = joystickGetDigital(c->num, 8, JOY_DOWN); + + if(c->right.front.l == KEY_UP)c->right.front.l = UP; + else if(c->right.front.l == DOWN && !joystickGetDigital(c->num, 8, JOY_LEFT))c->right.front.l = KEY_UP; + else c->right.front.l = joystickGetDigital(c->num, 8, JOY_LEFT); + + if(c->right.front.u == KEY_UP)c->right.front.u = UP; + else if(c->right.front.u == DOWN && !joystickGetDigital(c->num, 8, JOY_UP))c->right.front.u = KEY_UP; + else c->right.front.u = joystickGetDigital(c->num, 8, JOY_UP); + + if(c->right.front.r == KEY_UP)c->right.front.r = UP; + else if(c->right.front.r == DOWN && !joystickGetDigital(c->num, 8, JOY_RIGHT))c->right.front.r = KEY_UP; + else c->right.front.r = joystickGetDigital(c->num, 8, JOY_RIGHT); +} diff --git a/src/init.c b/src/init.c index e85313d..f8154d7 100644 --- a/src/init.c +++ b/src/init.c @@ -1,20 +1,34 @@ #include -void initializeIO(){ -} +Sensor intakeFrontLeft, + intakeFrontRight, + intakeLiftBase, + intakeLiftTop, + robotGyro; + +Gyro gyro; -void initialize(){ +bool initializeDone = false; + +void initializeIO(void){ + intakeFrontLeft = initSensor(7,ANALOG); + intakeFrontRight = initSensor(6,ANALOG); + intakeLiftBase = initUltrasonic(1,2); + intakeLiftTop = initSensor(8,ANALOG); + //robotGyro = initSensor(2,GYRO); +} - pinMode(20,INPUT_ANALOG); - pinMode(13,INPUT_ANALOG); +void initialize(void){ + lcdInit(uart2); + lcdClear(uart2); + lcdSetBacklight(uart2,true); - lcdInit(LCD_PORT); - lcdClear(LCD_PORT); - lcdSetBacklight(LCD_PORT,true); + gyro = gyroInit(2,0); - zGyroInit(); - zIMEInit(); + imeInitializeAll(); - delay(1000); + lcdPrint(uart2,1," 5106 ZEPHYR "); + initializeDone = true; + delay(2000); } diff --git a/src/opcontrol.c b/src/opcontrol.c index 41da208..7338883 100644 --- a/src/opcontrol.c +++ b/src/opcontrol.c @@ -1,320 +1,234 @@ #include -#include #include -/** - * The distance in inches the robot starts from the goal. - */ +#define AUTO_SKILLS -#define GOAL_DISTANCE 120 +extern Sensor intakeFrontLeft, + intakeFrontRight, + intakeLiftBase, + intakeLiftTop;//, + //robotGyro; -/** - * RTTTL songs for speaker usage. - */ +extern Gyro gyro; -const char *song = "John Cena:d=4,o=5,b=125:4p,4g5,8a5,8f5,8p,1g5,4p,4a#5,8a5,8f5,8p,1g5"; -const char *xpst = "WinXP Login:d=4,o=5,b=160:4d#6.,4a#5.,2g#5.,4d#6,4a#5"; -const char *xpst2 = "WinXP Shutdown:d=4,o=5,b=125:4g#6,4d#6,4g#5,2a#5"; -const char *bound = "Nobody to Love:d=4,o=5,b=125:4d#5,2g5,4p,4g5,4f5,2g5,4d#5,4f5,2g5,4d#5,4f5,4g5,4d#5,4d#5,4f5,4g5,4a#4,1c5,4d#5,4f5,2g5,\ -4a#5,8g5,8f5,4d#5"; +extern bool initializeDone; -/** - * Contains how many milliseconds it took to enter operatorControl(), used to - * measure how long we've been in operatorControl(). - */ +static TaskHandle taskLCD = NULL, + taskPos = NULL, + taskCan = NULL, + taskArm = NULL, + taskLift = NULL, + taskAim = NULL; -static unsigned long opmillis = 0; +static float xpos = 0, + ypos = 0; -/** - * Contains a light sensor value collected at init time for object detection. - */ +static double cangle = 0; -static int lightThresh = 0; - -/** - * The value passed to motorSet() for the cannons. This variable is declared - * in a global scope so that the 'Speed Adjust' buttons can modify raw speed - * when not in RPM Tracking Mode. - */ - -static char cann = 0; - -/** - * 'rpm' is the current RPM of the cannon motors when in RPM Tracking Mode. - * 'trpm' contains the target RPM for the cannon to reach, which is adjusted - * when the robot moves. - * 'arpm' stands for Adjust RPM, and contains a value modifiable by the - * operator and added to the target RPM. - */ - -static double rpm = 0, - trpm = 1850, - arpm = 0; +static double rpm = 0, trpm = 1850, arpm = 0; static bool cannReady = false; -/** - * Contains the current X and Y position in inches. The X axis extends from - * the front of the robot, with the Y axis perpendicular to the X axis. - */ - -static double xpos=0,ypos=0; - -/** - * These bools are set by their corresponding tasks when those tasks are ran or - * stopped. These prevent multiple instances of the same task. - */ - -static bool cannonProcRun = false, - armProcRun = false, - aimProcRun = false; - -/** - * Task handles for the tasks, should they be needed. - */ - -TaskHandle taskLCD, - taskCannon, - taskArm, - taskMove, - taskAim; - -/** - * Task function prototypes so that they can be spawned from operatorControl(). - */ - -void lcdUpdateFunc(void *); -void cannonProc(void *); -void armProc(void *); -void moveProc(void *); -void aimProc(void *); - -/** - * Cause the Cortex to reset, which results in the Cortex restarting the - * operator control code. - * - * This reset is accomplished through setting two bits, SYSRESETREQ and - * VECTRESET, in the Application Interrupt and Reset Control Register (AIRCR), - * which is at a known location in memory. SYSRESETREQ will actually request - * the system reset, while VECTRESET is 'reserved for debugging'. This second - * bit may not need to be set; it's only set here because others have found it - * necessary. - */ - -#define AIRCR_ADDR 0xE000ED0C -#define VECTKEY 0x05FA -#define SYSRESETREQ (1<<2) -#define VECTRESET (1<<0) - -void softwareReset(void){ - - /* - * Read the current value of the AIRCR, since some flags currently set in - * the register need to remain the same in order for the reset to work. - */ +static Controller c[2]; - uint32_t AIRCR = *((uint32_t *)AIRCR_ADDR); +static Button No = UP; - /* - * Here we save the lower 16 bits of the register, write a special key to - * the higher 16 bits that'll allow the write to occur, and then set the - * reset flags. - */ - - AIRCR = (AIRCR & 0xFFFF) | (VECTKEY << 16) | SYSRESETREQ | VECTRESET; - - // Update the AIRCR. - - *((uint32_t *)0xE000ED0C) = AIRCR; - - /* - * This instruction causes the program to wait until the previous memory - * write is complete, ensuring it is taken into effect and the reset - * request is made. - */ +void taskLCDCode(void *); +void taskPosCode(void *); +void taskCanCode(void *); +void taskLiftCode(void *); +void taskArmCode(void *); +void taskAimCode(void *); - asm("DSB"); +void operatorControl(void){ + static bool invert = false; - // Wait until the system reset completes. - - while(1); -} - -/****************************************************************************** - * OPERATOR CONTROL * - ******************************************************************************/ - -void operatorControl(){ - - /** - * 'ui_inc' is used to have button reads happen at a certain interval. - * 'cyc' contains what song to play next off of the speaker. - */ - - static unsigned char ui_inc = 0; - static unsigned char cyc = 0; + DEFAULT_TRPM; + c[0].num = 1; + c[1].num = 2; /** - * The raw speed to set the lift motors to. + * Insure that the initialization functions were executed. */ - static char lift; + if(!initializeDone){ + initializeIO(); + initialize(); + } /** - * Collected init-time variables. + * Get initial readings from each sensor. */ - opmillis = millis(); - lightThresh = analogRead(8) - 60; + intakeFrontLeft.initial = readSensor(&intakeFrontLeft); + intakeFrontRight.initial = readSensor(&intakeFrontRight); + intakeLiftBase.initial = readSensor(&intakeLiftBase); + intakeLiftTop.initial = readSensor(&intakeLiftTop); + //robotGyro.initial = readSensor(&robotGyro); - /** - * Spawn the LCD task and the position-tracking task. - */ + taskInit(taskLCD,NULL); + taskInit(taskPos,NULL); - taskLCD=taskCreate(lcdUpdateFunc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT); - taskMove=taskCreate(moveProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT+1); + if(taskCan) + taskDelete(taskCan); while(1){ - /* - * Handle drive controls and update drive motor speeds. + /** + * Update sensor values. */ - zDriveUpdate(); - - // Set the rotating motor speed. - - if(!aimProcRun) - zMotorSet("Rotater",-zJoyAnalog(1,1) / 4,0); - - // Set the intake's speed. + readSensor(&intakeFrontLeft); + readSensor(&intakeFrontRight); + readSensor(&intakeLiftBase); + readSensor(&intakeLiftTop); + //readSensor(&robotGyro); - zMotorSet("Intake", - zGetDigitalMotorSpeed(1,5,JOY_UP,JOY_DOWN,127)/*| - zGetDigitalMotorSpeed(2,5,JOY_UP,JOY_DOWN,127)*/, - 0 - ); - - // Set the lift's speed. + /** + * Read the joystick!!! + */ - if(!armProcRun){ - lift = zGetDigitalMotorSpeed(1,6,JOY_UP,JOY_DOWN,127); - zMotorSet("Lift 1",lift,0); - zMotorSet("Lift 2",lift,0); + setEvent(&c[0]); + setEvent(&c[1]); + + if(keyUp(c[1].left.front.l)){ + taskInit(taskCan,&c[1].left.front.l); + }else if(keyUp(c[1].left.front.u)){ + /*if(!taskLift){ + c[1].left.front.u = DOWN; + taskLift = taskCreate(taskLiftCode,TASK_DEFAULT_STACK_SIZE,&c[1].left.front.u,TASK_PRIORITY_DEFAULT); + }*/ + taskInit(taskAim,&c[1].left.front.u); + }else if(keyUp(c[1].left.front.d)){ + taskInit(taskArm,&c[1].left.front.d); } - // Set the cannon's speed. + if(keyUp(c[1].right.front.u)){ + arpm += 50; + }else if(keyUp(c[1].right.front.d)){ + arpm -= 50; + }else if(keyUp(c[1].right.front.l) | keyDown(c[0].right.front.l)){ + softwareReset(); + } - if(!cannonProcRun){ - zMotorSet("Left cannon" ,-cann,0); - zMotorSet("Right cannon", cann,0); + if(keyUp(c[0].right.front.r) | keyUp(c[1].right.front.r)){ + invert ^= true; } - if(++ui_inc == 50){ - ui_inc = 0; + motorSetN(DRIVE_LEFT ,c[0].left.stick.y); + motorSetN(DRIVE_RIGHT,c[0].right.stick.y); - // 1-5 CPU reset + motorSetN(INTAKE_2,(c[0].left.back.u | c[1].left.back.u) ? 127 : (c[0].left.back.d | c[1].left.back.d) ? -127 : 0); + motorSetN(INTAKE_1,invert ? -motorGet(INTAKE_2) : motorGet(INTAKE_2)); - if(zJoyDigital(1,5,JOY_UP) && zJoyDigital(1,5,JOY_DOWN)) - softwareReset(); + motorSetN(LIFT_1,c[1].right.back.u ? 127 : c[1].right.back.d ? -127 : 0); + motorSetN(LIFT_2,motorGet(LIFT_1)); - // 1-7L Speaker function + motorSetN(LIFT_ROTATER,-c[1].right.stick.x / 4); - /*if(zJoyDigital(1,7,JOY_LEFT)){ - speakerInit(); - switch(cyc){ - case 0:speakerPlayRtttl(song );break; - case 1:speakerPlayRtttl(xpst );break; - case 2:speakerPlayRtttl(xpst2);break; - case 3:speakerPlayRtttl(bound);break; - } - if(++cyc == 4) cyc = 0; - speakerShutdown(); - - // 2-8R Gyroscope reset + delay(20); + } +} - }else if(zJoyDigital(2,8,JOY_RIGHT)){ - zGyroReset(); - zMotorIMEReset("Rotater"); +static unsigned int ballPos = 0; - // 2-8U Auto-Aim start +void taskLiftCode(void *unused){ + Button *kill = (Button *)unused; - }else if(zJoyDigital(2,8,JOY_UP)) - taskAim = taskCreate(aimProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT); + motorTake(INTAKE_1,1); + motorTake(INTAKE_2,1); - // 2-8D Auto-Aim kill + do{ + if(!underSensor(intakeLiftTop,LIGHT_THRESH_DEFAULT)){ + if(cangle < 20 && cangle > -20){ + motorTake(LIFT_1,1); + motorTake(LIFT_2,1); + motorSetK(LIFT_1,127,1); + motorSetK(LIFT_2,127,1); + }else{ + motorSetK(LIFT_1,0,1); + motorSetK(LIFT_2,0,1); + motorFree(LIFT_1); + motorFree(LIFT_2); + + if(!underSensor(intakeFrontLeft,LIGHT_THRESH_DEFAULT) && + !underSensor(intakeFrontRight,LIGHT_THRESH_DEFAULT) ){ + motorSetK(INTAKE_1,127,1); + motorSetK(INTAKE_2,127,1); + }else{ + motorSetK(INTAKE_1,0,1); + motorSetK(INTAKE_2,0,1); + } + } + }else{ + motorSetK(INTAKE_1,0,1); + motorSetK(INTAKE_2,0,1); + motorSetN(LIFT_1,0); + motorSetN(LIFT_2,0); + } + }while(!keyDown(*kill)); - else if(zJoyDigital(2,8,JOY_DOWN)) - aimProcRun = false;*/ + motorFree(INTAKE_1); + motorFree(INTAKE_2); - // 2-7U Increase cannon (speed/target RPM) + while(keyDown(*kill)) + delay(100); - if(zJoyDigital(1,7,JOY_UP)){ - if(cannonProcRun) arpm += 50; - else if(cann < 120)cann += 10; + taskLift = NULL; +} - // 2-7D Decrease cannon +void taskAimCode(void *unused){ + Button *kill = (Button *)unused; - }else if(zJoyDigital(1,7,JOY_DOWN)){ - if(cannonProcRun) arpm -= 50; - else if(cann > -120)cann -= 10; + static double target = 0; - // 2-7L Toggle RPM Tracking task. + motorTake(LIFT_ROTATER,4); - }else if(zJoyDigital(1,7,JOY_LEFT)){ - if(!cannonProcRun) - taskCannon = taskCreate(cannonProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT); - else - cannonProcRun = false; - } + target = cangle; - // 2-7R Start Ball Pusher task. + do{ - if(zJoyDigital(1,7,JOY_RIGHT)) - taskArm = taskCreate(armProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT); + if(cangle > target){ + motorSetK(LIFT_ROTATER,30,4); + }else if(cangle < target){ + motorSetK(LIFT_ROTATER,-30,4); + }else{ + motorSetK(LIFT_ROTATER,0,4); } - delay(10); // Short delay to allow task switching - } -} - -/** - * The Position-Tracker process. - * - * This process tries to track the position of the robot, using a combination - * of motor encoders and the gyroscope. This process is created directly, and - * is expected to run at a higher priority than other tasks. - */ - -void moveProc(void *unused_param){ + delay(100); + }while(!keyDown(*kill)); - /** - * 'l' and 'r' contain IMEGet() values, 'lv' and 'rv' contain - * IMEGetVelocity() values. - */ + motorFree(LIFT_ROTATER); - static double l,r,lv,rv; + while(keyDown(*kill)) + delay(100); - /** - * 'dist' might contain the total distance traveled in the past 10 - * milliseconds. - * 'head' contains the angle the robot is facing at relative to its origin. - * 'dpos' is the delta position.? - */ + taskAim = NULL; +} - static double dist,head; +void taskPosCode(void *unused){ + static unsigned int dlime,drime; + static double /*l,r,*/lv,rv; + static double /*dist,*/head; static double dpos; + dlime = getIMEPort(DRIVE_LEFT); + drime = getIMEPort(DRIVE_RIGHT); + while(1){ + cangle = (int)floor(getIME(getIMEPort(LIFT_ROTATER)) / 627.2L * 112.5); + cangle += 0.28L * (cangle / 25); + /** - * Get IMEGet values. + * Get IME values. */ - l = zMotorIMEGet("Left drive") / 627.2L; - r = -zMotorIMEGet("Right drive") / 627.2L; + //l = getIME(dlime) / 627.2L; + //r = getIME(drime) / 627.2L; /** - * Get IMEGetVelocity values and convert to inches per millisecond: + * Get IME velocity values and convert to inches per millisecond: * * random # -> * motor RPM -> @@ -322,21 +236,22 @@ void moveProc(void *unused_param){ * inches per millisecond */ - lv = zMotorIMEGetVelocity("Left drive") / 39.2L * 12.566L / 60000; - rv = -zMotorIMEGetVelocity("Right drive") / 39.2L * 12.566L / 60000; + lv = getIMEVelocity(dlime) / 39.2L * 12.566L / 60000; + rv = -getIMEVelocity(drime) / 39.2L * 12.566L / 60000; /** * Get the distance thing. */ - dist = (l - r) * 8.64L; + //dist = (l - r) * 8.64L; /** * Calculate heading, then trash the result in favor of the gyroscope. */ - head = fmod(dist / 15,360.0L) / 2 * 90; - head = /*(head +*/ zGyroGet()/*) / 2*/; + //head = fmod(dist / 15,360.0L) / 2 * 90; + //head = 0;//getSensor(robotGyro); + head = gyroGet(gyro); /** * Calculate the delta position thing. @@ -355,149 +270,47 @@ void moveProc(void *unused_param){ } } -/** - * The Auto-Aim process. - * - * This function will attempt to keep the cannon aimed at a constant angle, - * adjusting its position when the robot's orientation changes by using the - * gyroscope and the encoder build into the rotater motor. - */ - -void aimProc(void *procPtr){ - - static double cangle, // Current angle (of rotater) - rangle; // 'Robot' angle (target angle - - // Tell others we're running. - - aimProcRun = true; +void taskCanCode(void *unused){ + Button *kill = (Button *)unused; - /** - * Claim necessary motors to prevent others from using them. - */ - - zMotorTake("Rotater",1); - - /** - * Run until a stop is requested. - */ - - while(aimProcRun){ - - /** - * Read orientation sensors. - */ - - cangle = (int)floor(zMotorIMEGet("Rotater") / 627.2L * 112.5); - rangle = zGyroGet() + (atan(ypos / (GOAL_DISTANCE - xpos)) * 180 / PI); - - lcdPrint(uart1,1,"%.3lf, %.3lf",cangle,rangle); - - /** - * Adjust aim if necessary. - */ - - if(cangle > rangle + 3) - zMotorSet("Rotater",30,1); - else if(cangle < rangle - 3) - zMotorSet("Rotater",-30,1); - else - zMotorSet("Rotater",0,1); - - delay(100); - } - - /** - * Free motors. - */ - - zMotorReturn("Rotater"); -} - -/** - * The RPM-Targeter process. - * - * This will attempt to keep the cannon motors running at a constant speed, - * determined through a target RPM set by the user. - */ - -void cannonProc(void *procPtr){ + static unsigned int clime,crime; static double cl,cr,ca; - static int speed;//,ispeed = 0; - - cannonProcRun = true; + static int speed; - /* - * Initialize variables. - * These need to be static so that their values are preserved through - * task switchs but will retain their values when the function is - * re-called, so here we reset them. - */ + clime = getIMEPort(CANNON_LEFT); + crime = getIMEPort(CANNON_RIGHT); speed = 20; rpm = cl = cr = ca = 0; - /* - * Reserve needed motors. - */ - - zMotorTake("Left cannon",2); - zMotorTake("Right cannon",2); - - /* - * Here we increase the power provided to the motors until our target - * RPM is reached. - */ + motorTake(CANNON_LEFT,2); + motorTake(CANNON_RIGHT,2); do{ - /* - * Bring up the speed ... - * The only reasonable explanation for an error such as the speed - * getting too high is a hardware fault in the robot (bad motor, - * bad IME, ...). - */ - speed += 10; if(speed > 120) speed = 127; - /* - * Set the power levels, and allow the motors to adjust. - */ - - zMotorSet("Left cannon" ,-speed,2); - zMotorSet("Right cannon", speed,2); + motorSetK(CANNON_LEFT,-speed,2); + motorSetK(CANNON_RIGHT,speed,2); delay(300); - /* - * Calculate the average RPM, and continue if our target is met. - */ - - cl = zMotorIMEGetVelocity("Left cannon") / 16.3333125L * 9; - cr = -zMotorIMEGetVelocity("Right cannon") / 16.3333125L * 9; + cl = getIMEVelocity(clime) / 16.3333125L * 9; + cr = -getIMEVelocity(crime) / 16.3333125L * 9; rpm = ca = cr;//(cl + cr) / 2; - }while(cannonProcRun && ca < trpm); - - if(!cannonProcRun) - return; + }while(ca < trpm); - /* - * Once we reach our target, we 'idle' at the sped and adjust as - * necessary. `cannInUse` will be cleared by any user attempt to use the - * motor. - */ - - while(cannonProcRun){ + while(!keyDown(*kill)){ /* * Update RPM values. */ - cl = zMotorIMEGetVelocity("Left cannon") / 16.3333125L * 9; - cr = -zMotorIMEGetVelocity("Right cannon") / 16.3333125L * 9; + cl = getIMEVelocity(clime) / 16.3333125L * 9; + cr = -getIMEVelocity(crime) / 16.3333125L * 9; rpm = ca = cr;//(cl + cr) / 2; /* @@ -522,152 +335,201 @@ void cannonProc(void *procPtr){ */ if(ca < trpm - 40){ - speed += 2; - zMotorSet("Left cannon" ,-speed,2); - zMotorSet("Right cannon", speed,2); + speed += 2 * ((trpm - rpm) / 60); + motorSetK(CANNON_LEFT,-speed,2); + motorSetK(CANNON_RIGHT,speed,2); cannReady = false; }else if(ca > trpm + 40){ - speed -= 2; - //if(speed < ispeed) speed = ispeed; - zMotorSet("Left cannon" ,-speed,2); - zMotorSet("Right cannon", speed,2); + speed --; + motorSetK(CANNON_LEFT,-speed,2); + motorSetK(CANNON_RIGHT,speed,2); cannReady = false; - }else{ + }else cannReady = true; - //ispeed = speed; - } - - lcdPrint(uart1,2,"%.0lf|%.3lf\n",trpm,rpm); - //printf("%.0lf,%.3lf,%d\n",trpm,rpm,speed); delay(100); } - zMotorSet("Right cannon",0,2); + motorSetK(CANNON_LEFT,0,2); + motorSetK(CANNON_RIGHT,0,2); + + motorFree(CANNON_LEFT); + motorFree(CANNON_RIGHT); + + while(keyDown(*kill)) + delay(100); - zMotorReturn("Left cannon"); - zMotorReturn("Right cannon"); + taskCan = NULL; } -/** - * The Ball-Pusher process. - * - * This process will handle the pusher that actually sends the ball into the - * cannon through either an instant push or a detected one, in which the lift - * is ran until a ball is seen via a light sensor. - */ +void taskArmCode(void *unused){ + if(keyDown(c[1].left.front.r)) + goto PUSH; -void armProc(void *procPtr){ - static unsigned int start; + while(!underSensor(intakeLiftTop,LIGHT_THRESH_DEFAULT) && ((rpm < trpm - 30) | (rpm > trpm + 50))) + delay(100); - armProcRun = true; + /*while(ballPos != 5) + delay(100);*/ - /* - * Claim necessary motors. - */ +PUSH: - zMotorTake("Lift 1",3); - zMotorTake("Lift 2",3); - zMotorTake("Misc",3); + motorTake(LIFT_PUSHER,3); - /* - * Collect the time we started this operation, but negate it so we can add - * the finish millis() call to collect a difference in milliseconds. - */ + motorSetK(LIFT_PUSHER,127,3); + delay(500); + motorSetK(LIFT_PUSHER,-127,3); + delay(800); + motorSetK(LIFT_PUSHER,0,3); - start = -millis(); + motorFree(LIFT_PUSHER); - /* - * Just run the pusher if it was requested by the user. - */ + taskArm = NULL; +} - if(zJoyDigital(1,8,JOY_DOWN)) - goto PUSH; - /* - * Run the lift and wait until a ball is detected by the light sensor. Once - * a ball is seen, stop the lift so that the pusher can do its job. - */ +void taskLCDCode(void *unused){ + static unsigned int pos = 1; + unsigned int lcdInput; + static double cangle = 0; - zMotorSet("Lift 1",127,3); - zMotorSet("Lift 2",127,3); + while(1){ - while(armProcRun && analogRead(8) > lightThresh) - delay(10); + switch(pos){ + case 0: + lcdPrint(LCD_PORT,1,"(%.2lf,%.2lf)",xpos,ypos); + lcdPrint(LCD_PORT,2,"%s: %u",taskGetState(taskLift) == TASK_RUNNING ? "Running" : "Stopped",ballPos); + break; + case 1: + lcdPrint(LCD_PORT,1,"%.0lf | %.2lf\n",trpm,rpm); + lcdPrint(LCD_PORT,2," "); + break; + case 2: + lcdPrint(LCD_PORT,1,"%u %u %u %u", + taskGetState(taskPos), + taskGetState(taskCan), + taskGetState(taskArm), + taskGetState(taskLift)); + break; + case 3: + lcdPrint(LCD_PORT,1,"%lf",cangle); + lcdPrint(LCD_PORT,2," "); + break; + } - if(!armProcRun) - return; + lcdInput = lcdReadButtons(LCD_PORT); - delay(300); + if((lcdInput & LCD_BTN_LEFT) && pos) + pos--; + else if((lcdInput & LCD_BTN_RIGHT) && pos < 3) + pos++; + else if(lcdInput & LCD_BTN_CENTER) + softwareReset(); - zMotorSet("Lift 1",0,3); - zMotorSet("Lift 2",0,3); + delay(500); + } +} - /* - * Push a ball into the cannon. - */ -PUSH: +#ifdef AUTO_SKILLS - zMotorSet("Misc",127,3); - delay(500); - zMotorSet("Misc",-127,3); - delay(500); - zMotorSet("Misc",0,3); +/***************************************************************************** + * AUTONOMOUS - SKILLS * + *****************************************************************************/ - /* - * 'Stop' the timer and print the result. Do this on the first line in case - * the RPM tracker or another process is using the second. - */ +void autonomous(){ + static unsigned long inc = 0; - start += millis(); - lcdPrint(uart1,1,"%ums",start); + EXTRA_TRPM; + intakeLiftTop.initial = readSensor(&intakeLiftTop); - /* - * Release the used motors. - */ + taskInit(taskPos,&No); + taskInit(taskAim,&No); + taskInit(taskCan,&No); - zMotorReturn("Lift 1"); - zMotorReturn("Lift 2"); - zMotorReturn("Misc"); + while(1){ - armProcRun = false; -} + if(++inc == 50){ + inc = 0; + lcdPrint(LCD_PORT,1,"%.0lf RPM",rpm); + } -/** - * The LCD update function, registered at init time to be called by libZephyr's - * LCD code. - */ + //readSensor(&intakeLiftTop); + //if(rpm >= trpm){// && underSensor(intakeLiftTop,LIGHT_THRESH_DEFAULT)){ + if(rpm > trpm - 30 && rpm < trpm + 50){ -void lcdUpdateFunc(void *unused_param){ - while(1){ - /* - * Track elapsed time since operatorControl() entrance. - */ + lcdPrint(LCD_PORT,2,"Launch!"); - //elapsed = millis() - opmillis; - //lcdPrint(uart1,1,"%02d:%02d",(int)(elapsed / 60000),(int)((elapsed / 1000) % 60)); - //lcdPrint(uart1,1,"%.3lf V",(float)analogRead(1)/70/4); + delay(500); + + motorSet(LIFT_PUSHER,127); + delay(500); + motorSet(LIFT_PUSHER,-127); + delay(800); + motorSet(LIFT_PUSHER,0); - //lcdPrint(uart1,2,"%4.0lf/%4.0lf",trpm,rpm); - delay(LCD_RATE); + lcdPrint(LCD_PORT,2," "); + } + + delay(10); } } +#else + +/***************************************************************************** + * AUTONOMOUS - NORMAL * + *****************************************************************************/ + void autonomous(){ - static unsigned long elapsed = 0; - opmillis = millis(); - taskCannon = taskCreate(cannonProc,TASK_DEFAULT_STACK_SIZE,NULL,TASK_PRIORITY_DEFAULT); + static unsigned long start,elapsed = 0; + static unsigned long inc = 0; + + EXTRA_TRPM; + start = millis(); + intakeLiftTop.initial = readSensor(&intakeLiftTop); + + taskInit(taskCan,&No); + + motorSet(LIFT_1,127); + motorSet(LIFT_2,127); + //motorSet(INTAKE_1,127); + //motorSet(INTAKE_2,127); + while(1){ - elapsed = millis() - opmillis; - lcdPrint(uart1,1,"%02d:%02d",(int)(elapsed / 60000),(int)((elapsed / 1000) % 60)); + elapsed = millis() - start; - if(cannReady){ - zMotorSet("Misc",127,0); - delay(500); - zMotorSet("Misc",-127,0); - delay(500); - zMotorSet("Misc",0,0); + if(++inc == 50){ + inc = 0; + lcdPrint(LCD_PORT,1,"%02d:%02d",(int)(elapsed / 60000),(int)((elapsed / 1000) % 60)); + lcdPrint(LCD_PORT,2,"%.0lf RPM",rpm); + } + + readSensor(&intakeLiftTop); + if(underSensor(intakeLiftTop,LIGHT_THRESH_DEFAULT)){ + + + delay(200); + motorSet(LIFT_1,0); + motorSet(LIFT_2,0); + //motorSet(INTAKE_1,0); + //motorSet(INTAKE_2,0); + + if(rpm >= trpm){ + motorSet(LIFT_PUSHER,127); + delay(500); + motorSet(LIFT_PUSHER,-127); + delay(500); + motorSet(LIFT_PUSHER,0); + + motorSet(LIFT_1,127); + motorSet(LIFT_2,127); + //motorSet(INTAKE_1,127); + //motorSet(INTAKE_2,127); + } } + delay(10); } } + +#endif // AUTO_SKILLS diff --git a/src/reset.c b/src/reset.c new file mode 100644 index 0000000..60b5b2b --- /dev/null +++ b/src/reset.c @@ -0,0 +1,52 @@ +#include + +/** + * Cause the Cortex to reset, which results in the Cortex restarting the + * operator control code. + * + * This reset is accomplished through setting two bits, SYSRESETREQ and + * VECTRESET, in the Application Interrupt and Reset Control Register (AIRCR), + * which is at a known location in memory. SYSRESETREQ will actually request + * the system reset, while VECTRESET is 'reserved for debugging'. This second + * bit may not need to be set; it's only set here because others have found it + * necessary. + */ + +#define AIRCR_ADDR 0xE000ED0C +#define VECTKEY 0x05FA +#define SYSRESETREQ (1<<2) +#define VECTRESET (1<<0) + +void softwareReset(void){ + + /* + * Read the current value of the AIRCR, since some flags currently set in + * the register need to remain the same in order for the reset to work. + */ + + uint32_t AIRCR = *((uint32_t *)AIRCR_ADDR); + + /* + * Here we save the lower 16 bits of the register, write a special key to + * the higher 16 bits that'll allow the write to occur, and then set the + * reset flags. + */ + + AIRCR = (AIRCR & 0xFFFF) | (VECTKEY << 16) | SYSRESETREQ | VECTRESET; + + // Update the AIRCR. + + *((uint32_t *)0xE000ED0C) = AIRCR; + + /* + * This instruction causes the program to wait until the previous memory + * write is complete, ensuring it is taken into effect and the reset + * request is made. + */ + + asm("DSB"); + + // Wait until the system reset completes. + + while(1); +} diff --git a/src/sensor.c b/src/sensor.c new file mode 100644 index 0000000..2725642 --- /dev/null +++ b/src/sensor.c @@ -0,0 +1,88 @@ +#include + +/** + * Nowhere else to put this...? + */ + +unsigned char MOTOR_USE_MAP[10] = { + 0,0,0,0,0,0,0,0,0,0 +}; + +int getIMEPort(unsigned int port){ + switch(port){ + case CANNON_LEFT : return CANNON_LEFT_IME; + case CANNON_RIGHT : return CANNON_RIGHT_IME; + case LIFT_PUSHER : + case INTAKE_1 : + case INTAKE_2 : return -1; + case DRIVE_RIGHT : return DRIVE_RIGHT_IME; + case DRIVE_LEFT : return DRIVE_LEFT_IME; + case LIFT_1 : return LIFT_1_IME; + case LIFT_2 : return LIFT_2_IME; + case LIFT_ROTATER : return LIFT_ROTATER_IME; + } + return -1; +} + +int getIME(unsigned int port){ + int ret; + imeGet(port,&ret); + return ret; +} + +int getIMEVelocity(unsigned int port){ + int ret; + imeGetVelocity(port,&ret); + return ret; +} + +/** + * Actual sensor stuffs + */ + +Sensor initSensor(uint32_t port,unsigned char type){ + Sensor s; + s.type = type; + switch(s.type){ + case DIGITAL: + pinMode(port,INPUT); + s.port = port; + //s.initial = digitalRead(port); + break; + case ANALOG: + pinMode(port + 13,INPUT_ANALOG); + s.port = port; + //s.initial = analogRead(port); + break; + case GYRO: + s.port = 0; + s.data.gyro = gyroInit(port,0); + //s.initial = gyroGet(s.data.gyro); + break; + case ULTRASONIC: + s.port = 0; + s.data.sonic = ultrasonicInit((uint16_t)port,port>>16); + //s.initial = ultrasonicGet(s.data.sonic); + break; + } + s.value = 0; + return s; +} + +int readSensor(Sensor *s){ + switch(s->type){ + case DIGITAL: + return (s->value = digitalRead(s->port)); + break; + case ANALOG: + return (s->value = analogRead(s->port)); + break; + case GYRO: + return (s->value = gyroGet(s->data.gyro)); + break; + case ULTRASONIC: + return (s->value = ultrasonicGet(s->data.sonic)); + break; + } + return (s->value = -1); +} diff --git a/src/zephyr.c b/src/zephyr.c deleted file mode 100644 index 6767dd8..0000000 --- a/src/zephyr.c +++ /dev/null @@ -1,184 +0,0 @@ -#include -#include - -#include - -#ifdef LCD_PORT -#endif // LCD_PORT - -#ifdef GYRO_PORT - -static Gyro gyro; -static bool gyroEnabled = false; - -void zGyroInit(void){ - if((gyro=gyroInit(2,0))){ - gyroEnabled = true; - } -} - -int zGyroGet(void){ - return gyroGet(gyro); -} - -void zGyroReset(void){ - gyroReset(gyro); -} - -#endif // GYRO_PORT - -/* - * A map of what's plugged into the motor ports. - * Expected declarations: - * - * DRIVEL - Left drive port - * DRIVER - Right drive port - * -*/ - -#define MOTOR_PORT_COUNT 10 - -#ifdef IME_ENABLE -#define MOTOR_IME_COUNT 7 -#endif // IME_ENABLE - -const char *MOTOR_PORT_MAP[MOTOR_PORT_COUNT] = { - "Left cannon", - "Right cannon", - "Misc", - "Intake", - "Intake", - "Right drive", - "Left drive", - "Lift 1", - "Lift 2", - "Rotater" -}; - -static unsigned int mInUse[10]={ - 0,0,0,0,0,0,0,0,0,0 -}; - -#ifdef IME_ENABLE - -const char *MOTOR_IME_MAP[MOTOR_IME_COUNT] = { - "Right drive", - "Left drive", - "Rotater", - "Lift 1", - "Lift 2", - "Left cannon", - "Right cannon" -}; - -static unsigned int imeCount = 0; - -void zIMEInit(void){ - imeCount = imeInitializeAll(); -} - -#endif // IME_ENABLE - -void zMotorSet(const char *motor,int speed,unsigned int id){ - for(unsigned char i=0;i 127)speed = 127; - if(speed < -127)speed = -127; - motorSet(i+1,speed); - //return; - } - } -} - -char zMotorGet(const char *motor){ - for(unsigned char i=0;i