diff --git a/.gitignore b/.gitignore index 259148f..a6cf755 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ *.exe *.out *.app + +Debug/* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c990bf6 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ + +CC := g++ +INC := -I include -I include/wiringPi -I /usr/local/include +CFLAGS := -c --std=c++11 -Wall $(shell pkg-config --cflags --libs libmongocxx) +LIB := -L /usr/local/lib -lmongocxx -lbsoncxx + + +SRCDIR := src +SRCEXT := cpp +LIBDIR := lib +BUILDDIR := build +TARGETDIR := bin +TARGET := bin/POCpp + +SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT)) +OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o)) + +# Main target +$(TARGET): $(OBJECTS) + @mkdir -p $(TARGETDIR) + @echo " Linking..." + @echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB) + +$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT) + @mkdir -p $(BUILDDIR) + @echo " Bulding..." + @echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<"; $(CC) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + @echo " Cleaning..."; + @echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET) diff --git a/POCpp.xcodeproj/project.pbxproj b/POCpp.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bf58171 --- /dev/null +++ b/POCpp.xcodeproj/project.pbxproj @@ -0,0 +1,373 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + C568AED71F13E97F00524D66 /* libbson-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C568AED11F13E97F00524D66 /* libbson-1.0.0.dylib */; }; + C568AED81F13E97F00524D66 /* libbsoncxx.3.1.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C568AED21F13E97F00524D66 /* libbsoncxx.3.1.1.dylib */; }; + C568AED91F13E97F00524D66 /* libbsoncxx.3.1.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C568AED31F13E97F00524D66 /* libbsoncxx.3.1.1.dylib */; }; + C568AEDA1F13E97F00524D66 /* libmongoc-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C568AED41F13E97F00524D66 /* libmongoc-1.0.0.dylib */; }; + C568AEDB1F13E97F00524D66 /* libmongocxx.3.1.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C568AED51F13E97F00524D66 /* libmongocxx.3.1.1.dylib */; }; + C568AEDC1F13E97F00524D66 /* libmongocxx.3.1.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C568AED61F13E97F00524D66 /* libmongocxx.3.1.1.dylib */; }; + C568AEF61F13EA5000524D66 /* AnalogIn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEDE1F13EA5000524D66 /* AnalogIn.cpp */; }; + C568AEF71F13EA5000524D66 /* Card.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEE01F13EA5000524D66 /* Card.cpp */; }; + C568AEF81F13EA5000524D66 /* Database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEE21F13EA5000524D66 /* Database.cpp */; }; + C568AEF91F13EA5000524D66 /* DigitalIn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEE41F13EA5000524D66 /* DigitalIn.cpp */; }; + C568AEFA1F13EA5000524D66 /* DigitalOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEE61F13EA5000524D66 /* DigitalOut.cpp */; }; + C568AEFB1F13EA5000524D66 /* FluidShot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEE81F13EA5000524D66 /* FluidShot.cpp */; }; + C568AEFC1F13EA5000524D66 /* LPPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEEA1F13EA5000524D66 /* LPPair.cpp */; }; + C568AEFD1F13EA5000524D66 /* LPStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEEC1F13EA5000524D66 /* LPStatus.cpp */; }; + C568AEFE1F13EA5000524D66 /* Measurement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEEE1F13EA5000524D66 /* Measurement.cpp */; }; + C568AEFF1F13EA5000524D66 /* MuxSetup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEF01F13EA5000524D66 /* MuxSetup.cpp */; }; + C568AF001F13EA5000524D66 /* Well.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEF21F13EA5000524D66 /* Well.cpp */; }; + C568AF011F13EA5000524D66 /* WellTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C568AEF41F13EA5000524D66 /* WellTest.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + C568AEBE1F13D1F800524D66 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + C568AEC01F13D1F800524D66 /* POCpp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = POCpp; sourceTree = BUILT_PRODUCTS_DIR; }; + C568AECA1F13D25200524D66 /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; path = src; sourceTree = ""; }; + C568AECB1F13D28500524D66 /* bin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = bin; sourceTree = ""; }; + C568AECC1F13D28500524D66 /* build */ = {isa = PBXFileReference; lastKnownFileType = folder; path = build; sourceTree = ""; }; + C568AECD1F13D28500524D66 /* include */ = {isa = PBXFileReference; lastKnownFileType = folder; path = include; sourceTree = ""; }; + C568AECE1F13D28500524D66 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + C568AED11F13E97F00524D66 /* libbson-1.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libbson-1.0.0.dylib"; path = "../../../../../usr/local/lib/libbson-1.0.0.dylib"; sourceTree = ""; }; + C568AED21F13E97F00524D66 /* libbsoncxx.3.1.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsoncxx.3.1.1.dylib; path = ../../../../../usr/local/lib/libbsoncxx.3.1.1.dylib; sourceTree = ""; }; + C568AED31F13E97F00524D66 /* libbsoncxx.3.1.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsoncxx.3.1.1.dylib; path = ../../../../../usr/local/lib/libbsoncxx.3.1.1.dylib; sourceTree = ""; }; + C568AED41F13E97F00524D66 /* libmongoc-1.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libmongoc-1.0.0.dylib"; path = "../../../../../usr/local/lib/libmongoc-1.0.0.dylib"; sourceTree = ""; }; + C568AED51F13E97F00524D66 /* libmongocxx.3.1.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmongocxx.3.1.1.dylib; path = ../../../../../usr/local/lib/libmongocxx.3.1.1.dylib; sourceTree = ""; }; + C568AED61F13E97F00524D66 /* libmongocxx.3.1.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmongocxx.3.1.1.dylib; path = ../../../../../usr/local/lib/libmongocxx.3.1.1.dylib; sourceTree = ""; }; + C568AEDE1F13EA5000524D66 /* AnalogIn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalogIn.cpp; path = src/AnalogIn.cpp; sourceTree = ""; }; + C568AEDF1F13EA5000524D66 /* AnalogIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalogIn.h; path = src/AnalogIn.h; sourceTree = ""; }; + C568AEE01F13EA5000524D66 /* Card.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Card.cpp; path = src/Card.cpp; sourceTree = ""; }; + C568AEE11F13EA5000524D66 /* Card.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Card.h; path = src/Card.h; sourceTree = ""; }; + C568AEE21F13EA5000524D66 /* Database.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Database.cpp; path = src/Database.cpp; sourceTree = ""; }; + C568AEE31F13EA5000524D66 /* Database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Database.h; path = src/Database.h; sourceTree = ""; }; + C568AEE41F13EA5000524D66 /* DigitalIn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DigitalIn.cpp; path = src/DigitalIn.cpp; sourceTree = ""; }; + C568AEE51F13EA5000524D66 /* DigitalIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DigitalIn.h; path = src/DigitalIn.h; sourceTree = ""; }; + C568AEE61F13EA5000524D66 /* DigitalOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DigitalOut.cpp; path = src/DigitalOut.cpp; sourceTree = ""; }; + C568AEE71F13EA5000524D66 /* DigitalOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DigitalOut.h; path = src/DigitalOut.h; sourceTree = ""; }; + C568AEE81F13EA5000524D66 /* FluidShot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FluidShot.cpp; path = src/FluidShot.cpp; sourceTree = ""; }; + C568AEE91F13EA5000524D66 /* FluidShot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FluidShot.h; path = src/FluidShot.h; sourceTree = ""; }; + C568AEEA1F13EA5000524D66 /* LPPair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LPPair.cpp; path = src/LPPair.cpp; sourceTree = ""; }; + C568AEEB1F13EA5000524D66 /* LPPair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LPPair.h; path = src/LPPair.h; sourceTree = ""; }; + C568AEEC1F13EA5000524D66 /* LPStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LPStatus.cpp; path = src/LPStatus.cpp; sourceTree = ""; }; + C568AEED1F13EA5000524D66 /* LPStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LPStatus.h; path = src/LPStatus.h; sourceTree = ""; }; + C568AEEE1F13EA5000524D66 /* Measurement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Measurement.cpp; path = src/Measurement.cpp; sourceTree = ""; }; + C568AEEF1F13EA5000524D66 /* Measurement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Measurement.h; path = src/Measurement.h; sourceTree = ""; }; + C568AEF01F13EA5000524D66 /* MuxSetup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MuxSetup.cpp; path = src/MuxSetup.cpp; sourceTree = ""; }; + C568AEF11F13EA5000524D66 /* MuxSetup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MuxSetup.h; path = src/MuxSetup.h; sourceTree = ""; }; + C568AEF21F13EA5000524D66 /* Well.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Well.cpp; path = src/Well.cpp; sourceTree = ""; }; + C568AEF31F13EA5000524D66 /* Well.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Well.h; path = src/Well.h; sourceTree = ""; }; + C568AEF41F13EA5000524D66 /* WellTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WellTest.cpp; path = src/WellTest.cpp; sourceTree = ""; }; + C568AEF51F13EA5000524D66 /* WellTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WellTest.h; path = src/WellTest.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + C568AEBD1F13D1F800524D66 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C568AED71F13E97F00524D66 /* libbson-1.0.0.dylib in Frameworks */, + C568AED81F13E97F00524D66 /* libbsoncxx.3.1.1.dylib in Frameworks */, + C568AED91F13E97F00524D66 /* libbsoncxx.3.1.1.dylib in Frameworks */, + C568AEDA1F13E97F00524D66 /* libmongoc-1.0.0.dylib in Frameworks */, + C568AEDB1F13E97F00524D66 /* libmongocxx.3.1.1.dylib in Frameworks */, + C568AEDC1F13E97F00524D66 /* libmongocxx.3.1.1.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + C568AEB71F13D1F800524D66 = { + isa = PBXGroup; + children = ( + C568AECB1F13D28500524D66 /* bin */, + C568AECC1F13D28500524D66 /* build */, + C568AECD1F13D28500524D66 /* include */, + C568AECE1F13D28500524D66 /* Makefile */, + C568AEDD1F13EA2B00524D66 /* src */, + C568AEC11F13D1F800524D66 /* Products */, + C568AED01F13E97F00524D66 /* Frameworks */, + ); + sourceTree = ""; + }; + C568AEC11F13D1F800524D66 /* Products */ = { + isa = PBXGroup; + children = ( + C568AEC01F13D1F800524D66 /* POCpp */, + ); + name = Products; + sourceTree = ""; + }; + C568AED01F13E97F00524D66 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C568AED11F13E97F00524D66 /* libbson-1.0.0.dylib */, + C568AED21F13E97F00524D66 /* libbsoncxx.3.1.1.dylib */, + C568AED31F13E97F00524D66 /* libbsoncxx.3.1.1.dylib */, + C568AED41F13E97F00524D66 /* libmongoc-1.0.0.dylib */, + C568AED51F13E97F00524D66 /* libmongocxx.3.1.1.dylib */, + C568AED61F13E97F00524D66 /* libmongocxx.3.1.1.dylib */, + ); + name = Frameworks; + sourceTree = ""; + }; + C568AEDD1F13EA2B00524D66 /* src */ = { + isa = PBXGroup; + children = ( + C568AEDE1F13EA5000524D66 /* AnalogIn.cpp */, + C568AEDF1F13EA5000524D66 /* AnalogIn.h */, + C568AEE01F13EA5000524D66 /* Card.cpp */, + C568AEE11F13EA5000524D66 /* Card.h */, + C568AEE21F13EA5000524D66 /* Database.cpp */, + C568AEE31F13EA5000524D66 /* Database.h */, + C568AEE41F13EA5000524D66 /* DigitalIn.cpp */, + C568AEE51F13EA5000524D66 /* DigitalIn.h */, + C568AEE61F13EA5000524D66 /* DigitalOut.cpp */, + C568AEE71F13EA5000524D66 /* DigitalOut.h */, + C568AEE81F13EA5000524D66 /* FluidShot.cpp */, + C568AEE91F13EA5000524D66 /* FluidShot.h */, + C568AEEA1F13EA5000524D66 /* LPPair.cpp */, + C568AEEB1F13EA5000524D66 /* LPPair.h */, + C568AEEC1F13EA5000524D66 /* LPStatus.cpp */, + C568AEED1F13EA5000524D66 /* LPStatus.h */, + C568AEEE1F13EA5000524D66 /* Measurement.cpp */, + C568AEEF1F13EA5000524D66 /* Measurement.h */, + C568AEF01F13EA5000524D66 /* MuxSetup.cpp */, + C568AEF11F13EA5000524D66 /* MuxSetup.h */, + C568AEF21F13EA5000524D66 /* Well.cpp */, + C568AEF31F13EA5000524D66 /* Well.h */, + C568AEF41F13EA5000524D66 /* WellTest.cpp */, + C568AEF51F13EA5000524D66 /* WellTest.h */, + C568AECA1F13D25200524D66 /* src */, + ); + name = src; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + C568AEBF1F13D1F800524D66 /* POCpp */ = { + isa = PBXNativeTarget; + buildConfigurationList = C568AEC71F13D1F800524D66 /* Build configuration list for PBXNativeTarget "POCpp" */; + buildPhases = ( + C568AEBC1F13D1F800524D66 /* Sources */, + C568AEBD1F13D1F800524D66 /* Frameworks */, + C568AEBE1F13D1F800524D66 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = POCpp; + productName = POCpp; + productReference = C568AEC01F13D1F800524D66 /* POCpp */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + C568AEB81F13D1F800524D66 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Henry Pump"; + TargetAttributes = { + C568AEBF1F13D1F800524D66 = { + CreatedOnToolsVersion = 8.3.3; + DevelopmentTeam = JNP6SX52H9; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = C568AEBB1F13D1F800524D66 /* Build configuration list for PBXProject "POCpp" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = C568AEB71F13D1F800524D66; + productRefGroup = C568AEC11F13D1F800524D66 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + C568AEBF1F13D1F800524D66 /* POCpp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + C568AEBC1F13D1F800524D66 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C568AEF61F13EA5000524D66 /* AnalogIn.cpp in Sources */, + C568AEFE1F13EA5000524D66 /* Measurement.cpp in Sources */, + C568AEFF1F13EA5000524D66 /* MuxSetup.cpp in Sources */, + C568AEF81F13EA5000524D66 /* Database.cpp in Sources */, + C568AEFA1F13EA5000524D66 /* DigitalOut.cpp in Sources */, + C568AEF71F13EA5000524D66 /* Card.cpp in Sources */, + C568AEFB1F13EA5000524D66 /* FluidShot.cpp in Sources */, + C568AEFD1F13EA5000524D66 /* LPStatus.cpp in Sources */, + C568AEFC1F13EA5000524D66 /* LPPair.cpp in Sources */, + C568AF011F13EA5000524D66 /* WellTest.cpp in Sources */, + C568AEF91F13EA5000524D66 /* DigitalIn.cpp in Sources */, + C568AF001F13EA5000524D66 /* Well.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + C568AEC51F13D1F800524D66 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + C568AEC61F13D1F800524D66 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + C568AEC81F13D1F800524D66 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEVELOPMENT_TEAM = JNP6SX52H9; + LIBRARY_SEARCH_PATHS = "/usr/local/lib/**"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "include/** /usr/local/include/libmongoc-1.0/** /usr/local/include/mongocxx/v_noabi/** /usr/local/include/bsoncxx/v_noabi/** /usr/local/include/libbson-1.0/** include/wiringPi ./include/** ./include/mraa/**"; + }; + name = Debug; + }; + C568AEC91F13D1F800524D66 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEVELOPMENT_TEAM = JNP6SX52H9; + LIBRARY_SEARCH_PATHS = "/usr/local/lib/**"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "include/** /usr/local/include/libmongoc-1.0/** /usr/local/include/mongocxx/v_noabi/** /usr/local/include/bsoncxx/v_noabi/** /usr/local/include/libbson-1.0/** include/wiringPi ./include/** ./include/mraa/**"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C568AEBB1F13D1F800524D66 /* Build configuration list for PBXProject "POCpp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C568AEC51F13D1F800524D66 /* Debug */, + C568AEC61F13D1F800524D66 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C568AEC71F13D1F800524D66 /* Build configuration list for PBXNativeTarget "POCpp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C568AEC81F13D1F800524D66 /* Debug */, + C568AEC91F13D1F800524D66 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = C568AEB81F13D1F800524D66 /* Project object */; +} diff --git a/POCpp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/POCpp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7a6dd12 --- /dev/null +++ b/POCpp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate b/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..2d39558 Binary files /dev/null and b/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fe2b454 --- /dev/null +++ b/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcschemes/POCpp.xcscheme b/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcschemes/POCpp.xcscheme new file mode 100644 index 0000000..9d3a266 --- /dev/null +++ b/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcschemes/POCpp.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcschemes/xcschememanagement.plist b/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..69166c4 --- /dev/null +++ b/POCpp.xcodeproj/xcuserdata/patrickjmcd.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + POCpp.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + C568AEBF1F13D1F800524D66 + + primary + + + + + diff --git a/include/mraa.h b/include/mraa.h new file mode 100644 index 0000000..70fde77 --- /dev/null +++ b/include/mraa.h @@ -0,0 +1,40 @@ +/* + * Author: Brendan Le Foll + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa/pwm.h" +#include "mraa/aio.h" +#include "mraa/gpio.h" +#include "mraa/spi.h" +#include "mraa/i2c.h" +#include "mraa/uart.h" +#include "mraa/uart_ow.h" + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa.hpp b/include/mraa.hpp new file mode 100644 index 0000000..41685a5 --- /dev/null +++ b/include/mraa.hpp @@ -0,0 +1,33 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "mraa/common.hpp" +#include "mraa/pwm.hpp" +#include "mraa/aio.hpp" +#include "mraa/gpio.hpp" +#include "mraa/i2c.hpp" +#include "mraa/spi.hpp" +#include "mraa/uart.hpp" diff --git a/include/mraa/aio.h b/include/mraa/aio.h new file mode 100644 index 0000000..23c0857 --- /dev/null +++ b/include/mraa/aio.h @@ -0,0 +1,107 @@ +/* + * Author: Nandkishor Sonar + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once +/** + * @file + * @brief Analog input/output + * + * AIO is the anlog input & output interface to libmraa. It is used to read or + * set the voltage applied to an AIO pin. + * + * @snippet analogin_a0.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include "common.h" +#include "gpio.h" + +/** + * Opaque pointer definition to the internal struct _aio. This context refers + * to one single AIO pin on the board. + */ +typedef struct _aio* mraa_aio_context; + +/** + * Initialise an Analog input device, connected to the specified pin + * + * @param pin Channel number to read ADC inputs + * @returns aio context or NULL + */ +mraa_aio_context mraa_aio_init(unsigned int pin); + +/** + * Read the input voltage. By default mraa will shift the raw value up or down + * to a 10 bit value. + * + * @param dev The AIO context + * @returns The current input voltage or -1 for error + */ +int mraa_aio_read(mraa_aio_context dev); + +/** + * Read the input voltage and return it as a normalized float (0.0f-1.0f). + * + * @param dev The AIO context + * @returns The current input voltage as a normalized float (0.0f-1.0f), error + * will be signaled by -1.0f + */ +float mraa_aio_read_float(mraa_aio_context dev); + +/** + * Close the analog input context, this will free the memory for the context + * + * @param dev The AIO context + * @return Result of operation + */ +mraa_result_t mraa_aio_close(mraa_aio_context dev); + +/** + * Set the bit value which mraa will shift the raw reading + * from the ADC to. I.e. 10bits + * @param dev the analog input context + * @param bits the bits the return from read should be i.e 10 + * + * @return mraa result type + */ +mraa_result_t mraa_aio_set_bit(mraa_aio_context dev, int bits); + +/** + * Gets the bit value mraa is shifting the analog read to. + * @param dev the analog input context + * + * @return bit value mraa is set return from the read function + */ +int mraa_aio_get_bit(mraa_aio_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/aio.hpp b/include/mraa/aio.hpp new file mode 100644 index 0000000..38ea8bc --- /dev/null +++ b/include/mraa/aio.hpp @@ -0,0 +1,133 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include "aio.h" +#include "types.hpp" + +namespace mraa +{ + +/** + * @brief API to Analog IO + * + * This file defines the aio interface for libmraa + * + * @snippet AioA0.cpp Interesting + */ +class Aio +{ + public: + /** + * Aio Constructor, takes a pin number which will map directly to the + * board number + * + * @param pin channel number to read ADC inputs + */ + Aio(int pin) + { + m_aio = mraa_aio_init(pin); + if (m_aio == NULL) { + throw std::invalid_argument("Invalid AIO pin specified - do you have an ADC?"); + } + } + /** + * Aio Constructor, takes a pointer to the AIO context and initialises + * the AIO class + * + * @param void * to an AIO context + */ + Aio(void* aio_context) + { + m_aio = (mraa_aio_context) aio_context; + if (m_aio == NULL) { + throw std::invalid_argument("Invalid AIO context"); + } + } + /** + * Aio destructor + */ + ~Aio() + { + mraa_aio_close(m_aio); + } + /** + * Read a value from the AIO pin. By default mraa will shift + * the raw value up or down to a 10 bit value. + * + * @throws std::invalid_argument in case of error + * @returns The current input voltage. By default, a 10bit value + */ + unsigned int + read() + { + int x = mraa_aio_read(m_aio); + if (x == -1) { + throw std::invalid_argument("Unknown error in Aio::read()"); + } + return (unsigned int) x; + } + /** + * Read a value from the AIO pin and return it as a normalized float. + * + * @throws std::invalid_argument in case of error + * @returns The current input voltage as a normalized float (0.0f-1.0f) + */ + float + readFloat() + { + float x = mraa_aio_read_float(m_aio); + if (x == -1.0f) { + throw std::invalid_argument("Unknown error in Aio::readFloat()"); + } + return x; + } + /** + * Set the bit value which mraa will shift the raw reading + * from the ADC to. I.e. 10bits + * @param bits the bits the return from read should be i.e 10 + * @return mraa::Result type + */ + Result + setBit(int bits) + { + return (Result) mraa_aio_set_bit(m_aio, bits); + } + /** + * Gets the bit value mraa is shifting the analog read to. + * + * @return bit value mraa is set return from the read function + */ + int + getBit() + { + return mraa_aio_get_bit(m_aio); + } + + private: + mraa_aio_context m_aio; +}; +} diff --git a/include/mraa/common.h b/include/mraa/common.h new file mode 100644 index 0000000..c0467ba --- /dev/null +++ b/include/mraa/common.h @@ -0,0 +1,311 @@ +/* + * Author: Brendan Le Foll + * Author: Thomas Ingleby + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#pragma once + +#include +#include "types.h" + +#define MRAA_PLATFORM_NAME_MAX_SIZE 64 +#define MRAA_PIN_NAME_SIZE 12 + +#define MRAA_SUB_PLATFORM_BIT_SHIFT 9 +#define MRAA_SUB_PLATFORM_MASK (1< MAX. Function will return + * -1 on failure. + * + * @param priority Value from typically 0 to 99 + * @return The priority value set + */ +int mraa_set_priority(const int priority); + +/** Get the version string of mraa autogenerated from git tag + * + * The version returned may not be what is expected however it is a reliable + * number associated with the git tag closest to that version at build time + * + * @return version string from version.h + */ +const char* mraa_get_version(); + +/** + * Print a textual representation of the mraa_result_t + * + * @param result the result to print + */ +void mraa_result_print(mraa_result_t result); + +/** + * Get platform type, board must be initialised. + * + * @return mraa_platform_t Platform type enum + */ +mraa_platform_t mraa_get_platform_type(); + +/** + * Get combined platform type, board must be initialised. + * The combined type is represented as + * (sub_platform_type << 8) | main_platform_type + * + * @return int combined platform type + */ +int mraa_get_platform_combined_type(); + +/** + * Get platform pincount, board must be initialised. + * + * @return uint of physical pin count on the in-use platform + */ +unsigned int mraa_get_pin_count(); + +/** + * Get platform usable I2C bus count, board must be initialised. + * + * @return number f usable I2C bus count on the current platform. Function will + * return -1 on failure + */ +int mraa_get_i2c_bus_count(); + +/** + * Get I2C adapter number in sysfs. + * + * @param i2c_bus the logical I2C bus number + * @return I2C adapter number in sysfs. Function will return -1 on failure + */ +int mraa_get_i2c_bus_id(int i2c_bus); + +/** + * Get specified platform pincount, board must be initialised. + * + * @param specified platform offset; 0 for main platform, 1 foor sub platform + * @return uint of physical pin count on the in-use platform + */ +unsigned int mraa_get_platform_pin_count(uint8_t platform_offset); + +/** +* Get name of pin, board must be initialised. +* +* @param pin number +* @return char* of pin name +*/ +char* mraa_get_pin_name(int pin); + +/** + * Get default i2c bus, board must be initialised. + * + * @return int default i2c bus index + */ +int mraa_get_default_i2c_bus(uint8_t platform_offset); + +/** + * Detect presence of sub platform. + * + * @return mraa_boolean_t 1 if sub platform is present and initialized, 0 otherwise + */ +mraa_boolean_t mraa_has_sub_platform(); + + +/** + * Check if pin or bus id includes sub platform mask. + * + * @param int pin or bus number + * + * @return mraa_boolean_t 1 if pin or bus is for sub platform, 0 otherwise + */ +mraa_boolean_t mraa_is_sub_platform_id(int pin_or_bus_id); + +/** + * Convert pin or bus index to corresponding sub platform id. + * + * @param int pin or bus index + * + * @return int sub platform pin or bus number + */ +int mraa_get_sub_platform_id(int pin_or_bus_index); + +/** + * Convert pin or bus sub platform id to index. + * + * @param int sub platform pin or bus id + * + * @return int pin or bus index + */ +int mraa_get_sub_platform_index(int pin_or_bus_id); + +/** + * Add mraa subplatform + * + * @param subplatform type + * @param uart device subplatform is on + * + * @return mraa_result_t indicating success + */ +mraa_result_t mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev); + +/** + * Remove a mraa subplatform + * + * @param subplatform type + * + * @return mraa_result indicating success + */ +mraa_result_t mraa_remove_subplatform(mraa_platform_t subplatformtype); + +/** + * Create IO using a description in the format: + * [io]-[pin] + * [io]-[raw]-[pin] + * [io]-[raw]-[id]-[pin] + * [io]-[raw]-[path] + * + * @param IO description + * + * @return void* to IO context or NULL + */ +void* mraa_init_io(const char* desc); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/common.hpp b/include/mraa/common.hpp new file mode 100644 index 0000000..29894d3 --- /dev/null +++ b/include/mraa/common.hpp @@ -0,0 +1,330 @@ +/* + * Author: Thomas Ingleby + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "common.h" +#include "types.hpp" +#include + +/** + * @namespace mraa namespace + */ +namespace mraa +{ + +/** + * @file + * @brief API to common functions of MRAA + * + * This file defines the interface for libmraa common functions + */ + +/** + * Initialise MRAA + * + * Detects running platform and attempts to use included pinmap, this is run on + * module/library init/load but is handy to rerun to check board initialised + * correctly. mraa::SUCCESS inidicates correct initialisation. + * + * @return Result of operation + */ +inline Result +init() +{ + return (Result) mraa_init(); +} + +/** + * Get libmraa version. + * + * @return libmraa version (e.g. v0.4.0-20-gb408207) + */ +inline std::string +getVersion() +{ + std::string ret = mraa_get_version(); + return ret; +} + +/** + * This function attempts to set the mraa process to a given priority and the + * scheduler to SCHED_RR. Highest * priority is typically 99 and minimum is 0. + * This function * will set to MAX if * priority is > MAX. Function will return + * -1 on failure. + * + * @param priority Value from typically 0 to 99 + * @return The priority value set + */ +inline int +setPriority(const int priority) +{ + return mraa_set_priority(priority); +} + +/** + * Get platform type, board must be initialised. + * + * @return mraa::platform Platform type enum + */ +inline Platform +getPlatformType() +{ + return (Platform) mraa_get_platform_type(); +} + +/** + * Print a textual representation of the mraa::Result + * + * @param Result the Result to print + */ +inline void +printError(Result result) +{ + mraa_result_print((mraa_result_t) result); +} + +/** + * Checks if a pin is able to use the passed in mode. + * + * @param pin Physical Pin to be checked. + * @param mode the mode to be tested. + * @return boolean if the mode is supported, 0=false. + */ +inline bool +pinModeTest(int pin, Pinmodes mode) +{ + return (bool) mraa_pin_mode_test(pin, (mraa_pinmodes_t) mode); +} + +/** + * Check the board's bit size when reading the value + * + * @return raw bits being read from kernel module. Zero if no ADC + */ +inline unsigned int +adcRawBits() +{ + return mraa_adc_raw_bits(); +} + +/** + * Return value that the raw value should be shifted to. Zero if no ADC + * + * @return return actual bit size the adc value should be understood as. + */ +inline unsigned int +adcSupportedBits() +{ + return mraa_adc_supported_bits(); +} + +/** + * Return Platform Name. Returns NULL if no platform inited. + * + * @return platform name + */ +inline std::string +getPlatformName() +{ + std::string ret_val(mraa_get_platform_name()); + return ret_val; +} + +/** + * Return platform versioning info. Returns NULL if no info present. + * + * @param optional subplatform identifier + * @return platform versioning info + */ +inline std::string +getPlatformVersion(int platform_offset=MRAA_MAIN_PLATFORM_OFFSET) +{ + std::string ret_val(mraa_get_platform_version(platform_offset)); + return ret_val; +} + +/** + * Return count of physical pins on the running platform + * + * @return uint of physical pins. + */ +inline unsigned int +getPinCount() +{ + return mraa_get_pin_count(); +} + +/** + * Get platform usable I2C bus count, board must be initialised. + * + * @return number f usable I2C bus count on the current platform. Function will + * return -1 on failure + */ +inline int +getI2cBusCount() +{ + return mraa_get_i2c_bus_count(); +} + +/** + * Get I2C adapter number in sysfs. + * + * @param i2c_bus the logical I2C bus number + * @return I2C adapter number in sysfs. Function will return -1 on failure + */ +inline int +getI2cBusId(int i2c_bus) +{ + return mraa_get_i2c_bus_id(i2c_bus); +} + +/** +* Get name of pin, board must be initialised. +* +* @param pin number +* +* @return char* of pin name +*/ +inline std::string +getPinName(int pin) +{ + std::string ret_val(mraa_get_pin_name(pin)); + return ret_val; +} + +/** + * Sets the log level to use from 0-7 where 7 is very verbose. These are the + * syslog log levels, see syslog(3) for more information on the levels. + * + * @param level + * @return Result of operation + */ +inline Result +setLogLevel(int level) +{ + return (Result) mraa_set_log_level(level); +} + +/** + * Detect presence of sub platform. + * + * @return bool true if sub platform is present and initialized, false otherwise + */ +inline bool +hasSubPlatform() +{ + return static_cast(mraa_has_sub_platform()); +} + +/** + * Check if pin or bus id includes sub platform mask. + * + * @param int pin or bus number + * + * @return mraa_boolean_t 1 if pin or bus is for sub platform, 0 otherwise + */ +inline bool +isSubPlatformId(int pin_or_bus_id) +{ + return static_cast(mraa_is_sub_platform_id(pin_or_bus_id)); +} + +/** + * Convert pin or bus index to corresponding sub platform id. + * + * @param int pin or bus index + * + * @return int sub platform pin or bus number + */ +inline int +getSubPlatformId(int pin_or_bus_index) +{ + return mraa_get_sub_platform_id(pin_or_bus_index); +} + +/** + * Convert pin or bus sub platform id to index. + * + * @param int sub platform pin or bus id + * + * @return int pin or bus index + */ +inline int +getSubPlatformIndex(int pin_or_bus_id) +{ + return mraa_get_sub_platform_index(pin_or_bus_id); +} + +/** + * Get default i2c bus, board must be initialised. + * + * @param optional subplatform identifier + * @return default i2c bus for paltform + */ +inline int +getDefaultI2cBus(int platform_offset=MRAA_MAIN_PLATFORM_OFFSET) +{ + return mraa_get_default_i2c_bus(platform_offset); +} + +/** + * Add mraa subplatform + * + * @param subplatformtype the type of subplatform to add + * (e.g. MRAA_GENERIC_FIRMATA) + * @param uart_dev subplatform device string (e.g. "/dev/ttyACM0") + * @return Result of operation + */ +inline Result +addSubplatform(Platform subplatformtype, std::string uart_dev) +{ + return (Result) mraa_add_subplatform((mraa_platform_t) subplatformtype, uart_dev.c_str()); +} + +inline Result +removeSubplatform(Platform subplatformtype) +{ + return (Result) mraa_remove_subplatform((mraa_platform_t) subplatformtype); +} + +/** + * Create IO using a description in the format: + * [io]-[pin] + * [io]-[raw]-[pin] + * [io]-[raw]-[id]-[pin] + * [io]-[raw]-[path] + * + * @param IO description + * + * @return class T initialised using pointer to IO or NULL + */ +template +inline T* +initIo(std::string desc) +{ + return new T(mraa_init_io(desc.c_str())); +} + +} diff --git a/include/mraa/firmata.h b/include/mraa/firmata.h new file mode 100644 index 0000000..ba8684e --- /dev/null +++ b/include/mraa/firmata.h @@ -0,0 +1,101 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief Firmata IO + * + * Firmata IO lets you SYSEX messages construct and ask for a callback on a + * SYSEX messages. This is meant to provide a way to call custom firmata APIs + * especially using the Custom firmata API + * + * @snippet firmata_curie_imu.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +/** + * Opaque pointer definition to the internal struct _firmata. This context + * refers to one firmata 'extension' letting you write/return SYSEX messages + * directly + */ +typedef struct _firmata* mraa_firmata_context; + +/** + * Initialise firmata context on a feature. This feature is what will be + * listened on if you request a response callback + * + * @param firmata feature + * @return firmata context or NULL + */ +mraa_firmata_context mraa_firmata_init(int feature); + +/** + * Sends a custom SYSEX message to the firmata board. + * + * @param dev The Firmata context + * @param msg The SYSEX message + * @param length The length of the sysex message + */ +mraa_result_t mraa_firmata_write_sysex(mraa_firmata_context dev, char* msg, int length); + +/** + * Set a callback on 'feature'. This function is not thread safe and threads + * calling it need to make sure they are the only thread calling this. + * + * @param dev The Firmata context + * @param fptr Function pointer to function to be called when interrupt is + * triggered, the returned buffer and length are the arguments. + * @return Result of operation + */ +mraa_result_t mraa_firmata_response(mraa_firmata_context dev, void (*fptr)(uint8_t*, int)); + +/** + * Stop getting events on feature. This is more efficient than mraa_firmata_close + * as it can be re-enabled without adding a feature + * + * @param dev The Firmata context + * @return Result of operation + */ +mraa_result_t mraa_firmata_response_stop(mraa_firmata_context dev); + +/** + * Free all firmata handle resources, this will leave an element in an array + * internally that will be skipped, avoid closing many firmata contexts often + * as there is a cost to doing this + * + * @param dev The Firmata context + * @return Result of operation + */ +mraa_result_t mraa_firmata_close(mraa_firmata_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/gpio.h b/include/mraa/gpio.h new file mode 100644 index 0000000..32e1c6e --- /dev/null +++ b/include/mraa/gpio.h @@ -0,0 +1,225 @@ +/* + * Author: Thomas Ingleby + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief General Purpose IO + * + * Gpio is the General Purpose IO interface to libmraa. Its features depend on + * the board type used, it can use gpiolibs (exported via a kernel module + * through sysfs), or memory mapped IO via a /dev/uio device or /dev/mem + * depending again on the board configuration. + * + * @snippet gpio_read6.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "common.h" + +#if defined(SWIGJAVA) || defined(JAVACALLBACK) +#include +extern "C" { + void mraa_java_isr_callback(void *args); +} +#endif + +/** + * Opaque pointer definition to the internal struct _gpio + */ +typedef struct _gpio* mraa_gpio_context; + +/** + * Gpio Output modes + */ +typedef enum { + MRAA_GPIO_STRONG = 0, /**< Default. Strong high and low */ + MRAA_GPIO_PULLUP = 1, /**< Resistive High */ + MRAA_GPIO_PULLDOWN = 2, /**< Resistive Low */ + MRAA_GPIO_HIZ = 3 /**< High Z State */ +} mraa_gpio_mode_t; + +/** + * Gpio Direction options + */ +typedef enum { + MRAA_GPIO_OUT = 0, /**< Output. A Mode can also be set */ + MRAA_GPIO_IN = 1, /**< Input */ + MRAA_GPIO_OUT_HIGH = 2, /**< Output. Init High */ + MRAA_GPIO_OUT_LOW = 3 /**< Output. Init Low */ +} mraa_gpio_dir_t; + +/** + * Gpio Edge types for interrupts + */ +typedef enum { + MRAA_GPIO_EDGE_NONE = 0, /**< No interrupt on Gpio */ + MRAA_GPIO_EDGE_BOTH = 1, /**< Interrupt on rising & falling */ + MRAA_GPIO_EDGE_RISING = 2, /**< Interrupt on rising only */ + MRAA_GPIO_EDGE_FALLING = 3 /**< Interrupt on falling only */ +} mraa_gpio_edge_t; + +/** + * Initialise gpio_context, based on board number + * + * @param pin Pin number read from the board, i.e IO3 is 3 + * @returns gpio context or NULL + */ +mraa_gpio_context mraa_gpio_init(int pin); + +/** + * Initialise gpio context without any mapping to a pin + * + * @param gpiopin gpio pin as listed in SYSFS + * @return gpio context or NULL + */ +mraa_gpio_context mraa_gpio_init_raw(int gpiopin); + +/** + * Set the edge mode on the gpio + * + * @param dev The Gpio context + * @param mode The edge mode to set the gpio into + * @return Result of operation + */ +mraa_result_t mraa_gpio_edge_mode(mraa_gpio_context dev, mraa_gpio_edge_t mode); + +/** + * Set an interrupt on pin + * + * @param dev The Gpio context + * @param edge The edge mode to set the gpio into + * @param fptr Function pointer to function to be called when interrupt is + * triggered + * @param args Arguments passed to the interrupt handler (fptr) + * @return Result of operation + */ +mraa_result_t mraa_gpio_isr(mraa_gpio_context dev, mraa_gpio_edge_t edge, void (*fptr)(void*), void* args); + +/** + * Stop the current interrupt watcher on this Gpio, and set the Gpio edge mode + * to MRAA_GPIO_EDGE_NONE + * + * @param dev The Gpio context + * @return Result of operation + */ +mraa_result_t mraa_gpio_isr_exit(mraa_gpio_context dev); + +/** + * Set Gpio Output Mode, + * + * @param dev The Gpio context + * @param mode The Gpio Output Mode + * @return Result of operation + */ +mraa_result_t mraa_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode); + +/** + * Set Gpio direction + * + * @param dev The Gpio context + * @param dir The direction of the Gpio + * @return Result of operation + */ +mraa_result_t mraa_gpio_dir(mraa_gpio_context dev, mraa_gpio_dir_t dir); + +/** + * Read Gpio direction + * + * @param dev The Gpio context + * @param dir The address where to store the Gpio direction + * @return Result of operation + */ +mraa_result_t mraa_gpio_read_dir(mraa_gpio_context dev, mraa_gpio_dir_t *dir); + +/** + * Close the Gpio context + * - Will free the memory for the context and unexport the Gpio + * + * @param dev The Gpio context + * @return Result of operation + */ +mraa_result_t mraa_gpio_close(mraa_gpio_context dev); + +/** + * Read the Gpio value. This can be 0 or 1. A resonse of -1 means that there + * was a fatal error. + * + * @param dev The Gpio context + * @return Result of operation + */ +int mraa_gpio_read(mraa_gpio_context dev); + +/** + * Write to the Gpio Value. + * + * @param dev The Gpio context + * @param value Integer value to write + * @return Result of operation + */ +mraa_result_t mraa_gpio_write(mraa_gpio_context dev, int value); + +/** + * Change ownership of the context. + * + * @param dev The Gpio context + * @param owner Does this context own the pin + * @return Result of operation + */ +mraa_result_t mraa_gpio_owner(mraa_gpio_context dev, mraa_boolean_t owner); + +/** + * Enable using memory mapped io instead of sysfs + * + * @param dev The Gpio context + * @param mmap Use mmap instead of sysfs + * @return Result of operation + */ +mraa_result_t mraa_gpio_use_mmaped(mraa_gpio_context dev, mraa_boolean_t mmap); + +/** + * Get a pin number of the gpio, invalid will return -1 + * + * @param dev The Gpio context + * @return Pin number + */ +int mraa_gpio_get_pin(mraa_gpio_context dev); + +/** + * Get a gpio number as used within sysfs, invalid will return -1 + * + * @param dev The Gpio context + * @return gpio number + */ +int mraa_gpio_get_pin_raw(mraa_gpio_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/gpio.hpp b/include/mraa/gpio.hpp new file mode 100644 index 0000000..e2d7ad5 --- /dev/null +++ b/include/mraa/gpio.hpp @@ -0,0 +1,325 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "gpio.h" +#include "types.hpp" +#include + +#if defined(SWIGJAVASCRIPT) +#if NODE_MODULE_VERSION >= 0x000D +#include +#endif +#endif + +namespace mraa +{ + +// These enums must match the enums in gpio.h + +/** + * Gpio Output modes + */ +typedef enum { + MODE_STRONG = 0, /**< Default. Strong High and Low */ + MODE_PULLUP = 1, /**< Resistive High */ + MODE_PULLDOWN = 2, /**< Resistive Low */ + MODE_HIZ = 3 /**< High Z State */ +} Mode; + +/** + * Gpio Direction options + */ +typedef enum { + DIR_OUT = 0, /**< Output. A Mode can also be set */ + DIR_IN = 1, /**< Input */ + DIR_OUT_HIGH = 2, /**< Output. Init High */ + DIR_OUT_LOW = 3 /**< Output. Init Low */ +} Dir; + +/** + * Gpio Edge types for interrupts + */ +typedef enum { + EDGE_NONE = 0, /**< No interrupt on Gpio */ + EDGE_BOTH = 1, /**< Interrupt on rising & falling */ + EDGE_RISING = 2, /**< Interrupt on rising only */ + EDGE_FALLING = 3 /**< Interrupt on falling only */ +} Edge; + +/** + * @brief API to General Purpose IO + * + * This file defines the gpio interface for libmraa + * + * @snippet Blink-IO.cpp Interesting + */ +class Gpio +{ + public: + /** + * Instantiates a Gpio object + * + * @param pin pin number to use + * @param owner (optional) Set pin owner, default behaviour is to 'own' + * the pin if we exported it. This means we will close it on destruct. + * Otherwise it will get left open. This is only valid in sysfs use + * cases + * @param raw (optional) Raw pins will use gpiolibs pin numbering from + * the kernel module. Note that you will not get any muxers set up for + * you so this may not always work as expected. + */ + Gpio(int pin, bool owner = true, bool raw = false) + { + if (raw) { + m_gpio = mraa_gpio_init_raw(pin); + } else { + m_gpio = mraa_gpio_init(pin); + } + + if (m_gpio == NULL) { + throw std::invalid_argument("Invalid GPIO pin specified"); + } + + if (!owner) { + mraa_gpio_owner(m_gpio, 0); + } + } + /** + * Gpio Constructor, takes a pointer to the GPIO context and initialises + * the GPIO class + * + * @param void * to GPIO context + */ + Gpio(void* gpio_context) + { + m_gpio = (mraa_gpio_context) gpio_context; + if (m_gpio == NULL) { + throw std::invalid_argument("Invalid GPIO context"); + } + } + /** + * Gpio object destructor, this will only unexport the gpio if we where + * the owner + */ + ~Gpio() + { + mraa_gpio_close(m_gpio); + } + /** + * Set the edge mode for ISR + * + * @param mode The edge mode to set + * @return Result of operation + */ + Result + edge(Edge mode) + { + return (Result) mraa_gpio_edge_mode(m_gpio, (mraa_gpio_edge_t) mode); + } +#if defined(SWIGPYTHON) + Result + isr(Edge mode, PyObject* pyfunc, PyObject* args) + { + return (Result) mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) mode, (void (*) (void*)) pyfunc, (void*) args); + } +#elif defined(SWIGJAVASCRIPT) + static void + v8isr(uv_work_t* req, int status) + { +#if NODE_MODULE_VERSION >= 0x000D + v8::HandleScope scope(v8::Isolate::GetCurrent()); +#endif + mraa::Gpio* This = (mraa::Gpio*) req->data; + int argc = 1; + v8::Local argv[] = { SWIGV8_INTEGER_NEW(-1) }; +#if NODE_MODULE_VERSION >= 0x000D + v8::Local f = v8::Local::New(v8::Isolate::GetCurrent(), This->m_v8isr); + f->Call(SWIGV8_CURRENT_CONTEXT()->Global(), argc, argv); +#else + This->m_v8isr->Call(SWIGV8_CURRENT_CONTEXT()->Global(), argc, argv); +#endif + delete req; + } + + static void + nop(uv_work_t* req) + { + // Do nothing. + } + + static void + uvwork(void* ctx) + { + uv_work_t* req = new uv_work_t; + req->data = ctx; + uv_queue_work(uv_default_loop(), req, nop, v8isr); + } + + Result + isr(Edge mode, v8::Handle func) + { +#if NODE_MODULE_VERSION >= 0x000D + m_v8isr.Reset(v8::Isolate::GetCurrent(), func); +#else + m_v8isr = v8::Persistent::New(func); +#endif + return (Result) mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) mode, &uvwork, this); + } +#elif defined(SWIGJAVA) || defined(JAVACALLBACK) + Result + isr(Edge mode, jobject runnable) + { + return (Result) mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) mode, mraa_java_isr_callback, runnable); + } +#endif + /** + * Sets a callback to be called when pin value changes + * + * @param mode The edge mode to set + * @param fptr Function pointer to function to be called when interrupt is + * triggered + * @param args Arguments passed to the interrupt handler (fptr) + * @return Result of operation + */ + Result + isr(Edge mode, void (*fptr)(void*), void* args) + { + return (Result) mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) mode, fptr, args); + } + + /** + * Exits callback - this call will not kill the isr thread immediately + * but only when it is out of it's critical section + * + * @return Result of operation + */ + Result + isrExit() + { +#if defined(SWIGJAVASCRIPT) +#if NODE_MODULE_VERSION >= 0x000D + m_v8isr.Reset(); +#else + m_v8isr.Dispose(); + m_v8isr.Clear(); +#endif +#endif + return (Result) mraa_gpio_isr_exit(m_gpio); + } + /** + * Change Gpio mode + * + * @param mode The mode to change the gpio into + * @return Result of operation + */ + Result + mode(Mode mode) + { + return (Result )mraa_gpio_mode(m_gpio, (mraa_gpio_mode_t) mode); + } + /** + * Change Gpio direction + * + * @param dir The direction to change the gpio into + * @return Result of operation + */ + Result + dir(Dir dir) + { + return (Result )mraa_gpio_dir(m_gpio, (mraa_gpio_dir_t) dir); + } + + /** + * Read Gpio direction + * + * @throw std::runtime_error in case of failure + * @return Result of operation + */ + Dir + readDir() + { + mraa_gpio_dir_t dir; + if (mraa_gpio_read_dir(m_gpio, &dir) != MRAA_SUCCESS) { + throw std::runtime_error("Failed to read direction"); + } + return (Dir) dir; + } + + /** + * Read value from Gpio + * + * @return Gpio value + */ + int + read() + { + return mraa_gpio_read(m_gpio); + } + /** + * Write value to Gpio + * + * @param value Value to write to Gpio + * @return Result of operation + */ + Result + write(int value) + { + return (Result) mraa_gpio_write(m_gpio, value); + } + /** + * Enable use of mmap i/o if available. + * + * @param enable true to use mmap + * @return Result of operation + */ + Result + useMmap(bool enable) + { + return (Result) mraa_gpio_use_mmaped(m_gpio, (mraa_boolean_t) enable); + } + /** + * Get pin number of Gpio. If raw param is True will return the + * number as used within sysfs. Invalid will return -1. + * + * @param raw (optional) get the raw gpio number. + * @return Pin number + */ + int + getPin(bool raw = false) + { + if (raw) { + return mraa_gpio_get_pin_raw(m_gpio); + } + return mraa_gpio_get_pin(m_gpio); + } + + private: + mraa_gpio_context m_gpio; +#if defined(SWIGJAVASCRIPT) + v8::Persistent m_v8isr; +#endif +}; +} diff --git a/include/mraa/i2c.h b/include/mraa/i2c.h new file mode 100644 index 0000000..657a53d --- /dev/null +++ b/include/mraa/i2c.h @@ -0,0 +1,186 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief Inter-Integrated Circuit + * + * An i2c context represents a master on an i2c bus and that context can + * communicate to multiple i2c slaves by configuring the address. + * @htmlinclude i2c.txt + * + * @snippet i2c_HMC5883L.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#include "common.h" +#include "gpio.h" + +/** + * Opaque pointer definition to the internal struct _i2c + */ +typedef struct _i2c* mraa_i2c_context; + +/** + * Initialise i2c context, using board defintions + * + * @param bus i2c bus to use + * @return i2c context or NULL + */ +mraa_i2c_context mraa_i2c_init(int bus); + +/** + * Initialise i2c context, passing in the i2c bus to use. + * + * @param bus The i2c bus to use i.e. /dev/i2c-2 would be "2" + * @return i2c context or NULL + */ +mraa_i2c_context mraa_i2c_init_raw(unsigned int bus); + +/** + * Sets the frequency of the i2c context. Most platforms do not support this. + * + * @param dev The i2c context + * @param mode The bus mode + * @return Result of operation + */ +mraa_result_t mraa_i2c_frequency(mraa_i2c_context dev, mraa_i2c_mode_t mode); + +/** + * Simple bulk read from an i2c context + * + * @param dev The i2c context + * @param data pointer to the byte array to read data in to + * @param length max number of bytes to read + * @return length of the read in bytes or -1 + */ +int mraa_i2c_read(mraa_i2c_context dev, uint8_t* data, int length); + +/** + * Simple read for a single byte from the i2c context + * + * @param dev The i2c context + * @return The result of the read or -1 if failed + */ +int mraa_i2c_read_byte(mraa_i2c_context dev); + +/** + * Read a single byte from i2c context, from designated register + * + * @param dev The i2c context + * @param command The register + * @return The result of the read or -1 if failed + */ +int mraa_i2c_read_byte_data(mraa_i2c_context dev, const uint8_t command); + +/** + * Read a single word from i2c context, from designated register + * + * @param dev The i2c context + * @param command The register + * @return The result of the read or -1 if failed + */ +int mraa_i2c_read_word_data(mraa_i2c_context dev, const uint8_t command); + +/** + * Bulk read from i2c context, starting from designated register + * + * @param dev The i2c context + * @param command The register + * @param data pointer to the byte array to read data in to + * @param length max number of bytes to read + * @return The length in bytes passed to the function or -1 + */ +int mraa_i2c_read_bytes_data(mraa_i2c_context dev, uint8_t command, uint8_t* data, int length); + +/** + * Write length bytes to the bus, the first byte in the array is the + * command/register to write + * + * @param dev The i2c context + * @param data pointer to the byte array to be written + * @param length the number of bytes to transmit + * @return Result of operation + */ +mraa_result_t mraa_i2c_write(mraa_i2c_context dev, const uint8_t* data, int length); + +/** + * Write a single byte to an i2c context + * + * @param dev The i2c context + * @param data The byte to write + * @return Result of operation + */ +mraa_result_t mraa_i2c_write_byte(mraa_i2c_context dev, const uint8_t data); + +/** + * Write a single byte to an i2c context + * + * @param dev The i2c context + * @param data The byte to write + * @param command The register + * @return Result of operation + */ +mraa_result_t mraa_i2c_write_byte_data(mraa_i2c_context dev, const uint8_t data, const uint8_t command); + +/** + * Write a single word to an i2c context + * + * @param dev The i2c context + * @param data The word to write + * @param command The register + * @return Result of operation + */ +mraa_result_t mraa_i2c_write_word_data(mraa_i2c_context dev, const uint16_t data, const uint8_t command); + +/** + * Sets the i2c slave address. + * + * @param dev The i2c context + * @param address The address to set for the slave (7-bit address) + * @return Result of operation + */ +mraa_result_t mraa_i2c_address(mraa_i2c_context dev, uint8_t address); + +/** + * De-inits an mraa_i2c_context device + * + * @param dev The i2c context + * @return Result of operation + */ +mraa_result_t mraa_i2c_stop(mraa_i2c_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/i2c.hpp b/include/mraa/i2c.hpp new file mode 100644 index 0000000..52e2153 --- /dev/null +++ b/include/mraa/i2c.hpp @@ -0,0 +1,250 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "i2c.h" +#include "types.hpp" +#include + +namespace mraa +{ + +/** + * @brief API to Inter-Integrated Circuit + * + * An I2c object represents an i2c master and can talk multiple i2c slaves by + * selecting the correct address + * @htmlinclude i2c.txt + * + * @snippet I2c-compass.cpp Interesting + */ +class I2c +{ + public: + /** + * Instantiates an i2c bus. Multiple instances of the same bus can + * exist and the bus is not guarranteed to be on the correct address + * before read/write. + * + * @param bus The i2c bus to use + * @param raw Whether to disable pinmapper for your board + */ + I2c(int bus, bool raw = false) + { + if (raw) { + m_i2c = mraa_i2c_init_raw(bus); + } else { + m_i2c = mraa_i2c_init(bus); + } + if (m_i2c == NULL) { + throw std::invalid_argument("Invalid i2c bus"); + } + } + /** + * I2C constructor, takes a pointer to a I2C context and initialises the I2C class + * + * @param void * to an I2C context + */ + I2c(void* i2c_context) + { + m_i2c = (mraa_i2c_context) i2c_context; + if (m_i2c == NULL) { + throw std::invalid_argument("Invalid I2C context"); + } + } + + /** + * Closes the I2c Bus used. This does not guarrantee the bus will not + * be usable by anyone else or communicates this disconnect to any + * slaves. + */ + ~I2c() + { + mraa_i2c_stop(m_i2c); + } + + /** + * Sets the i2c Frequency for communication. Your board may not support + * the set frequency. Anyone can change this at any time and this will + * affect every slave on the bus + * + * @param mode Frequency to set the bus to + * @return Result of operation + */ + Result + frequency(I2cMode mode) + { + return (Result) mraa_i2c_frequency(m_i2c, (mraa_i2c_mode_t) mode); + } + + /** + * Set the slave to talk to, typically called before every read/write + * operation + * + * @param address Communicate to the i2c slave on this address + * @return Result of operation + */ + Result + address(uint8_t address) + { + return (Result) mraa_i2c_address(m_i2c, address); + } + + /** + * Read exactly one byte from the bus + * + * @throws std::invalid_argument in case of error + * @return char read from the bus + */ + uint8_t + readByte() + { + int x = mraa_i2c_read_byte(m_i2c); + if (x == -1) { + throw std::invalid_argument("Unknown error in I2c::readByte()"); + } + return (uint8_t) x; + } + + /** + * Read length bytes from the bus into *data pointer + * + * @param data Data to read into + * @param length Size of read in bytes to make + * @return length of read, should match length + */ + int + read(uint8_t* data, int length) + { + return mraa_i2c_read(m_i2c, data, length); + } + + /** + * Read byte from an i2c register + * + * @param reg Register to read from + * + * @throws std::invalid_argument in case of error + * @return char read from register + */ + uint8_t + readReg(uint8_t reg) + { + int x = mraa_i2c_read_byte_data(m_i2c, reg); + if (x == -1) { + throw std::invalid_argument("Unknown error in I2c::readReg()"); + } + return (uint8_t) x; + } + + /** + * Read word from an i2c register + * + * @param reg Register to read from + * + * @throws std::invalid_argument in case of error + * @return char read from register + */ + uint16_t + readWordReg(uint8_t reg) + { + int x = mraa_i2c_read_word_data(m_i2c, reg); + if (x == -1) { + throw std::invalid_argument("Unknown error in I2c::readReg()"); + } + return (uint16_t) x; + } + + /** + * Read length bytes from the bus into *data pointer starting from + * an i2c register + * + * @param reg Register to read from + * @param data pointer to the byte array to read data in to + * @param length max number of bytes to read + * @return length passed to the function or -1 + */ + int + readBytesReg(uint8_t reg, uint8_t* data, int length) + { + return mraa_i2c_read_bytes_data(m_i2c, reg, data, length); + } + + /** + * Write a byte on the bus + * + * @param data The byte to send on the bus + * @return Result of operation + */ + Result + writeByte(uint8_t data) + { + return (Result) mraa_i2c_write_byte(m_i2c, data); + } + + /** + * Write length bytes to the bus, the first byte in the array is the + * command/register to write + * + * @param data Buffer to send on the bus, first byte is i2c command + * @param length Size of buffer to send + * @return Result of operation + */ + Result + write(const uint8_t* data, int length) + { + return (Result) mraa_i2c_write(m_i2c, data, length); + } + + /** + * Write a byte to an i2c register + * + * @param reg Register to write to + * @param data Value to write to register + * @return Result of operation + */ + Result + writeReg(uint8_t reg, uint8_t data) + { + return (Result) mraa_i2c_write_byte_data(m_i2c, data, reg); + } + + /** + * Write a word to an i2c register + * + * @param reg Register to write to + * @param data Value to write to register + * @return Result of operation + */ + Result + writeWordReg(uint8_t reg, uint16_t data) + { + return (Result) mraa_i2c_write_word_data(m_i2c, data, reg); + } + + private: + mraa_i2c_context m_i2c; +}; +} diff --git a/include/mraa/iio.h b/include/mraa/iio.h new file mode 100644 index 0000000..a205a76 --- /dev/null +++ b/include/mraa/iio.h @@ -0,0 +1,139 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "common.h" +#include "iio_kernel_headers.h" + +typedef struct { + int index; + int enabled; + char* type; + mraa_boolean_t lendian; + int signedd; + unsigned int offset; + uint64_t mask; + unsigned int bits_used; + unsigned int bytes; + unsigned int shift; + unsigned int location; +} mraa_iio_channel; + +typedef struct { + char* name; + int enabled; +} mraa_iio_event; + +/** + * @file + * @brief iio + * + * An iio context represents an IIO device + * + * @snippet iio_driver.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#include "common.h" + +/** + * Opaque pointer definition to the internal struct _iio + */ +typedef struct _iio* mraa_iio_context; + +/** + * Initialise iio context + * + * @param bus iio device to use + * @return i2c context or NULL + */ +mraa_iio_context mraa_iio_init(int device); + +mraa_result_t mraa_iio_trigger_buffer(mraa_iio_context dev, void (*fptr)(char* data), void* args); + +const char* mraa_iio_get_device_name(mraa_iio_context dev); + +int mraa_iio_get_device_num_by_name(const char* name); + +int mraa_iio_read_size(mraa_iio_context dev); + +mraa_iio_channel* mraa_iio_get_channels(mraa_iio_context dev); + +int mraa_iio_get_channel_count(mraa_iio_context dev); + +mraa_result_t mraa_iio_read_float(mraa_iio_context dev, const char* filename, float* data); + +mraa_result_t mraa_iio_read_int(mraa_iio_context dev, const char* filename, int* data); + +mraa_result_t mraa_iio_read_string(mraa_iio_context dev, const char* filename, char* data, int max_len); + +mraa_result_t mraa_iio_write_float(mraa_iio_context dev, const char* attr_chan, const float data); + +mraa_result_t mraa_iio_write_int(mraa_iio_context dev, const char* attr_chan, const int data); + +mraa_result_t mraa_iio_write_string(mraa_iio_context dev, const char* attr_chan, const char* data); + +mraa_result_t mraa_iio_get_channel_data(mraa_iio_context dev); + +mraa_result_t mraa_iio_get_event_data(mraa_iio_context dev); + +mraa_result_t mraa_iio_event_poll(mraa_iio_context dev, struct iio_event_data* data); + +mraa_result_t +mraa_iio_event_setup_callback(mraa_iio_context dev, void (*fptr)(struct iio_event_data* data, void* args), void* args); + +mraa_result_t mraa_iio_event_extract_event(struct iio_event_data* event, + int* chan_type, + int* modifier, + int* type, + int* direction, + int* channel, + int* channel2, + int* different); + +mraa_result_t mraa_iio_get_mount_matrix(mraa_iio_context dev, const char *sysfs_name, float mm[9]); + +mraa_result_t mraa_iio_create_trigger(mraa_iio_context dev, const char* trigger); + +mraa_result_t mraa_iio_update_channels(mraa_iio_context dev); +/** + * De-inits an mraa_iio_context device + * + * @param dev The iio context + * @return Result of operation + */ +mraa_result_t mraa_iio_close(mraa_iio_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/iio.hpp b/include/mraa/iio.hpp new file mode 100644 index 0000000..9cfbb18 --- /dev/null +++ b/include/mraa/iio.hpp @@ -0,0 +1,245 @@ +/* + * Author: Henry Bruce + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include + #include +#include "iio.h" +#include "types.hpp" + +namespace mraa +{ + +struct IioEventData +{ + int channelType; + int modifier; + int type; + int direction; + int channel; + int channel2; + int diff; +}; + +class IioHandler +{ +public: + virtual void onIioEvent(const IioEventData& eventData) = 0; +}; + + +/** + * @brief API to Industrial IO + * + * This file defines the C++ iio interface for libmraa + * + * @snippet iio_dummy_test.cpp Interesting + */ +class Iio +{ + public: + /** + * Iio Constructor, takes a device number which will map directly to sysfs + * e.g. device 0 maps to /sys/bus/iio/devices/iio:device0 + * + * @param device IIO device number + * + * @throws std::invalid_argument if initialization fails + */ + Iio(int device) + { + m_iio = mraa_iio_init(device); + if (m_iio == NULL) { + std::ostringstream oss; + oss << "IIO device " << device << " is not valid"; + throw std::invalid_argument(oss.str()); + } + } + + /** + * Iio Constructor + * + * @param deviceName IIO device name + * + * @throws std::invalid_argument if initialization fails + */ + Iio(const std::string& deviceName) + { + std::ostringstream oss; + int id = mraa_iio_get_device_num_by_name(deviceName.c_str()); + if (id == -1) { + oss << "IIO device name " << deviceName << " not found"; + throw std::invalid_argument(oss.str()); + } + m_iio = mraa_iio_init(id); + if (m_iio == NULL) { + oss << "IIO device " << deviceName << " is not valid"; + throw std::invalid_argument(oss.str()); + } + } + + /** + * Iio destructor + */ + ~Iio() + { + mraa_iio_close(m_iio); + } + + + /** + * Get device name + * + * @returns The device name + */ + std::string + getDeviceName() const + { + return mraa_iio_get_device_name(m_iio); + } + + /** + * Read an int value from specified attribute. + * + * @param attributeName attribute mame + * + * @returns The int value + * + * @throws std::invalid_argument if read fails + */ + int + readInt(const std::string& attributeName) const + { + int value; + mraa_result_t res = mraa_iio_read_int(m_iio, attributeName.c_str(), &value); + if (res != MRAA_SUCCESS) { + std::ostringstream oss; + oss << "IIO readInt for attibute " << attributeName << " failed"; + throw std::runtime_error(oss.str()); + } + return value; + } + + /** + * Read a float value from specified attribute. + * + * @param attributeName attribute mame + * + * @returns The float value + * + * @throws std::invalid_argument if read fails + */ + float + readFloat(const std::string& attributeName) const + { + float value; + mraa_result_t res = mraa_iio_read_float(m_iio, attributeName.c_str(), &value); + if (res != MRAA_SUCCESS) { + std::ostringstream oss; + oss << "IIO readFloat for attibute " << attributeName << " failed"; + throw std::runtime_error(oss.str()); + } + return value; + } + + /** + * Write an int value to specified attribute. + * + * @param attributeName attribute mame + * @param value int value + * + * @throws std::invalid_argument if write fails + */ + void + writeInt(const std::string& attributeName, int value) const + { + mraa_result_t res = mraa_iio_write_int(m_iio, attributeName.c_str(), value); + if (res != MRAA_SUCCESS) { + std::ostringstream oss; + oss << "IIO writeInt for attibute " << attributeName << " failed"; + throw std::runtime_error(oss.str()); + } + + } + + /** + * Write a float value to specified attribute. + * + * @param attributeName attribute mame + * @param value float value + * + * @throws std::invalid_argument if write fails + */ + void + writeFloat(const std::string& attributeName, float value) const + { + mraa_result_t res = mraa_iio_write_float(m_iio, attributeName.c_str(), value); + if (res != MRAA_SUCCESS) { + std::ostringstream oss; + oss << "IIO writeFloat for attibute " << attributeName << " failed"; + throw std::runtime_error(oss.str()); + } + + } + + /** + * Register event handler. + * + * @param handler handler class that implements IioHandler + * + * @throws std::invalid_argument on failure + */ + void + registerEventHandler(IioHandler* handler) const + { + mraa_result_t res = mraa_iio_event_setup_callback(m_iio, private_event_handler, handler); + if (res != MRAA_SUCCESS) { + throw std::runtime_error("registerEventHandler failed"); + } + } + + private: + static void private_event_handler(iio_event_data* data, void *args) + { + if (args != NULL) { + IioHandler* handler = (IioHandler*)args; + IioEventData eventData; + int chan_type, modifier, type, direction, channel, channel2, different; + mraa_iio_event_extract_event(data, &chan_type, &modifier, &type, &direction, &channel, &channel2, &different); + eventData.channelType = chan_type; + eventData.modifier = modifier; + eventData.type = type; + eventData.direction = direction; + eventData.channel = channel; + eventData.channel2 = channel2; + eventData.diff = different; + handler->onIioEvent(eventData); + } + } + + mraa_iio_context m_iio; +}; + +} diff --git a/include/mraa/iio_kernel_headers.h b/include/mraa/iio_kernel_headers.h new file mode 100644 index 0000000..43a3f9d --- /dev/null +++ b/include/mraa/iio_kernel_headers.h @@ -0,0 +1,144 @@ +/* + * Author: Lay, Kuan Loon + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +//For kernel 4.1+, +//#include +//#include + +//linux/iio/types.h +enum iio_chan_type { + IIO_VOLTAGE, + IIO_CURRENT, + IIO_POWER, + IIO_ACCEL, + IIO_ANGL_VEL, + IIO_MAGN, + IIO_LIGHT, + IIO_INTENSITY, + IIO_PROXIMITY, + IIO_TEMP, + IIO_INCLI, + IIO_ROT, + IIO_ANGL, + IIO_TIMESTAMP, + IIO_CAPACITANCE, + IIO_ALTVOLTAGE, + IIO_CCT, + IIO_PRESSURE, + IIO_HUMIDITYRELATIVE, + IIO_ACTIVITY, + IIO_STEPS, + IIO_ENERGY, + IIO_DISTANCE, + IIO_VELOCITY, +}; + +enum iio_modifier { + IIO_NO_MOD, + IIO_MOD_X, + IIO_MOD_Y, + IIO_MOD_Z, + IIO_MOD_X_AND_Y, + IIO_MOD_X_AND_Z, + IIO_MOD_Y_AND_Z, + IIO_MOD_X_AND_Y_AND_Z, + IIO_MOD_X_OR_Y, + IIO_MOD_X_OR_Z, + IIO_MOD_Y_OR_Z, + IIO_MOD_X_OR_Y_OR_Z, + IIO_MOD_LIGHT_BOTH, + IIO_MOD_LIGHT_IR, + IIO_MOD_ROOT_SUM_SQUARED_X_Y, + IIO_MOD_SUM_SQUARED_X_Y_Z, + IIO_MOD_LIGHT_CLEAR, + IIO_MOD_LIGHT_RED, + IIO_MOD_LIGHT_GREEN, + IIO_MOD_LIGHT_BLUE, + IIO_MOD_QUATERNION, + IIO_MOD_TEMP_AMBIENT, + IIO_MOD_TEMP_OBJECT, + IIO_MOD_NORTH_MAGN, + IIO_MOD_NORTH_TRUE, + IIO_MOD_NORTH_MAGN_TILT_COMP, + IIO_MOD_NORTH_TRUE_TILT_COMP, + IIO_MOD_RUNNING, + IIO_MOD_JOGGING, + IIO_MOD_WALKING, + IIO_MOD_STILL, + IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z, +}; + +enum iio_event_type { + IIO_EV_TYPE_THRESH, + IIO_EV_TYPE_MAG, + IIO_EV_TYPE_ROC, + IIO_EV_TYPE_THRESH_ADAPTIVE, + IIO_EV_TYPE_MAG_ADAPTIVE, + IIO_EV_TYPE_CHANGE, +}; + +enum iio_event_direction { + IIO_EV_DIR_EITHER, + IIO_EV_DIR_RISING, + IIO_EV_DIR_FALLING, + IIO_EV_DIR_NONE, +}; + +//linux/iio/events.h +#if defined(MSYS) || defined(__APPLE__) || defined(__MACOSX__) +#define __USE_LINUX_IOCTL_DEFS +#include +#else +#include +#endif +#if defined(__APPLE__) || defined(__MACOSX__) +#include +#endif + +/** + * struct iio_event_data - The actual event being pushed to userspace + * @id: event identifier + * @timestamp: best estimate of time of event occurrence (often from + * the interrupt handler) + */ +struct iio_event_data { + unsigned long long int id; + long long int timestamp; +}; + +#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int) + +#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) + +#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F) + +#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) + +/* Event code number extraction depends on which type of event we have. + * Perhaps review this function in the future*/ +#define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((short int)(mask & 0xFFFF)) +#define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((short int)(((mask) >> 16) & 0xFFFF)) + +#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF) +#define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1) diff --git a/include/mraa/pwm.h b/include/mraa/pwm.h new file mode 100644 index 0000000..d6f17df --- /dev/null +++ b/include/mraa/pwm.h @@ -0,0 +1,187 @@ +/* + * Author: Thomas Ingleby + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief Pulse Width Modulation module + * + * PWM is the Pulse Width Modulation interface to libmraa. It allows the + * generation of a signal on a pin. Some boards may have higher or lower levels + * of resolution so make sure you check the board & pin you are using before + * hand. + * + * @snippet cycle-pwm3.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "common.h" + +typedef struct _pwm* mraa_pwm_context; + +/** + * Initialise pwm_context, uses board mapping + * + * @param pin The PWM PIN + * @return pwm context or NULL + */ +mraa_pwm_context mraa_pwm_init(int pin); + +/** + * Initialise pwm_context, raw mode + * + * @param chipid The chip inwhich the PWM is under in SYSFS + * @param pin The PWM PIN. + * @return pwm context or NULL + */ +mraa_pwm_context mraa_pwm_init_raw(int chipid, int pin); + +/** + * Set the output duty-cycle percentage, as a float + * + * @param dev The Pwm context to use + * @param percentage A floating-point value representing percentage of output. + * The value should lie between 0.0f (representing on 0%) and 1.0f + * Values above or below this range will be set at either 0.0f or 1.0f + * @return Result of operation + */ +mraa_result_t mraa_pwm_write(mraa_pwm_context dev, float percentage); + +/** + * Read the output duty-cycle percentage, as a float + * + * @param dev The Pwm context to use + * @return percentage A floating-point value representing percentage of output. + * The value should lie between 0.0f (representing on 0%) and 1.0f + * Values above or below this range will be set at either 0.0f or 1.0f + */ +float mraa_pwm_read(mraa_pwm_context dev); + +/** + * Set the PWM period as seconds represented in a float + * + * @param dev The Pwm context to use + * @param seconds Period represented as a float in seconds + * @return Result of operation + */ +mraa_result_t mraa_pwm_period(mraa_pwm_context dev, float seconds); + +/** + * Set period, milliseconds. + * + * @param dev The Pwm context to use + * @param ms Milliseconds for period + * @return Result of operation + */ +mraa_result_t mraa_pwm_period_ms(mraa_pwm_context dev, int ms); + +/** + * Set period, microseconds + * + * @param dev The Pwm context to use + * @param us Microseconds as period + * @return Result of operation + */ +mraa_result_t mraa_pwm_period_us(mraa_pwm_context dev, int us); + +/** + * Set pulsewidth, As represnted by seconds in a (float) + * + * @param dev The Pwm context to use + * @param seconds The duration of a pulse + * @return Result of operation + */ +mraa_result_t mraa_pwm_pulsewidth(mraa_pwm_context dev, float seconds); + +/** + * Set pulsewidth, milliseconds + * + * @param dev The Pwm context to use + * @param ms Milliseconds for pulsewidth + * @return Result of operation + */ +mraa_result_t mraa_pwm_pulsewidth_ms(mraa_pwm_context dev, int ms); + +/** + * Set pulsewidth, microseconds + * + * @param dev The Pwm context to use + * @param us Microseconds for pulsewidth + * @return Result of operation + */ +mraa_result_t mraa_pwm_pulsewidth_us(mraa_pwm_context dev, int us); + +/** + * Set the enable status of the PWM pin. None zero will assume on with output being driven. + * and 0 will disable the output. + * + * @param dev The pwm context to use + * @param enable Toggle status of pin + * @return Result of operation. + */ +mraa_result_t mraa_pwm_enable(mraa_pwm_context dev, int enable); + +/** + * Change ownership of context + * + * @param dev the context + * @param owner Ownership boolean + * @return Result of operation + */ +mraa_result_t mraa_pwm_owner(mraa_pwm_context dev, mraa_boolean_t owner); + +/** + * Close and unexport the PWM pin + * + * @param dev The pwm context to use + * @return Result of operation + */ +mraa_result_t mraa_pwm_close(mraa_pwm_context dev); + +/** + * Get the maximum pwm period in us + * + * @param dev The pwm context to use + * @return max pwm in us + */ +int mraa_pwm_get_max_period(mraa_pwm_context dev); + +/** + * Get the minimum pwm period in us + * + * @param dev The pwm context to use + * @return min pwm in us + */ +int mraa_pwm_get_min_period(mraa_pwm_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/pwm.hpp b/include/mraa/pwm.hpp new file mode 100644 index 0000000..c75255a --- /dev/null +++ b/include/mraa/pwm.hpp @@ -0,0 +1,219 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "pwm.h" +#include "types.hpp" +#include + +namespace mraa +{ + +/** + * @brief API to Pulse Width Modulation + * + * This file defines the PWM interface for libmraa + * + * @snippet Pwm3-cycle.cpp Interesting + */ +class Pwm +{ + public: + /** + * instanciates a PWM object on a pin + * + * @param pin the pin number used on your board + * @param owner if you are the owner of the pin the destructor will + * unexport the pin from sysfs, default behaviour is you are the owner + * if the pinmapper exported it + * @param chipid the pwmchip to use, use only in raw mode + */ + Pwm(int pin, bool owner = true, int chipid = -1) + { + if (chipid == -1) { + m_pwm = mraa_pwm_init(pin); + } else { + m_pwm = mraa_pwm_init_raw(chipid, pin); + } + + if (m_pwm == NULL) { + throw std::invalid_argument("Error initialising PWM on pin"); + } + + if (!owner) { + mraa_pwm_owner(m_pwm, 0); + } + } + + /** + * Pwm constructor, takes a pointer to the PWM context and + * initialises the class + * + * @param void * to a PWM context + */ + Pwm(void* pwm_context) + { + m_pwm = (mraa_pwm_context) pwm_context; + if (m_pwm == NULL) { + throw std::invalid_argument("Invalid PWM context"); + } + } + /** + * Pwm destructor + */ + ~Pwm() + { + mraa_pwm_close(m_pwm); + } + /** + * Set the output duty-cycle percentage, as a float + * + * @param percentage A floating-point value representing percentage of + * output. The value should lie between 0.0f (representing 0%) and + * 1.0f Values above or below this range will be set at either 0.0f or + * 1.0f + * @return Result of operation + */ + Result + write(float percentage) + { + return (Result) mraa_pwm_write(m_pwm, percentage); + } + /** + * Read the output duty-cycle percentage, as a float + * + * @return A floating-point value representing percentage of + * output. The value should lie between 0.0f (representing 0%) and + * 1.0f Values above or below this range will be set at either 0.0f or + * 1.0f + */ + float + read() + { + return mraa_pwm_read(m_pwm); + } + /** + * Set the PWM period as seconds represented in a float + * + * @param period Period represented as a float in seconds + * @return Result of operation + */ + Result + period(float period) + { + return (Result) mraa_pwm_period(m_pwm, period); + } + /** + * Set period, milliseconds + * + * @param ms milliseconds for period + * @return Result of operation + */ + Result + period_ms(int ms) + { + return (Result) mraa_pwm_period_ms(m_pwm, ms); + } + /** + * Set period, microseconds + * + * @param us microseconds as period + * @return Result of operation + */ + Result + period_us(int us) + { + return (Result) mraa_pwm_period_us(m_pwm, us); + } + /** + * Set pulsewidth, as represented by seconds in a float + * + * @param seconds The duration of a pulse + * @return Result of operation + */ + Result + pulsewidth(float seconds) + { + return (Result) mraa_pwm_pulsewidth(m_pwm, seconds); + } + /** + * Set pulsewidth, milliseconds + * + * @param ms milliseconds for pulsewidth + * @return Result of operation + */ + Result + pulsewidth_ms(int ms) + { + return (Result) mraa_pwm_pulsewidth_ms(m_pwm, ms); + } + /** + * The pulsewidth, microseconds + * + * @param us microseconds for pulsewidth + * @return Result of operation + */ + Result + pulsewidth_us(int us) + { + return (Result) mraa_pwm_pulsewidth_us(m_pwm, us); + } + /** + * Set the enable status of the PWM pin. None zero will assume on with + * output being driven and 0 will disable the output + * + * @param enable enable status of pin + * @return Result of operation + */ + Result + enable(bool enable) + { + return (Result) mraa_pwm_enable(m_pwm, enable); + } + /** + * Get the maximum PWM period in us + * + * @return max PWM period in us + */ + int + max_period() + { + return mraa_pwm_get_max_period(m_pwm); + } + /** + * Get the minimum PWM period in us + * + * @return min PWM period in us + */ + int + min_period() + { + return mraa_pwm_get_min_period(m_pwm); + } + + private: + mraa_pwm_context m_pwm; +}; +} diff --git a/include/mraa/spi.h b/include/mraa/spi.h new file mode 100644 index 0000000..d53ec3a --- /dev/null +++ b/include/mraa/spi.h @@ -0,0 +1,196 @@ +/* + * Author: Thomas Ingleby + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief Serial Peripheral Interface + * + * This file defines the spi interface for libmraa. A Spi object in libmraa + * represents a spidev device. Linux spidev devices are created per spi bus and + * every chip select available on that bus has another spidev 'file'. A lot + * more information on spidev devices is available + * [here](https://www.kernel.org/doc/Documentation/spi/spidev). + * + * @snippet spi_mcp4261.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include "common.h" + +/** + * MRAA SPI Modes + */ +typedef enum { + MRAA_SPI_MODE0 = 0, /**< CPOL = 0, CPHA = 0, Clock idle low, data is clocked in on rising edge, + output data (change) on falling edge */ + MRAA_SPI_MODE1 = 1, /**< CPOL = 0, CPHA = 1, Clock idle low, data is clocked in on falling edge, + output data (change) on rising edge */ + MRAA_SPI_MODE2 = 2, /**< CPOL = 1, CPHA = 0, Clock idle low, data is clocked in on falling edge, + output data (change) on rising edge */ + MRAA_SPI_MODE3 = 3, /**< CPOL = 1, CPHA = 1, Clock idle low, data is clocked in on rising, edge + output data (change) on falling edge */ +} mraa_spi_mode_t; + +/** + * Opaque pointer definition to the internal struct _spi + */ +typedef struct _spi* mraa_spi_context; + +/** + * Initialise SPI_context, uses board mapping. Sets the muxes + * + * @param bus Bus to use, as listed in platform definition, normally 0 + * @return Spi context or NULL + */ +mraa_spi_context mraa_spi_init(int bus); + +/** + * Initialise SPI_context without any board configuration, selects a bus and a mux. + * + * @param bus Bus to use as listed by spidev + * @param cs Chip select to use as listed in spidev + * @return Spi context or NULL + */ +mraa_spi_context mraa_spi_init_raw(unsigned int bus, unsigned int cs); + +/** + * Set the SPI device mode. see spidev 0-3. + * + * @param dev The Spi context + * @param mode The SPI mode, See Linux spidev + * @return Result of operation + */ +mraa_result_t mraa_spi_mode(mraa_spi_context dev, mraa_spi_mode_t mode); + +/** + * Set the SPI device operating clock frequency. + * + * @param dev the Spi context + * @param hz the frequency in hz + * @return Result of operation + */ +mraa_result_t mraa_spi_frequency(mraa_spi_context dev, int hz); + +/** + * Write Single Byte to the SPI device. + * + * @param dev The Spi context + * @param data Data to send + * @return Data received on the miso line or -1 in case of error + */ +int mraa_spi_write(mraa_spi_context dev, uint8_t data); + +/** + * Write Two Bytes to the SPI device. + * + * @param dev The Spi context + * @param data Data to send + * @return Data received on the miso line + */ +int mraa_spi_write_word(mraa_spi_context dev, uint16_t data); + +/** + * Write Buffer of bytes to the SPI device. The pointer return has to be + * free'd by the caller. It will return a NULL pointer in cases of error. + * + * @param dev The Spi context + * @param data to send + * @param length elements within buffer, Max 4096 + * @return Data received on the miso line, same length as passed in + */ +uint8_t* mraa_spi_write_buf(mraa_spi_context dev, uint8_t* data, int length); + +/** + * Write Buffer of uint16 to the SPI device. The pointer return has to be + * free'd by the caller. It will return a NULL pointer in cases of error. + * + * @param dev The Spi context + * @param data to send + * @param length elements (in bytes) within buffer, Max 4096 + * @return Data received on the miso line, same length as passed in + */ +uint16_t* mraa_spi_write_buf_word(mraa_spi_context dev, uint16_t* data, int length); + +/** + * Transfer Buffer of bytes to the SPI device. Both send and recv buffers + * are passed in + * + * @param dev The Spi context + * @param data to send + * @param rxbuf buffer to recv data back, may be NULL + * @param length elements within buffer, Max 4096 + * @return Result of operation + */ +mraa_result_t mraa_spi_transfer_buf(mraa_spi_context dev, uint8_t* data, uint8_t* rxbuf, int length); + +/** + * Transfer Buffer of uint16 to the SPI device. Both send and recv buffers + * are passed in + * + * @param dev The Spi context + * @param data to send + * @param rxbuf buffer to recv data back, may be NULL + * @param length elements (in bytes) within buffer, Max 4096 + * @return Result of operation + */ +mraa_result_t mraa_spi_transfer_buf_word(mraa_spi_context dev, uint16_t* data, uint16_t* rxbuf, int length); + +/** + * Change the SPI lsb mode + * + * @param dev The Spi context + * @param lsb Use least significant bit transmission. 0 for msbi + * @return Result of operation + */ +mraa_result_t mraa_spi_lsbmode(mraa_spi_context dev, mraa_boolean_t lsb); + +/** + * Set bits per mode on transaction, defaults at 8 + * + * @param dev The Spi context + * @param bits bits per word + * @return Result of operation + */ +mraa_result_t mraa_spi_bit_per_word(mraa_spi_context dev, unsigned int bits); + +/** + * De-inits an mraa_spi_context device + * + * @param dev The Spi context + * @return Result of operation + */ +mraa_result_t mraa_spi_stop(mraa_spi_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/spi.hpp b/include/mraa/spi.hpp new file mode 100644 index 0000000..94a3f64 --- /dev/null +++ b/include/mraa/spi.hpp @@ -0,0 +1,243 @@ +/* + * Author: Brendan Le Foll + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "spi.h" +#include "types.hpp" +#include + +namespace mraa +{ + +/** + * MRAA SPI Modes + */ +typedef enum { + SPI_MODE0 = 0, /**< CPOL = 0, CPHA = 0, Clock idle low, data is clocked in on rising edge, + output data (change) on falling edge */ + SPI_MODE1 = 1, /**< CPOL = 0, CPHA = 1, Clock idle low, data is clocked in on falling edge, + output data (change) on rising edge */ + SPI_MODE2 = 2, /**< CPOL = 1, CPHA = 0, Clock idle low, data is clocked in on falling edge, + output data (change) on rising edge */ + SPI_MODE3 = 3, /**< CPOL = 1, CPHA = 1, Clock idle low, data is clocked in on rising, edge + output data (change) on falling edge */ +} Spi_Mode; + + +/** +* @brief API to Serial Peripheral Interface +* +* This file defines the SPI interface for libmraa +* +* @snippet Spi-pot.cpp Interesting +*/ +class Spi +{ + public: + /** + * Initialise SPI object using the board mapping to set muxes + * + * @param bus to use, as listed in the platform definition, normally 0 + */ + Spi(int bus) + { + m_spi = mraa_spi_init(bus); + + if (m_spi == NULL) { + throw std::invalid_argument("Error initialising SPI bus"); + } + } + + Spi(int bus, int cs) + { + m_spi = mraa_spi_init_raw(bus, cs); + + if (m_spi == NULL) { + throw std::invalid_argument("Error initialising SPI bus"); + } + } + + /** + * Spi Constructor, takes a pointer to a SPI context and initialises + * the SPI class + * + * @param void * to SPI context + */ + Spi(void* spi_context) + { + m_spi = (mraa_spi_context) spi_context; + if (m_spi == NULL) { + throw std::invalid_argument("Invalid SPI context"); + } + } + + /** + * Closes spi bus + */ + ~Spi() + { + mraa_spi_stop(m_spi); + } + + /** + * Set the SPI device mode. see spidev0-3 + * + * @param mode the mode. See Linux spidev doc + * @return Result of operation + */ + Result + mode(Spi_Mode mode) + { + return (Result) mraa_spi_mode(m_spi, (mraa_spi_mode_t) mode); + } + + /** + * Set the SPI device operating clock frequency + * + * @param hz the frequency to set in hz + * @return Result of operation + */ + Result + frequency(int hz) + { + return (Result) mraa_spi_frequency(m_spi, hz); + } + + /** + * Write single byte to the SPI device + * + * @param data the byte to send + * @return data received on the miso line or -1 in case of error + */ + int + writeByte(uint8_t data) + { + return mraa_spi_write(m_spi, (uint8_t) data); + } + + /** + * Write single byte to the SPI device + * + * @param data the byte to send + * @return data received on the miso line or -1 in case of error + */ + int + writeWord(uint16_t data) + { + return mraa_spi_write_word(m_spi, (uint16_t) data); + } + + /** + * Write buffer of bytes to SPI device The pointer return has to be + * free'd by the caller. It will return a NULL pointer in cases of + * error + * + * @param txBuf buffer to send + * @param length size of buffer to send + * @return uint8_t* data received on the miso line. Same length as passed in + */ + uint8_t* + write(uint8_t* txBuf, int length) + { + return mraa_spi_write_buf(m_spi, txBuf, length); + } + +#ifndef SWIG + /** + * Write buffer of bytes to SPI device The pointer return has to be + * free'd by the caller. It will return a NULL pointer in cases of + * error + * + * @param txBuf buffer to send + * @param length size of buffer (in bytes) to send + * @return uint8_t* data received on the miso line. Same length as passed in + */ + uint16_t* + writeWord(uint16_t* txBuf, int length) + { + return mraa_spi_write_buf_word(m_spi, txBuf, length); + } +#endif + +#ifndef SWIG + /** + * Transfer data to and from SPI device Receive pointer may be null if + * return data is not needed. + * + * @param txBuf buffer to send + * @param rxBuf buffer to optionally receive data from spi device + * @param length size of buffer to send + * @return Result of operation + */ + Result + transfer(uint8_t* txBuf, uint8_t* rxBuf, int length) + { + return (Result) mraa_spi_transfer_buf(m_spi, txBuf, rxBuf, length); + } + + /** + * Transfer data to and from SPI device Receive pointer may be null if + * return data is not needed. + * + * @param txBuf buffer to send + * @param rxBuf buffer to optionally receive data from spi device + * @param length size of buffer to send + * @return Result of operation + */ + Result + transfer_word(uint16_t* txBuf, uint16_t* rxBuf, int length) + { + return (Result) mraa_spi_transfer_buf_word(m_spi, txBuf, rxBuf, length); + } +#endif + + /** + * Change the SPI lsb mode + * + * @param lsb Use least significant bit transmission - 0 for msbi + * @return Result of operation + */ + Result + lsbmode(bool lsb) + { + return (Result) mraa_spi_lsbmode(m_spi, (mraa_boolean_t) lsb); + } + + /** + * Set bits per mode on transaction, default is 8 + * + * @param bits bits per word + * @return Result of operation + */ + Result + bitPerWord(unsigned int bits) + { + return (Result) mraa_spi_bit_per_word(m_spi, bits); + } + + private: + mraa_spi_context m_spi; +}; +} diff --git a/include/mraa/types.h b/include/mraa/types.h new file mode 100644 index 0000000..da479b9 --- /dev/null +++ b/include/mraa/types.h @@ -0,0 +1,251 @@ +/* + * Author: Brendan Le Foll + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#pragma once + +/** @file + * + * This file defines the basic shared types for libmraa + * this file is different to common.h in that swig takes this as an input + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * MRAA supported platform types + */ +typedef enum { + MRAA_INTEL_GALILEO_GEN1 = 0, /**< The Generation 1 Galileo platform (RevD) */ + MRAA_INTEL_GALILEO_GEN2 = 1, /**< The Generation 2 Galileo platform (RevG/H) */ + MRAA_INTEL_EDISON_FAB_C = 2, /**< The Intel Edison (FAB C) */ + MRAA_INTEL_DE3815 = 3, /**< The Intel DE3815 Baytrail NUC */ + MRAA_INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ + MRAA_RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ + MRAA_BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ + MRAA_BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ + MRAA_INTEL_NUC5 = 8, /**< The Intel 5th generations Broadwell NUCs */ + MRAA_96BOARDS = 9, /**< Linaro 96boards */ + MRAA_INTEL_SOFIA_3GR = 10, /**< The Intel SoFIA 3GR */ + MRAA_INTEL_CHERRYHILLS = 11, /**< The Intel Braswell Cherryhills */ + MRAA_UP = 12, /**< The UP Board */ + MRAA_INTEL_GT_TUCHUCK = 13, /**< The Intel GT Tuchuck Board */ + + // USB platform extenders start at 256 + MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ + + // contains bit 9 so is subplatform + MRAA_GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + + MRAA_MOCK_PLATFORM = 96, /**< Mock platform, which requires no real hardware */ + MRAA_NULL_PLATFORM = 98, /**< Platform with no capabilities that hosts a sub platform */ + MRAA_UNKNOWN_PLATFORM = + 99 /**< An unknown platform type, typically will load INTEL_GALILEO_GEN1 */ +} mraa_platform_t; + +/** + * Intel edison miniboard numbering enum + */ +typedef enum { + MRAA_INTEL_EDISON_MINIBOARD_J17_1 = 0, + MRAA_INTEL_EDISON_MINIBOARD_J17_5 = 4, + MRAA_INTEL_EDISON_MINIBOARD_J17_7 = 6, + MRAA_INTEL_EDISON_MINIBOARD_J17_8 = 7, + MRAA_INTEL_EDISON_MINIBOARD_J17_9 = 8, + MRAA_INTEL_EDISON_MINIBOARD_J17_10 = 9, + MRAA_INTEL_EDISON_MINIBOARD_J17_11 = 10, + MRAA_INTEL_EDISON_MINIBOARD_J17_12 = 11, + MRAA_INTEL_EDISON_MINIBOARD_J17_14 = 13, + MRAA_INTEL_EDISON_MINIBOARD_J18_1 = 14, + MRAA_INTEL_EDISON_MINIBOARD_J18_2 = 15, + MRAA_INTEL_EDISON_MINIBOARD_J18_6 = 19, + MRAA_INTEL_EDISON_MINIBOARD_J18_7 = 20, + MRAA_INTEL_EDISON_MINIBOARD_J18_8 = 21, + MRAA_INTEL_EDISON_MINIBOARD_J18_10 = 23, + MRAA_INTEL_EDISON_MINIBOARD_J18_11 = 24, + MRAA_INTEL_EDISON_MINIBOARD_J18_12 = 25, + MRAA_INTEL_EDISON_MINIBOARD_J18_13 = 26, + MRAA_INTEL_EDISON_MINIBOARD_J19_4 = 31, + MRAA_INTEL_EDISON_MINIBOARD_J19_5 = 32, + MRAA_INTEL_EDISON_MINIBOARD_J19_6 = 33, + MRAA_INTEL_EDISON_MINIBOARD_J19_8 = 35, + MRAA_INTEL_EDISON_MINIBOARD_J19_9 = 36, + MRAA_INTEL_EDISON_MINIBOARD_J19_10 = 37, + MRAA_INTEL_EDISON_MINIBOARD_J19_11 = 38, + MRAA_INTEL_EDISON_MINIBOARD_J19_12 = 39, + MRAA_INTEL_EDISON_MINIBOARD_J19_13 = 40, + MRAA_INTEL_EDISON_MINIBOARD_J19_14 = 41, + MRAA_INTEL_EDISON_MINIBOARD_J20_3 = 44, + MRAA_INTEL_EDISON_MINIBOARD_J20_4 = 45, + MRAA_INTEL_EDISON_MINIBOARD_J20_5 = 46, + MRAA_INTEL_EDISON_MINIBOARD_J20_6 = 47, + MRAA_INTEL_EDISON_MINIBOARD_J20_7 = 48, + MRAA_INTEL_EDISON_MINIBOARD_J20_8 = 49, + MRAA_INTEL_EDISON_MINIBOARD_J20_9 = 50, + MRAA_INTEL_EDISON_MINIBOARD_J20_10 = 51, + MRAA_INTEL_EDISON_MINIBOARD_J20_11 = 52, + MRAA_INTEL_EDISON_MINIBOARD_J20_12 = 53, + MRAA_INTEL_EDISON_MINIBOARD_J20_13 = 54, + MRAA_INTEL_EDISON_MINIBOARD_J20_14 = 55 +} mraa_intel_edison_miniboard_t; + +/** + * Intel Edison raw GPIO numbering enum + */ +typedef enum { + MRAA_INTEL_EDISON_GP182 = 0, + MRAA_INTEL_EDISON_GP135 = 4, + MRAA_INTEL_EDISON_GP27 = 6, + MRAA_INTEL_EDISON_GP20 = 7, + MRAA_INTEL_EDISON_GP28 = 8, + MRAA_INTEL_EDISON_GP111 = 0, + MRAA_INTEL_EDISON_GP109 = 10, + MRAA_INTEL_EDISON_GP115 = 11, + MRAA_INTEL_EDISON_GP128 = 13, + MRAA_INTEL_EDISON_GP13 = 14, + MRAA_INTEL_EDISON_GP165 = 15, + MRAA_INTEL_EDISON_GP19 = 19, + MRAA_INTEL_EDISON_GP12 = 20, + MRAA_INTEL_EDISON_GP183 = 21, + MRAA_INTEL_EDISON_GP110 = 23, + MRAA_INTEL_EDISON_GP114 = 24, + MRAA_INTEL_EDISON_GP129 = 25, + MRAA_INTEL_EDISON_GP130 = 26, + MRAA_INTEL_EDISON_GP44 = 31, + MRAA_INTEL_EDISON_GP46 = 32, + MRAA_INTEL_EDISON_GP48 = 33, + MRAA_INTEL_EDISON_GP131 = 35, + MRAA_INTEL_EDISON_GP14 = 36, + MRAA_INTEL_EDISON_GP40 = 37, + MRAA_INTEL_EDISON_GP43 = 38, + MRAA_INTEL_EDISON_GP77 = 39, + MRAA_INTEL_EDISON_GP82 = 40, + MRAA_INTEL_EDISON_GP83 = 41, + MRAA_INTEL_EDISON_GP134 = 44, + MRAA_INTEL_EDISON_GP45 = 45, + MRAA_INTEL_EDISON_GP47 = 46, + MRAA_INTEL_EDISON_GP49 = 47, + MRAA_INTEL_EDISON_GP15 = 48, + MRAA_INTEL_EDISON_GP84 = 49, + MRAA_INTEL_EDISON_GP42 = 50, + MRAA_INTEL_EDISON_GP41 = 51, + MRAA_INTEL_EDISON_GP78 = 52, + MRAA_INTEL_EDISON_GP79 = 53, + MRAA_INTEL_EDISON_GP80 = 54, + MRAA_INTEL_EDISON_GP81 = 55 +} mraa_intel_edison_t; + +/** +* Raspberry PI Wiring compatible numbering enum +*/ +typedef enum { + MRAA_RASPBERRY_WIRING_PIN8 = 3, + MRAA_RASPBERRY_WIRING_PIN9 = 5, + MRAA_RASPBERRY_WIRING_PIN7 = 7, + MRAA_RASPBERRY_WIRING_PIN15 = 8, + MRAA_RASPBERRY_WIRING_PIN16 = 10, + MRAA_RASPBERRY_WIRING_PIN0 = 11, + MRAA_RASPBERRY_WIRING_PIN1 = 12, + MRAA_RASPBERRY_WIRING_PIN2 = 13, + MRAA_RASPBERRY_WIRING_PIN3 = 15, + MRAA_RASPBERRY_WIRING_PIN4 = 16, + MRAA_RASPBERRY_WIRING_PIN5 = 18, + MRAA_RASPBERRY_WIRING_PIN12 = 19, + MRAA_RASPBERRY_WIRING_PIN13 = 21, + MRAA_RASPBERRY_WIRING_PIN6 = 22, + MRAA_RASPBERRY_WIRING_PIN14 = 23, + MRAA_RASPBERRY_WIRING_PIN10 = 24, + MRAA_RASPBERRY_WIRING_PIN11 = 26, + MRAA_RASPBERRY_WIRING_PIN17 = 29, // RPi B V2 + MRAA_RASPBERRY_WIRING_PIN21 = 29, + MRAA_RASPBERRY_WIRING_PIN18 = 30, // RPi B V2 + MRAA_RASPBERRY_WIRING_PIN19 = 31, // RPI B V2 + MRAA_RASPBERRY_WIRING_PIN22 = 31, + MRAA_RASPBERRY_WIRING_PIN20 = 32, // RPi B V2 + MRAA_RASPBERRY_WIRING_PIN26 = 32, + MRAA_RASPBERRY_WIRING_PIN23 = 33, + MRAA_RASPBERRY_WIRING_PIN24 = 35, + MRAA_RASPBERRY_WIRING_PIN27 = 36, + MRAA_RASPBERRY_WIRING_PIN25 = 37, + MRAA_RASPBERRY_WIRING_PIN28 = 38, + MRAA_RASPBERRY_WIRING_PIN29 = 40 +} mraa_raspberry_wiring_t; + +/** + * MRAA return codes + */ +typedef enum { + MRAA_SUCCESS = 0, /**< Expected response */ + MRAA_ERROR_FEATURE_NOT_IMPLEMENTED = 1, /**< Feature TODO */ + MRAA_ERROR_FEATURE_NOT_SUPPORTED = 2, /**< Feature not supported by HW */ + MRAA_ERROR_INVALID_VERBOSITY_LEVEL = 3, /**< Verbosity level wrong */ + MRAA_ERROR_INVALID_PARAMETER = 4, /**< Parameter invalid */ + MRAA_ERROR_INVALID_HANDLE = 5, /**< Handle invalid */ + MRAA_ERROR_NO_RESOURCES = 6, /**< No resource of that type avail */ + MRAA_ERROR_INVALID_RESOURCE = 7, /**< Resource invalid */ + MRAA_ERROR_INVALID_QUEUE_TYPE = 8, /**< Queue type incorrect */ + MRAA_ERROR_NO_DATA_AVAILABLE = 9, /**< No data available */ + MRAA_ERROR_INVALID_PLATFORM = 10, /**< Platform not recognised */ + MRAA_ERROR_PLATFORM_NOT_INITIALISED = 11, /**< Board information not initialised */ + MRAA_ERROR_UART_OW_SHORTED = 12, /**< UART OW Short Circuit Detected*/ + MRAA_ERROR_UART_OW_NO_DEVICES = 13, /**< UART OW No devices detected */ + MRAA_ERROR_UART_OW_DATA_ERROR = 14, /**< UART OW Data/Bus error detected */ + + MRAA_ERROR_UNSPECIFIED = 99 /**< Unknown Error */ +} mraa_result_t; + +/** + * Enum representing different possible modes for a pin. + */ +typedef enum { + MRAA_PIN_VALID = 0, /**< Pin Valid */ + MRAA_PIN_GPIO = 1, /**< General Purpose IO */ + MRAA_PIN_PWM = 2, /**< Pulse Width Modulation */ + MRAA_PIN_FAST_GPIO = 3, /**< Faster GPIO */ + MRAA_PIN_SPI = 4, /**< SPI */ + MRAA_PIN_I2C = 5, /**< I2C */ + MRAA_PIN_AIO = 6, /**< Analog in */ + MRAA_PIN_UART = 7 /**< UART */ +} mraa_pinmodes_t; + +/** + * Enum reprensenting different i2c speeds/modes + */ +typedef enum { + MRAA_I2C_STD = 0, /**< up to 100Khz */ + MRAA_I2C_FAST = 1, /**< up to 400Khz */ + MRAA_I2C_HIGH = 2 /**< up to 3.4Mhz */ +} mraa_i2c_mode_t; + +typedef enum { + MRAA_UART_PARITY_NONE = 0, + MRAA_UART_PARITY_EVEN = 1, + MRAA_UART_PARITY_ODD = 2, + MRAA_UART_PARITY_MARK = 3, + MRAA_UART_PARITY_SPACE = 4 +} mraa_uart_parity_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/types.hpp b/include/mraa/types.hpp new file mode 100644 index 0000000..4aa50a8 --- /dev/null +++ b/include/mraa/types.hpp @@ -0,0 +1,247 @@ +/* + * Author: Brendan Le Foll + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#pragma once + +/** @file + * + * This file defines the basic shared types for libmraa + * this file is different to common.h in that swig takes this as an input + */ + +namespace mraa +{ + +//These enums must match the enums in types.h + +/** + * MRAA supported platform types + */ +typedef enum { + INTEL_GALILEO_GEN1 = 0, /**< The Generation 1 Galileo platform (RevD) */ + INTEL_GALILEO_GEN2 = 1, /**< The Generation 2 Galileo platform (RevG/H) */ + INTEL_EDISON_FAB_C = 2, /**< The Intel Edison (FAB C) */ + INTEL_DE3815 = 3, /**< The Intel DE3815 Baytrail NUC */ + INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ + RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ + BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ + BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ + INTEL_NUC5 = 8, /**< The Intel 5th generations Broadwell NUCs */ + A96BOARDS = 9, /**< Linaro 96boards, A prefix for 'ARM' since not allowed numerical */ + INTEL_SOFIA_3GR = 10, /**< The Intel SoFIA 3GR */ + INTEL_CHERRYHILLS = 11, /**< The Intel Braswell Cherryhills */ + INTEL_UP = 12, /**< The UP Board */ + INTEL_GT_TUCHUCK = 13, /**< The Intel GT Board */ + + FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ + + GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + + NULL_PLATFORM = 98, + UNKNOWN_PLATFORM = + 99 /**< An unknown platform type, typically will load INTEL_GALILEO_GEN1 */ +} Platform; + +/** + * Intel edison miniboard numbering enum + */ +typedef enum { + INTEL_EDISON_MINIBOARD_J17_1 = 0, + INTEL_EDISON_MINIBOARD_J17_5 = 4, + INTEL_EDISON_MINIBOARD_J17_7 = 6, + INTEL_EDISON_MINIBOARD_J17_8 = 7, + INTEL_EDISON_MINIBOARD_J17_9 = 8, + INTEL_EDISON_MINIBOARD_J17_10 = 9, + INTEL_EDISON_MINIBOARD_J17_11 = 10, + INTEL_EDISON_MINIBOARD_J17_12 = 11, + INTEL_EDISON_MINIBOARD_J17_14 = 13, + INTEL_EDISON_MINIBOARD_J18_1 = 14, + INTEL_EDISON_MINIBOARD_J18_2 = 15, + INTEL_EDISON_MINIBOARD_J18_6 = 19, + INTEL_EDISON_MINIBOARD_J18_7 = 20, + INTEL_EDISON_MINIBOARD_J18_8 = 21, + INTEL_EDISON_MINIBOARD_J18_10 = 23, + INTEL_EDISON_MINIBOARD_J18_11 = 24, + INTEL_EDISON_MINIBOARD_J18_12 = 25, + INTEL_EDISON_MINIBOARD_J18_13 = 26, + INTEL_EDISON_MINIBOARD_J19_4 = 31, + INTEL_EDISON_MINIBOARD_J19_5 = 32, + INTEL_EDISON_MINIBOARD_J19_6 = 33, + INTEL_EDISON_MINIBOARD_J19_8 = 35, + INTEL_EDISON_MINIBOARD_J19_9 = 36, + INTEL_EDISON_MINIBOARD_J19_10 = 37, + INTEL_EDISON_MINIBOARD_J19_11 = 38, + INTEL_EDISON_MINIBOARD_J19_12 = 39, + INTEL_EDISON_MINIBOARD_J19_13 = 40, + INTEL_EDISON_MINIBOARD_J19_14 = 41, + INTEL_EDISON_MINIBOARD_J20_3 = 44, + INTEL_EDISON_MINIBOARD_J20_4 = 45, + INTEL_EDISON_MINIBOARD_J20_5 = 46, + INTEL_EDISON_MINIBOARD_J20_6 = 47, + INTEL_EDISON_MINIBOARD_J20_7 = 48, + INTEL_EDISON_MINIBOARD_J20_8 = 49, + INTEL_EDISON_MINIBOARD_J20_9 = 50, + INTEL_EDISON_MINIBOARD_J20_10 = 51, + INTEL_EDISON_MINIBOARD_J20_11 = 52, + INTEL_EDISON_MINIBOARD_J20_12 = 53, + INTEL_EDISON_MINIBOARD_J20_13 = 54, + INTEL_EDISON_MINIBOARD_J20_14 = 55 +} IntelEdisonMiniboard; + +/** + * Intel Edison raw GPIO numbering enum + */ +typedef enum { + INTEL_EDISON_GP182 = 0, + INTEL_EDISON_GP135 = 4, + INTEL_EDISON_GP27 = 6, + INTEL_EDISON_GP20 = 7, + INTEL_EDISON_GP28 = 8, + INTEL_EDISON_GP111 = 0, + INTEL_EDISON_GP109 = 10, + INTEL_EDISON_GP115 = 11, + INTEL_EDISON_GP128 = 13, + INTEL_EDISON_GP13 = 14, + INTEL_EDISON_GP165 = 15, + INTEL_EDISON_GP19 = 19, + INTEL_EDISON_GP12 = 20, + INTEL_EDISON_GP183 = 21, + INTEL_EDISON_GP110 = 23, + INTEL_EDISON_GP114 = 24, + INTEL_EDISON_GP129 = 25, + INTEL_EDISON_GP130 = 26, + INTEL_EDISON_GP44 = 31, + INTEL_EDISON_GP46 = 32, + INTEL_EDISON_GP48 = 33, + INTEL_EDISON_GP131 = 35, + INTEL_EDISON_GP14 = 36, + INTEL_EDISON_GP40 = 37, + INTEL_EDISON_GP43 = 38, + INTEL_EDISON_GP77 = 39, + INTEL_EDISON_GP82 = 40, + INTEL_EDISON_GP83 = 41, + INTEL_EDISON_GP134 = 44, + INTEL_EDISON_GP45 = 45, + INTEL_EDISON_GP47 = 46, + INTEL_EDISON_GP49 = 47, + INTEL_EDISON_GP15 = 48, + INTEL_EDISON_GP84 = 49, + INTEL_EDISON_GP42 = 50, + INTEL_EDISON_GP41 = 51, + INTEL_EDISON_GP78 = 52, + INTEL_EDISON_GP79 = 53, + INTEL_EDISON_GP80 = 54, + INTEL_EDISON_GP81 = 55 +} IntelEdison; + +/** +* Raspberry PI Wiring compatible numbering enum +*/ +typedef enum { + RASPBERRY_WIRING_PIN8 = 3, + RASPBERRY_WIRING_PIN9 = 5, + RASPBERRY_WIRING_PIN7 = 7, + RASPBERRY_WIRING_PIN15 = 8, + RASPBERRY_WIRING_PIN16 = 10, + RASPBERRY_WIRING_PIN0 = 11, + RASPBERRY_WIRING_PIN1 = 12, + RASPBERRY_WIRING_PIN2 = 13, + RASPBERRY_WIRING_PIN3 = 15, + RASPBERRY_WIRING_PIN4 = 16, + RASPBERRY_WIRING_PIN5 = 18, + RASPBERRY_WIRING_PIN12 = 19, + RASPBERRY_WIRING_PIN13 = 21, + RASPBERRY_WIRING_PIN6 = 22, + RASPBERRY_WIRING_PIN14 = 23, + RASPBERRY_WIRING_PIN10 = 24, + RASPBERRY_WIRING_PIN11 = 26, + RASPBERRY_WIRING_PIN17 = 29, // RPi B V2 + RASPBERRY_WIRING_PIN21 = 29, + RASPBERRY_WIRING_PIN18 = 30, // RPi B V2 + RASPBERRY_WIRING_PIN19 = 31, // RPI B V2 + RASPBERRY_WIRING_PIN22 = 31, + RASPBERRY_WIRING_PIN20 = 32, // RPi B V2 + RASPBERRY_WIRING_PIN26 = 32, + RASPBERRY_WIRING_PIN23 = 33, + RASPBERRY_WIRING_PIN24 = 35, + RASPBERRY_WIRING_PIN27 = 36, + RASPBERRY_WIRING_PIN25 = 37, + RASPBERRY_WIRING_PIN28 = 38, + RASPBERRY_WIRING_PIN29 = 40 +} RaspberryWiring; + +/** + * MRAA return codes + */ +typedef enum { + SUCCESS = 0, /**< Expected response */ + ERROR_FEATURE_NOT_IMPLEMENTED = 1, /**< Feature TODO */ + ERROR_FEATURE_NOT_SUPPORTED = 2, /**< Feature not supported by HW */ + ERROR_INVALID_VERBOSITY_LEVEL = 3, /**< Verbosity level wrong */ + ERROR_INVALID_PARAMETER = 4, /**< Parameter invalid */ + ERROR_INVALID_HANDLE = 5, /**< Handle invalid */ + ERROR_NO_RESOURCES = 6, /**< No resource of that type avail */ + ERROR_INVALID_RESOURCE = 7, /**< Resource invalid */ + ERROR_INVALID_QUEUE_TYPE = 8, /**< Queue type incorrect */ + ERROR_NO_DATA_AVAILABLE = 9, /**< No data available */ + ERROR_INVALID_PLATFORM = 10, /**< Platform not recognised */ + ERROR_PLATFORM_NOT_INITIALISED = 11, /**< Board information not initialised */ + ERROR_UART_OW_SHORTED = 12, /**< UART OW Short Circuit Detected*/ + ERROR_UART_OW_NO_DEVICES = 13, /**< UART OW No devices detected */ + ERROR_UART_OW_DATA_ERROR = 14, /**< UART OW Data/Bus error detected */ + + ERROR_UNSPECIFIED = 99 /**< Unknown Error */ +} Result; + +/** + * Enum representing different possible modes for a pin. + */ +typedef enum { + PIN_VALID = 0, /**< Pin Valid */ + PIN_GPIO = 1, /**< General Purpose IO */ + PIN_PWM = 2, /**< Pulse Width Modulation */ + PIN_FAST_GPIO = 3, /**< Faster GPIO */ + PIN_SPI = 4, /**< SPI */ + PIN_I2C = 5, /**< I2C */ + PIN_AIO = 6, /**< Analog in */ + PIN_UART = 7 /**< UART */ +} Pinmodes; + +/** + * Enum reprensenting different i2c speeds/modes + */ +typedef enum { + I2C_STD = 0, /**< up to 100Khz */ + I2C_FAST = 1, /**< up to 400Khz */ + I2C_HIGH = 2 /**< up to 3.4Mhz */ +} I2cMode; + +typedef enum { + UART_PARITY_NONE = 0, + UART_PARITY_EVEN = 1, + UART_PARITY_ODD = 2, + UART_PARITY_MARK = 3, + UART_PARITY_SPACE = 4 +} UartParity; + +} diff --git a/include/mraa/uart.h b/include/mraa/uart.h new file mode 100644 index 0000000..c6f5a7a --- /dev/null +++ b/include/mraa/uart.h @@ -0,0 +1,178 @@ +/* + * Author: Thomas Ingleby + * Contributions: Jon Trulson + * Brendan Le Foll + * Copyright (c) 2014 - 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief UART module + * + * UART is the Universal asynchronous receiver/transmitter interface to + * libmraa. It allows the exposure of UART pins on supported boards. + * With functionality to expand at a later date. + * + * @snippet uart.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "common.h" + +typedef struct _uart* mraa_uart_context; + +/** + * Initialise uart_context, uses board mapping + * + * @param uart the index of the uart set to use + * @return uart context or NULL + */ +mraa_uart_context mraa_uart_init(int uart); + +/** + * Initialise a raw uart_context. No board setup. + * + * @param path for example "/dev/ttyS0" + * @return uart context or NULL + */ +mraa_uart_context mraa_uart_init_raw(const char* path); + +/** + * Flush the outbound data. + * Blocks until complete. + * + * @param dev The UART context + * @return Result of operation + */ +mraa_result_t mraa_uart_flush(mraa_uart_context dev); + +/** + * Set the baudrate. + * Takes an int and will attempt to decide what baudrate is + * to be used on the UART hardware. + * + * @param dev The UART context + * @param baud unsigned int of baudrate i.e. 9600 + * @return Result of operation + */ +mraa_result_t mraa_uart_set_baudrate(mraa_uart_context dev, unsigned int baud); + +/** + * Set the transfer mode + * For example setting the mode to 8N1 would be + * "mraa_uart_set_mode(dev, 8,MRAA_UART_PARITY_NONE , 1)" + * + * @param dev The UART context + * @param bytesize data bits + * @param parity Parity bit setting + * @param stopbits stop bits + * @return Result of operation + */ +mraa_result_t mraa_uart_set_mode(mraa_uart_context dev, int bytesize, mraa_uart_parity_t parity, int stopbits); + +/** + * Set the flowcontrol + * + * @param dev The UART context + * @param xonxoff XON/XOFF Software flow control. + * @param rtscts RTS/CTS out of band hardware flow control + * @return Result of operation + */ +mraa_result_t mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_boolean_t rtscts); + +/** + * Set the timeout for read and write operations + * <= 0 will disable that timeout + * + * @param dev The UART context + * @param read read timeout + * @param write write timeout + * @param interchar inbetween char timeout + * @return Result of operation + */ +mraa_result_t mraa_uart_set_timeout(mraa_uart_context dev, int read, int write, int interchar); + +/** + * Set the blocking state for write operations + * + * @param dev The UART context + * @param nonblock new nonblocking state + * @return Result of operation + */ +mraa_result_t mraa_uart_set_non_blocking(mraa_uart_context dev, mraa_boolean_t nonblock); + +/** + * Get Char pointer with tty device path within Linux + * For example. Could point to "/dev/ttyS0" + * + * @param dev uart context + * @return char pointer of device path + */ +const char* mraa_uart_get_dev_path(mraa_uart_context dev); + +/** + * Destroy a mraa_uart_context + * + * @param dev uart context + * @return mraa_result_t + */ +mraa_result_t mraa_uart_stop(mraa_uart_context dev); + +/** + * Read bytes from the device into a buffer + * + * @param dev uart context + * @param buf buffer pointer + * @param length maximum size of buffer + * @return the number of bytes read, or -1 if an error occurred + */ +int mraa_uart_read(mraa_uart_context dev, char* buf, size_t length); + +/** + * Write bytes in buffer to a device + * + * @param dev uart context + * @param buf buffer pointer + * @param length maximum size of buffer + * @return the number of bytes written, or -1 if an error occurred + */ +int mraa_uart_write(mraa_uart_context dev, const char* buf, size_t length); + +/** + * Check to see if data is available on the device for reading + * + * @param dev uart context + * @param millis number of milliseconds to wait, or 0 to return immediately + * @return 1 if there is data available to read, 0 otherwise + */ +mraa_boolean_t mraa_uart_data_available(mraa_uart_context dev, unsigned int millis); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/uart.hpp b/include/mraa/uart.hpp new file mode 100644 index 0000000..0771fdc --- /dev/null +++ b/include/mraa/uart.hpp @@ -0,0 +1,274 @@ +/* + * Author: Brendan Le Foll + * Contributions: Jon Trulson + * Contributions: Thomas Ingleby + * Copyright (c) 2014 - 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "uart.h" +#include "types.hpp" +#include +#include +#include + +namespace mraa +{ + +/** + * @brief API to UART (enabling only) + * + * This file defines the UART interface for libmraa + * + * @snippet Uart-example.cpp Interesting + */ +class Uart +{ + public: + /** + * Uart Constructor, takes a pin number which will map directly to the + * linux uart number, this 'enables' the uart, nothing more + * + * @param uart the index of the uart set to use + */ + Uart(int uart) + { + m_uart = mraa_uart_init(uart); + + if (m_uart == NULL) { + throw std::invalid_argument("Error initialising UART"); + } + } + + /** + * Uart Constructor, takes a string to the path of the serial + * interface that is needed. + * + * @param uart the index of the uart set to use + */ + Uart(std::string path) + { + m_uart = mraa_uart_init_raw(path.c_str()); + + if (m_uart == NULL) { + throw std::invalid_argument("Error initialising UART"); + } + } + + /** + * Uart Constructor, takes a pointer to the UART context and initialises + * the UART class + * + * @param void * to a UART context + */ + Uart(void* uart_context) + { + m_uart = (mraa_uart_context) uart_context; + + if (m_uart == NULL) { + throw std::invalid_argument("Invalid UART context"); + } + } + /** + * Uart destructor + */ + ~Uart() + { + mraa_uart_stop(m_uart); + } + + /** + * Get string with tty device path within Linux + * For example. Could point to "/dev/ttyS0" + * + * @return char pointer of device path + */ + std::string + getDevicePath() + { + std::string ret_val(mraa_uart_get_dev_path(m_uart)); + return ret_val; + } + + /** + * Read bytes from the device into char* buffer + * + * @param data buffer pointer + * @param length maximum size of buffer + * @return numbers of bytes read + */ + int + read(char* data, int length) + { + return mraa_uart_read(m_uart, data, (size_t) length); + } + + /** + * Write bytes in String object to a device + * + * @param data buffer pointer + * @param length maximum size of buffer + * @return the number of bytes written, or -1 if an error occurred + */ + int + write(const char* data, int length) + { + return mraa_uart_write(m_uart, data, (size_t) length); + } + + /** + * Read bytes from the device into a String object + * + * @param length to read + * @throws std::bad_alloc If there is no space left for read. + * @return string of data + */ + std::string + readStr(int length) + { + char* data = (char*) malloc(sizeof(char) * length); + if (data == NULL) { + throw std::bad_alloc(); + } + + int v = mraa_uart_read(m_uart, data, (size_t) length); + std::string ret(data, v); + free(data); + return ret; + } + + /** + * Write bytes in String object to a device + * + * @param string to write + * @return the number of bytes written, or -1 if an error occurred + */ + int + writeStr(std::string data) + { + // this is data.length() not +1 because we want to avoid the '\0' char + return mraa_uart_write(m_uart, data.c_str(), (data.length())); + } + + /** + * Check to see if data is available on the device for reading + * + * @param millis number of milliseconds to wait, or 0 to return immediately + * @return true if there is data available to read, false otherwise + */ + bool + dataAvailable(unsigned int millis = 0) + { + if (mraa_uart_data_available(m_uart, millis)) + return true; + else + return false; + } + + /** + * Flush the outbound data. + * Blocks until complete. + * + * @return Result of operation + */ + Result + flush() + { + return (Result) mraa_uart_flush(m_uart); + } + + /** + * Set the baudrate. + * Takes an int and will attempt to decide what baudrate is + * to be used on the UART hardware. + * + * @param baud unsigned int of baudrate i.e. 9600 + * @return Result of operation + */ + Result + setBaudRate(unsigned int baud) + { + return (Result) mraa_uart_set_baudrate(m_uart, baud); + } + + /** + * Set the transfer mode + * For example setting the mode to 8N1 would be + * "dev.setMode(8,UART_PARITY_NONE , 1)" + * + * @param bytesize data bits + * @param parity Parity bit setting + * @param stopbits stop bits + * @return Result of operation + */ + Result + setMode(int bytesize, UartParity parity, int stopbits) + { + return (Result) mraa_uart_set_mode(m_uart, bytesize, (mraa_uart_parity_t) parity, stopbits); + } + + /** + * Set the flowcontrol + * + * @param xonxoff XON/XOFF Software flow control. + * @param rtscts RTS/CTS out of band hardware flow control + * @return Result of operation + */ + Result + setFlowcontrol(bool xonxoff, bool rtscts) + { + return (Result) mraa_uart_set_flowcontrol(m_uart, xonxoff, rtscts); + } + + /** + * Set the timeout for read and write operations + * <= 0 will disable that timeout + * + * @param read read timeout + * @param write write timeout + * @param interchar inbetween char timeout + * @return Result of operation + */ + Result + setTimeout(int read, int write, int interchar) + { + return (Result) mraa_uart_set_timeout(m_uart, read, write, interchar); + } + + /** + * Set the blocking state for write operations + * + * @param dev The UART context + * @param nonblock new nonblocking state + * @return Result of operation + */ + Result + SetNonBlocking(bool nonblock) + { + return (Result) mraa_uart_set_non_blocking(m_uart, nonblock); + } + + private: + mraa_uart_context m_uart; +}; +} diff --git a/include/mraa/uart_ow.h b/include/mraa/uart_ow.h new file mode 100644 index 0000000..7cd098f --- /dev/null +++ b/include/mraa/uart_ow.h @@ -0,0 +1,197 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * @file + * @brief UART OW module + * + * This module allows one to use MRAA's UART support in order to + * interact with Dallas 1-wire compliant devices on a 1-wire bus. It + * makes use of the UART for timing purposes. The principle of + * operation is described here: + * https://www.maximintegrated.com/en/app-notes/index.mvp/id/214 + * + * It is important the you use a UART with CMOS/TTL level voltages + * (3.3v/5v) RX and TX lines. DO NOT use standard RS232 level + * voltages, or you are going to have a bad day. + * + * In addition, a diode should be placed across the RX and + * TX lines like so: + * + * -| + * U| + * A| TX---|<--+ + * R| | + * T| RX-------o--------o 1-wire data bus + * -| + * + * The diode on TX is a 1N4148 (cheap and common), with the cathode + * connected to TX, and the anode connected to RX and the rest of the + * 1-wire data line. + * + * @snippet uart_ow.c Interesting + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "common.h" +#include "uart.h" + +/* for now, we simply use the normal MRAA UART context */ +typedef struct _mraa_uart_ow { + mraa_uart_context uart; + /* search state */ + unsigned char ROM_NO[8]; /* 8 byte (64b) rom code */ + int LastDiscrepancy; + int LastFamilyDiscrepancy; + mraa_boolean_t LastDeviceFlag; +} *mraa_uart_ow_context; + +/* 8 bytes (64 bits) for a device rom code */ +static const int MRAA_UART_OW_ROMCODE_SIZE = 8; + +/** + * UART One Wire ROM related Command bytes + */ +typedef enum { + MRAA_UART_OW_CMD_READ_ROM = 0x33, /**< read rom, when only one device on bus */ + MRAA_UART_OW_CMD_MATCH_ROM = 0x55, /**< match a specific rom code */ + MRAA_UART_OW_CMD_SKIP_ROM = 0xcc, /**< skip match/search rom */ + MRAA_UART_OW_CMD_SEARCH_ROM_ALARM = 0xec, /**< search all roms in alarm state */ + MRAA_UART_OW_CMD_SEARCH_ROM = 0xf0 /**< search all rom codes */ +} mraa_uart_ow_rom_cmd_t; + +/** + * Initialise uart_ow_context, uses UART board mapping + * + * @param uart the index of the uart set to use + * @return uart_ow context or NULL + */ +mraa_uart_ow_context mraa_uart_ow_init(int uart); + +/** + * Initialise a raw uart_ow_context. No board setup. + * + * @param path for example "/dev/ttyS0" + * @return uart_ow context or NULL + */ +mraa_uart_ow_context mraa_uart_ow_init_raw(const char* path); + +/** + * Get char pointer with tty device path within Linux + * For example. Could point to "/dev/ttyS0" + * + * @param dev uart_ow context + * @return char pointer of device path + */ +const char* mraa_uart_ow_get_dev_path(mraa_uart_ow_context dev); + +/** + * Destroy a mraa_uart_ow_context + * + * @param dev uart_ow context + * @return mraa_result_t + */ +mraa_result_t mraa_uart_ow_stop(mraa_uart_ow_context dev); + +/** + * Read a byte from the 1-wire bus + * + * @param dev uart_ow context + * @return the byte read or -1 for error + */ +int mraa_uart_ow_read_byte(mraa_uart_ow_context dev); + +/** + * Write a byte to a 1-wire bus + * + * @param dev uart_ow context + * @param byte the byte to write to the bus + * @return the byte read back during the time slot or -1 for error + */ +int mraa_uart_ow_write_byte(mraa_uart_ow_context dev, uint8_t byte); + +/** + * Write a bit to a 1-wire bus and read a bit corresponding to the + * time slot back. This is possible due to the way we wired the TX + * and RX together with a diode, forming a loopback. + * + * @param dev uart_ow context + * @param bit the bit to write to the bus + * @return the bit read back during the time slot or -1 for error + */ +int mraa_uart_ow_bit(mraa_uart_ow_context dev, uint8_t bit); + +/** + * Send a reset pulse to the 1-wire bus and test for device presence + * + * @param dev uart_ow context + * @return one of the mraa_result_t values + */ +mraa_result_t mraa_uart_ow_reset(mraa_uart_ow_context dev); + +/** + * Begin a rom code search of the 1-wire bus. This function + * implements the 1-wire search algorithm. See the uart_ow.c example + * for an idea on how to use this function to identify all devices + * present on the bus. + * + * @param dev uart_ow context + * @param start true to start a new search from scratch, false to + * continue an existing search + * @param id the 8-byte rom code id of the current matched device when + * a device is found + * @return one of the mraa_result_t values + */ +mraa_result_t mraa_uart_ow_rom_search(mraa_uart_ow_context dev, mraa_boolean_t start, uint8_t* id); + +/** + * Send a command byte to a device on the 1-wire bus + * + * @param dev uart_ow context + * @param command the command byte to send + * @param id the rom code id of the device to receive the command, + * NULL for all devices on the bus + * @return one of the mraa_result_t values + */ +mraa_result_t mraa_uart_ow_command(mraa_uart_ow_context dev, uint8_t command, uint8_t* id); + +/** + * Perform a Dallas 1-wire compliant CRC8 computation on a buffer + * + * @param buffer the buffer containing the data + * @param length the length of the buffer + * @return the computed CRC + */ +uint8_t mraa_uart_ow_crc8(uint8_t* buffer, uint16_t length); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa/uart_ow.hpp b/include/mraa/uart_ow.hpp new file mode 100644 index 0000000..d20f87e --- /dev/null +++ b/include/mraa/uart_ow.hpp @@ -0,0 +1,277 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "uart_ow.h" +#include "types.hpp" +#include +#include + +namespace mraa +{ + +/** + * @brief API for UART One Wire + * + * This file defines the UartOW (UART to Dallas 1-wire) interface for libmraa + * + * @snippet UartOW.cpp Interesting + */ +class UartOW +{ + public: + /** + * UartOW Constructor, takes a pin number which will map directly to the + * linux uart number, this 'enables' the uart, nothing more + * + * @throws std::invalid_argument in case of error + * @param uart the index of the uart to use + */ + UartOW(int uart) + { + m_uart = mraa_uart_ow_init(uart); + + if (m_uart == NULL) { + throw std::invalid_argument("Error initialising UART_OW"); + } + } + + /** + * UartOW Constructor, takes a string to the path of the serial + * interface that is needed. + * + * @throws std::invalid_argument in case of error + * @param path the file path for the UART to use + */ + UartOW(std::string path) + { + m_uart = mraa_uart_ow_init_raw(path.c_str()); + + if (m_uart == NULL) { + throw std::invalid_argument("Error initialising UART"); + } + } + + /** + * Uart destructor + */ + ~UartOW() + { + mraa_uart_ow_stop(m_uart); + } + + /** + * Get string with tty device path within Linux + * For example. Could point to "/dev/ttyS0" + * + * @return char pointer of device path + */ + std::string + getDevicePath() + { + std::string ret_val(mraa_uart_ow_get_dev_path(m_uart)); + return ret_val; + } + + /** + * Read a byte from the 1-wire bus + * + * @throws std::invalid_argument in case of error + * @return the byte read + */ + uint8_t + readByte() + { + int res = mraa_uart_ow_read_byte(m_uart); + if (res == -1) { + throw std::invalid_argument("Unknown UART_OW error"); + } + return (uint8_t) res; + } + + /** + * Write a byte to a 1-wire bus + * + * @param byte the byte to write to the bus + * + * @throws std::invalid_argument in case of error + * @return the byte read back during the time slot + */ + uint8_t + writeByte(uint8_t byte) + { + int res = mraa_uart_ow_write_byte(m_uart, byte); + if (res == -1) { + throw std::invalid_argument("Unknown UART_OW error"); + } + return (uint8_t) res; + } + + /** + * Write a bit to a 1-wire bus and read a bit corresponding to the + * time slot back. This is possible due to the way we wired the TX + * and RX together with a diode, forming a loopback. + * + * @param bit the bit to write to the bus + * @throws std::invalid_argument in case of error + * @return the bit read back during the time slot + */ + bool + writeBit(bool bit) + { + int res = mraa_uart_ow_bit(m_uart, (bit) ? 1 : 0); + if (res == -1) { + throw std::invalid_argument("Unknown UART_OW error"); + } + return ((res) ? true : false); + } + + /** + * Send a reset pulse to the 1-wire bus and test for device presence + * + * @return one of the mraa::Result values + */ + mraa::Result + reset() + { + return (mraa::Result) mraa_uart_ow_reset(m_uart); + } + + /** + * Begin a rom code search of the 1-wire bus. This function + * implements the 1-wire search algorithm. See the uart_ow.c example + * for an idea on how to use this function to identify all devices + * present on the bus. + * + * @param start true to start a search from scratch, false to + * continue a previously started search + * @param id the 8-byte rom code id of the current matched device when a + * device is found + * @return one of the mraa::Result values + */ + mraa::Result + search(bool start, uint8_t* id) + { + return (mraa::Result) mraa_uart_ow_rom_search(m_uart, (start) ? 1 : 0, id); + } + + /** + * Begin a rom code search of the 1-wire bus. This function + * implements the 1-wire search algorithm. See the UartOW.cpp + * example for an idea on how to use this function to identify all + * devices present on the bus. + * + * @param start true to start a search from scratch, false to + * continue a previously started search + * @return an empty string if no [more] devices are found, or a + * string containing the 8-byte romcode of a detected device. + */ + std::string + search(bool start) + { + uint8_t id[MRAA_UART_OW_ROMCODE_SIZE]; + mraa_result_t rv; + + rv = mraa_uart_ow_rom_search(m_uart, (start) ? 1 : 0, id); + + if (rv == MRAA_SUCCESS) { + // we found one + std::string idStr((char*) id, MRAA_UART_OW_ROMCODE_SIZE); + return idStr; + } else { + // failure, or end of search + return ""; + } + } + + /** + * Send a command byte to a device on the 1-wire bus + * + * @param command the command byte to send + * @param id the rom code id of the device to receive the command, + * NULL for all devices on the bus + * @return one of the mraa::Result values + */ + mraa::Result + command(uint8_t command, uint8_t* id) + { + return (mraa::Result) mraa_uart_ow_command(m_uart, command, id); + } + + /** + * Send a command byte to a device on the 1-wire bus, supplying + * the id as a std::string + * + * @param command the command byte to send + * @param id std::string representing the code id of the device to + * receive the command, or an empty string for all devices on the + * bus. This string should be 8 bytes in size. + * @return one of the mraa::Result values + */ + mraa::Result + command(uint8_t command, std::string id) + { + if (id.empty() == 0) + return (mraa::Result) mraa_uart_ow_command(m_uart, command, NULL); + else { + if (id.size() != 8) { + // Only 8 byte romcodes are legal. + throw std::invalid_argument(std::string(__FUNCTION__) + + ": id must be 8 bytes only"); + } + return (mraa::Result) mraa_uart_ow_command(m_uart, command, (uint8_t*) id.c_str()); + } + } + + /** + * Perform a Dallas 1-wire compliant CRC8 computation on a buffer + * + * @param buffer the buffer containing the data + * @param length the length of the buffer + * @return the computed CRC + */ + uint8_t + crc8(uint8_t* buffer, uint16_t length) + { + return mraa_uart_ow_crc8(buffer, length); + } + + /** + * Perform a Dallas 1-wire compliant CRC8 computation on a + * std::string based buffer + * + * @param buffer std::string buffer containing the data + * @return the computed CRC + */ + uint8_t + crc8(std::string buffer) + { + return mraa_uart_ow_crc8((uint8_t*) buffer.c_str(), buffer.size()); + } + + private: + mraa_uart_ow_context m_uart; +}; +} diff --git a/include/wiringPi/wiringPi.h b/include/wiringPi/wiringPi.h new file mode 100644 index 0000000..f601f13 --- /dev/null +++ b/include/wiringPi/wiringPi.h @@ -0,0 +1,254 @@ +/* + * wiringPi.h: + * Arduino like Wiring library for the Raspberry Pi. + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifndef __WIRING_PI_H__ +#define __WIRING_PI_H__ + +// C doesn't have true/false by default and I can never remember which +// way round they are, so ... +// (and yes, I know about stdbool.h but I like capitals for these and I'm old) + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + +// GCC warning suppressor + +#define UNU __attribute__((unused)) + +// Mask for the bottom 64 pins which belong to the Raspberry Pi +// The others are available for the other devices + +#define PI_GPIO_MASK (0xFFFFFFC0) + +// Handy defines + +// wiringPi modes + +#define WPI_MODE_PINS 0 +#define WPI_MODE_GPIO 1 +#define WPI_MODE_GPIO_SYS 2 +#define WPI_MODE_PHYS 3 +#define WPI_MODE_PIFACE 4 +#define WPI_MODE_UNINITIALISED -1 + +// Pin modes + +#define INPUT 0 +#define OUTPUT 1 +#define PWM_OUTPUT 2 +#define GPIO_CLOCK 3 +#define SOFT_PWM_OUTPUT 4 +#define SOFT_TONE_OUTPUT 5 +#define PWM_TONE_OUTPUT 6 + +#define LOW 0 +#define HIGH 1 + +// Pull up/down/none + +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +// PWM + +#define PWM_MODE_MS 0 +#define PWM_MODE_BAL 1 + +// Interrupt levels + +#define INT_EDGE_SETUP 0 +#define INT_EDGE_FALLING 1 +#define INT_EDGE_RISING 2 +#define INT_EDGE_BOTH 3 + +// Pi model types and version numbers +// Intended for the GPIO program Use at your own risk. + +#define PI_MODEL_A 0 +#define PI_MODEL_B 1 +#define PI_MODEL_AP 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_2 4 +#define PI_ALPHA 5 +#define PI_MODEL_CM 6 +#define PI_MODEL_07 7 +#define PI_MODEL_3 8 +#define PI_MODEL_ZERO 9 +#define PI_MODEL_CM3 10 +#define PI_MODEL_ZERO_W 12 + +#define PI_VERSION_1 0 +#define PI_VERSION_1_1 1 +#define PI_VERSION_1_2 2 +#define PI_VERSION_2 3 + +#define PI_MAKER_SONY 0 +#define PI_MAKER_EGOMAN 1 +#define PI_MAKER_EMBEST 2 +#define PI_MAKER_UNKNOWN 3 + +extern const char *piModelNames [16] ; +extern const char *piRevisionNames [16] ; +extern const char *piMakerNames [16] ; +extern const int piMemorySize [ 8] ; + + +// Intended for the GPIO program Use at your own risk. + +// Threads + +#define PI_THREAD(X) void *X (UNU void *dummy) + +// Failure modes + +#define WPI_FATAL (1==1) +#define WPI_ALMOST (1==2) + + +// wiringPiNodeStruct: +// This describes additional device nodes in the extended wiringPi +// 2.0 scheme of things. +// It's a simple linked list for now, but will hopefully migrate to +// a binary tree for efficiency reasons - but then again, the chances +// of more than 1 or 2 devices being added are fairly slim, so who +// knows.... + +struct wiringPiNodeStruct +{ + int pinBase ; + int pinMax ; + + int fd ; // Node specific + unsigned int data0 ; // ditto + unsigned int data1 ; // ditto + unsigned int data2 ; // ditto + unsigned int data3 ; // ditto + + void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ; + void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ; + int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ; +//unsigned int (*digitalRead8) (struct wiringPiNodeStruct *node, int pin) ; + void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; +// void (*digitalWrite8) (struct wiringPiNodeStruct *node, int pin, int value) ; + void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; + void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + + struct wiringPiNodeStruct *next ; +} ; + +extern struct wiringPiNodeStruct *wiringPiNodes ; + + +// Function prototypes +// c++ wrappers thanks to a comment by Nick Lott +// (and others on the Raspberry Pi forums) + +#ifdef __cplusplus +extern "C" { +#endif + +// Data + +// Internal + +extern int wiringPiFailure (int fatal, const char *message, ...) ; + +// Core wiringPi functions + +extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; +extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; + +extern void wiringPiVersion (int *major, int *minor) ; +extern int wiringPiSetup (void) ; +extern int wiringPiSetupSys (void) ; +extern int wiringPiSetupGpio (void) ; +extern int wiringPiSetupPhys (void) ; + +extern void pinModeAlt (int pin, int mode) ; +extern void pinMode (int pin, int mode) ; +extern void pullUpDnControl (int pin, int pud) ; +extern int digitalRead (int pin) ; +extern void digitalWrite (int pin, int value) ; +extern unsigned int digitalRead8 (int pin) ; +extern void digitalWrite8 (int pin, int value) ; +extern void pwmWrite (int pin, int value) ; +extern int analogRead (int pin) ; +extern void analogWrite (int pin, int value) ; + +// PiFace specifics +// (Deprecated) + +extern int wiringPiSetupPiFace (void) ; +extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only + +// On-Board Raspberry Pi hardware specific stuff + +extern int piGpioLayout (void) ; +extern int piBoardRev (void) ; // Deprecated +extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; +extern int wpiPinToGpio (int wpiPin) ; +extern int physPinToGpio (int physPin) ; +extern void setPadDrive (int group, int value) ; +extern int getAlt (int pin) ; +extern void pwmToneWrite (int pin, int freq) ; +extern void pwmSetMode (int mode) ; +extern void pwmSetRange (unsigned int range) ; +extern void pwmSetClock (int divisor) ; +extern void gpioClockSet (int pin, int freq) ; +extern unsigned int digitalReadByte (void) ; +extern unsigned int digitalReadByte2 (void) ; +extern void digitalWriteByte (int value) ; +extern void digitalWriteByte2 (int value) ; + +// Interrupts +// (Also Pi hardware specific) + +extern int waitForInterrupt (int pin, int mS) ; +extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; + +// Threads + +extern int piThreadCreate (void *(*fn)(void *)) ; +extern void piLock (int key) ; +extern void piUnlock (int key) ; + +// Schedulling priority + +extern int piHiPri (const int pri) ; + +// Extras from arduino land + +extern void delay (unsigned int howLong) ; +extern void delayMicroseconds (unsigned int howLong) ; +extern unsigned int millis (void) ; +extern unsigned int micros (void) ; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/wiringPi/wiringPiI2C.h b/include/wiringPi/wiringPiI2C.h new file mode 100644 index 0000000..6db8c68 --- /dev/null +++ b/include/wiringPi/wiringPiI2C.h @@ -0,0 +1,42 @@ +/* + * wiringPiI2C.h: + * Simplified I2C access routines + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int wiringPiI2CRead (int fd) ; +extern int wiringPiI2CReadReg8 (int fd, int reg) ; +extern int wiringPiI2CReadReg16 (int fd, int reg) ; + +extern int wiringPiI2CWrite (int fd, int data) ; +extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; +extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ; + +extern int wiringPiI2CSetupInterface (const char *device, int devId) ; +extern int wiringPiI2CSetup (const int devId) ; + +#ifdef __cplusplus +} +#endif diff --git a/include/wiringPi/wiringPiSPI.h b/include/wiringPi/wiringPiSPI.h new file mode 100644 index 0000000..3980321 --- /dev/null +++ b/include/wiringPi/wiringPiSPI.h @@ -0,0 +1,36 @@ +/* + * wiringPiSPI.h: + * Simplified SPI access routines + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +int wiringPiSPIGetFd (int channel) ; +int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; +int wiringPiSPISetupMode (int channel, int speed, int mode) ; +int wiringPiSPISetup (int channel, int speed) ; + +#ifdef __cplusplus +} +#endif diff --git a/include/wiringPi/wiringSerial.h b/include/wiringPi/wiringSerial.h new file mode 100644 index 0000000..430dc73 --- /dev/null +++ b/include/wiringPi/wiringSerial.h @@ -0,0 +1,38 @@ +/* + * wiringSerial.h: + * Handle a serial port + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int serialOpen (const char *device, const int baud) ; +extern void serialClose (const int fd) ; +extern void serialFlush (const int fd) ; +extern void serialPutchar (const int fd, const unsigned char c) ; +extern void serialPuts (const int fd, const char *s) ; +extern void serialPrintf (const int fd, const char *message, ...) ; +extern int serialDataAvail (const int fd) ; +extern int serialGetchar (const int fd) ; + +#ifdef __cplusplus +} +#endif diff --git a/include/wiringPi/wiringShift.h b/include/wiringPi/wiringShift.h new file mode 100644 index 0000000..419ade4 --- /dev/null +++ b/include/wiringPi/wiringShift.h @@ -0,0 +1,41 @@ +/* + * wiringShift.h: + * Emulate some of the Arduino wiring functionality. + * + * Copyright (c) 2009-2012 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#ifndef _STDINT_H +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; +extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; + +#ifdef __cplusplus +} +#endif diff --git a/src/AnalogIn.cpp b/src/AnalogIn.cpp new file mode 100644 index 0000000..7fbee89 --- /dev/null +++ b/src/AnalogIn.cpp @@ -0,0 +1,110 @@ +/* + * AnalogIn.cpp + * + * Created on: Jun 27, 2017 + * Author: patrickjmcd + */ + +#include "AnalogIn.h" + +AnalogIn::AnalogIn(int channel, double rawMin, double rawMax, double euMin, double euMax) { + // TODO Auto-generated constructor stub + this->channel = channel; + if (channel != 99){ + channelMux[0] = MUX_VALUES[channel][0]; + channelMux[1] = MUX_VALUES[channel][1]; + channelMux[2] = MUX_VALUES[channel][2]; + } + badReads = 0; + this->rawMax = rawMax; + this->rawMin = rawMin; + this->euMax = euMax; + this->euMin = euMin; + + lastValue = 0; + rawValue = 0; + + + m = (euMax - euMin) / (rawMax - rawMin); + b = euMax - m * (rawMax); +} +void shiftright (double myarray[], int size) +{ + double temp; + + for (int i=0; i<(size -1); i++) + { + temp = myarray[size-1]; + myarray[size-1] = myarray[i]; + myarray[i] = temp; + } +} + +double AnalogIn::getHistory(int index){ + return history[index]; +} + +double AnalogIn::getLastValue(){ + return lastValue; +} + +int AnalogIn::getRawValue(){ + return rawValue; +} + +long AnalogIn::getBadReads(){ + return badReads; +} + +double AnalogIn::setValue(int value){ + rawValue = value; + double pv = m * rawValue + b; + lastValue = pv; + //TODO: lastStored = Instant.now(); + shiftright(history, 100); + history[0] = lastValue; + return pv; +} + +double AnalogIn::read(MuxSetup *mux){ + mux->set(channelMux[0], channelMux[1], channelMux[2]); + int rawIn = mux->readAnalog(); + if (rawIn != -1){ + badReads = 0; + return setValue(rawIn); + } else { + badReads++; + } + if (badReads > 10){ + std::cout <<"Too many bad reads" << std::endl; + +// mux->preAnalogWrite(); +// mux->postAnalogWrite(); + } + return lastValue; + +} + +AnalogIn::~AnalogIn() { + // TODO Auto-generated destructor stub +} + +int main(){ + MuxSetup mux; + double a1val, a2val; + + AnalogIn aI1(1, 32560, 65535, 0, 100); + AnalogIn aI2(2, 0, 65535, 0, 50000); + + for(int i = 0; i< 50; i++){ + a1val = aI1.read(&mux); + a2val = aI2.read(&mux); + + std::cout << "Input 1: " << a1val << ", badReads: " << aI1.getBadReads() << std::endl; + std::cout << "Input 2: " << a2val << ", badReads: " << aI2.getBadReads() << std::endl; + std::cout << "--" << std::endl; + } + + return 1; +} + diff --git a/src/AnalogIn.h b/src/AnalogIn.h new file mode 100644 index 0000000..5424563 --- /dev/null +++ b/src/AnalogIn.h @@ -0,0 +1,38 @@ +/* + * AnalogIn.h + * + * Created on: Jun 27, 2017 + * Author: patrickjmcd + */ + +#ifndef ANALOGIN_H_ +#define ANALOGIN_H_ + +#include "MuxSetup.h" +#include +#include + +class AnalogIn { +public: + AnalogIn(int ch, double rawMinI, double rawMaxI, double euMinI, double euMaxI); + int getRawValue(); + double getLastValue(); + long getBadReads(); + double getHistory(int index); + double setValue(int value); + double read(MuxSetup *mux); + double readSim(double simRaw); + virtual ~AnalogIn(); + +private: + int channel; + int rawValue; + double lastValue; + double rawMin, rawMax, euMin, euMax; + double m, b; + int channelMux[3]; + double history[100]; + long badReads; +}; + +#endif /* ANALOGIN_H_ */ diff --git a/src/Card.cpp b/src/Card.cpp new file mode 100644 index 0000000..3d1f52b --- /dev/null +++ b/src/Card.cpp @@ -0,0 +1,529 @@ +/* + * Card.cpp + * + * Created on: Jul 3, 2017 + * Author: patrickjmcd + */ + +#include "Card.h" + +template void printElement(T t, const int& width) +{ + const char separator = ' '; + std::cout << std::left << std::setw(width) << std::setfill(separator) << t; +}; + +Card::Card(): surfacePositionMax(0, 0), surfacePositionMin(0, 0),surfaceLoadMax(0,0), surfaceLoadMin(0,0), downholePositionMax(0,0), downholePositionMin(0, 0), downholeLoadMax(0,0), downholeLoadMin(0,0), topCorner(0,0), bottomCorner(0,0) { + strokeNumber = 0; + + // Initializations + surfaceStrokeLength = -1; + downholeNetStrokeLength = -1; + downholeGrossStrokeLength = -1; + downholeAdjustedGrossStrokeLength = -1; + downholeLoadSpan = -1; + fluidLoad = -1; + pumpIntakePressure = -1; + fluidLevel = -1; + fillageEstimated = -1; + fillageCalculated = -1; + tubingMovement = -1; + strokeSpeed = -1; + + structuralLoading = -1; + + polishedRodHorsepower = -1; + pumpHorsepower = -1; + fluidBblMoved = -1; + fluidBblMovedAdjusted = -1; + waterBblMoved = -1; + oilBblMoved = -1; + gasMcfMoved = -1; + numPointsUsed = 0; + + + strokeStartTime = std::chrono::duration_cast< std::chrono::milliseconds >( + std::chrono::system_clock::now().time_since_epoch() + ); + +} + +Card::Card(long strokeNumber): surfacePositionMax(0, 0), surfacePositionMin(0, 0),surfaceLoadMax(0,0), surfaceLoadMin(0,0), downholePositionMax(0,0), downholePositionMin(0, 0), downholeLoadMax(0,0), downholeLoadMin(0,0), topCorner(0,0), bottomCorner(0,0) { + this->strokeNumber = strokeNumber; + + // Initializations + surfaceStrokeLength = -1; + downholeNetStrokeLength = -1; + downholeGrossStrokeLength = -1; + downholeAdjustedGrossStrokeLength = -1; + downholeLoadSpan = -1; + fluidLoad = -1; + pumpIntakePressure = -1; + fluidLevel = -1; + fillageEstimated = -1; + fillageCalculated = -1; + tubingMovement = -1; + strokeSpeed = -1; + + structuralLoading = -1; + + polishedRodHorsepower = -1; + pumpHorsepower = -1; + fluidBblMoved = -1; + fluidBblMovedAdjusted = -1; + waterBblMoved = -1; + oilBblMoved = -1; + gasMcfMoved = -1; + numPointsUsed = 0; + + + strokeStartTime = std::chrono::duration_cast< std::chrono::milliseconds >( + std::chrono::system_clock::now().time_since_epoch() + ); + +} + +// Public Functions + +void Card::setSurfacePosition(int i, double position){ + surfacePosition[i] = position; +} + +void Card::setDownholePosition(int i, double position){ + downholePosition[i] = position; +} + +void Card::setSurfaceLoad(int i, double load){ + surfaceLoad[i] = load; +} + +void Card::setDownholeLoad(int i, double load){ + downholeLoad[i] = load; +} + +LPPair Card::getSurfacePositionMax(){ + return surfacePositionMax; +} + +LPPair Card::getSurfaceLoadMax(){ + return surfaceLoadMax; +} + +LPPair Card::getSurfacePositionMin(){ + return surfacePositionMin; +} + +LPPair Card::getSurfaceLoadMin(){ + return surfaceLoadMin; +} + +LPPair Card::getDownholePositionMax(){ + return downholePositionMax; +} + +LPPair Card::getDownholeLoadMax(){ + return downholeLoadMax; +} + +LPPair Card::getDownholePositionMin(){ + return downholePositionMin; +} + +LPPair Card::getDownholeLoadMin(){ + return downholeLoadMin; +} + +long Card::getStrokeNumber(){ + return strokeNumber; +} + +double Card::getSurfaceStrokeLength(){ + return surfaceStrokeLength; +} + +double Card::getDownholeNetStrokeLength(){ + return downholeNetStrokeLength; +} + +double Card::getDownholeGrossStrokeLength(){ + return downholeGrossStrokeLength; +} + +double Card:: getDownholeAdjustedGrossStrokeLength(){ + return downholeAdjustedGrossStrokeLength; +} + +double Card::getDownholeLoadSpan(){ + return downholeLoadSpan; +} + +double Card::getFluidLoad(){ + return fluidLoad; +} + +double Card::getFillageEstimated(){ + return fillageEstimated; +} + +double Card::getFillageCalculated(){ + return fillageCalculated; +} + +double Card::getTubingMovement(){ + return tubingMovement; +} + +double Card::getStructuralLoading(){ + return structuralLoading; +} + +double Card::getPumpIntakePressure(){ + return pumpIntakePressure; +} + +double Card::getFluidLevel(){ + return fluidLevel; +} + +double Card::getStrokeSpeed(){ + return strokeSpeed; +} + +double Card::getPolishedRodHorsepower(){ + return polishedRodHorsepower; +} + +double Card::getPumpHorsepower(){ + return pumpHorsepower; +} + +double Card::getFluidBblMoved(){ + return fluidBblMoved; +} + +double Card::getFluidBblMovedAdjusted(){ + return fluidBblMovedAdjusted; +} + +double Card::getWaterBblMoved(){ + return waterBblMoved; +} + +double Card::getOilBblMoved(){ + return oilBblMoved; +} + +double Card::getGasMcfMoved(){ + return gasMcfMoved; +} + +int Card::getNumPointsUsed(){ + return numPointsUsed; +} + +void Card::setNumPointsUsed(int i){ + numPointsUsed = i; +} + +void Card::printCard(std::string cardPrintType, bool printDataToo) +{ + const int posLength = 10; + const int lodLength = 12; + if(cardPrintType.compare("csv") == 0){ + std::cout << "=== CARD " << strokeNumber << " ===" << std::endl; + std::cout << "Surf Pos,Surf Load,DH Pos,DH Load" << std::endl; + } else if (cardPrintType.compare("table") == 0) { + std::cout << "=== CARD " << strokeNumber << " ===" << std::endl; + printElement("Surf Pos", posLength); + printElement("Surf Load", lodLength); + printElement("DH Pos", posLength); + printElement("DH Load", lodLength); + std::cout << std::endl; + } + + for(int i = 0; i < numPointsUsed; i++) + { + if(cardPrintType.compare("csv") == 0){ + std::cout << surfacePosition[i] << ","; + std::cout << surfaceLoad[i] << ","; + std::cout << downholePosition[i] << ","; + std::cout << downholeLoad[i]; + std::cout << std::endl; + } else if (cardPrintType.compare("table") == 0) { + printElement(surfacePosition[i], posLength); + printElement(surfaceLoad[i], lodLength); + printElement(downholePosition[i], posLength); + printElement(downholeLoad[i], lodLength); + std::cout << std::endl; + } + } + + + const int labelLength = 22; + const int measLength = 15; + if(printDataToo){ + std::cout << std::endl; + std::cout << "=== CARD DATA " << strokeNumber << " ===" << std::endl; + printElement("Fillage (Est.)", labelLength); + printElement(fillageEstimated, measLength); + std::cout << std::endl; + + printElement("Fillage (Calc.)", labelLength); + printElement(fillageCalculated, measLength); + std::cout << std::endl; + + // printElement("Top Corner", labelLength); + // printElement(topCorner.position, measLength); + // printElement(topCorner.load, measLength); + // std::cout << std::endl; + // + // printElement("Bottom Corner", labelLength); + // printElement(bottomCorner.position, measLength); + // printElement(bottomCorner.load, measLength); + // std::cout << std::endl; + + + printElement("Fluid Load", labelLength); + printElement(fluidLoad, measLength); + std::cout << std::endl; + + printElement("Pump Intake Pressure", labelLength); + printElement(pumpIntakePressure, measLength); + std::cout << std::endl; + + printElement("Fluid Level", labelLength); + printElement(fluidLevel, measLength); + std::cout << std::endl; + + printElement("Surf. Stroke Length", labelLength); + printElement(surfaceStrokeLength, measLength); + std::cout << std::endl; + + printElement("Down. Gross Stroke", labelLength); + printElement(downholeGrossStrokeLength, measLength); + std::cout << std::endl; + + printElement("Down. Net Stroke", labelLength); + printElement(downholeNetStrokeLength, measLength); + std::cout << std::endl; + + printElement("Polished Rod HP", labelLength); + printElement(polishedRodHorsepower, measLength); + std::cout << std::endl; + + printElement("Pump HP", labelLength); + printElement(pumpHorsepower, measLength); + std::cout << std::endl; + } +} + + +// PRIVATE FUNCTIONS +double Card::lineResolve(double x1, double x2, double y1, double y2, double xTest){ + double line_m = (y2 - y1) / (x2 - x1); + double line_b = y1 - line_m * x1; + double yTest = line_m * xTest + line_b; + return yTest; +} + +LPPair Card::positionMax(double* positionArr, double* loadArr, int arrSize){ + double maxPos = positionArr[0]; + double loadAtMaxP = -__DBL_MAX__; + + for(int i = 0; i < arrSize; i++) { + maxPos = std::max(maxPos, positionArr[i]); + if (maxPos == positionArr[i]) loadAtMaxP = loadArr[i]; + } + LPPair foundPoint(maxPos, loadAtMaxP); + return foundPoint; +} + + +LPPair Card::positionMin(double* positionArr, double* loadArr, int arrSize){ + double minPosition = positionArr[0]; + double loadAtMinP = __DBL_MAX__; + + for(int i = 0; i < arrSize; i++) { + minPosition = std::min(minPosition, positionArr[i]); + if (minPosition == positionArr[i]) loadAtMinP = loadArr[i]; + } + LPPair foundPoint(minPosition, loadAtMinP); + return foundPoint; +} + +LPPair Card::loadMax(double* positionArr, double* loadArr, int arrSize){ + double maxLoad = loadArr[0]; + double posAtMaxL = -__DBL_MAX__; + + for(int i = 0; i < arrSize; i++) { + maxLoad = std::max(maxLoad, loadArr[i]); + if (maxLoad == positionArr[i]) posAtMaxL = positionArr[i]; + } + LPPair foundPoint(posAtMaxL, maxLoad); + return foundPoint; +} + +LPPair Card::loadMin(double* positionArr, double* loadArr, int arrSize){ + double minLoad = loadArr[0]; + double posAtMinL = __DBL_MAX__; + + for(int i = 0; i < arrSize; i++) { + minLoad = std::min(minLoad, loadArr[i]); + if (minLoad == positionArr[i]) posAtMinL = positionArr[i]; + } + LPPair foundPoint(posAtMinL, minLoad); + return foundPoint; +} + +double Card::distanceToLine(double pos, double load){ + double x1 = downholePositionMin.getPosition(); + double x2 = downholePositionMax.getPosition(); + double y1 = downholeLoadMin.getLoad(); + double y2 = downholeLoadMax.getLoad(); + + return std::abs((y2-y1)*pos - (x2-x1)*load + x2*y1 - y2*x1) / sqrt(pow(y2-y1, 2) + pow(x2-x1,2)); +} + + +void Card::calculateSpm(){ + std::chrono::milliseconds now = std::chrono::duration_cast< std::chrono::milliseconds >( + std::chrono::system_clock::now().time_since_epoch() + ); +// std::chrono::milliseconds strokeMillis = now - strokeStartTime; + strokeSpeed = 60000.0 / (double)(now.count() - strokeStartTime.count()); +} + +void Card::calcStrokeData(int numSlices, double fluidGradient, double rodDepth, double anchorDepth, double tubingCSA, double pumpArea, double frictionEstimate, double structuralRating, double kFactor, double waterBBLRatio, double oilBBLRatio, double gasMCFRatio){ + + calculateSpm(); + surfacePositionMax = positionMax(surfacePosition, surfaceLoad, numPointsUsed); + surfaceLoadMax = loadMax(surfacePosition, surfaceLoad, numPointsUsed); + surfacePositionMin = positionMin(surfacePosition, surfaceLoad, numPointsUsed); + surfaceLoadMin = loadMin(surfacePosition, surfaceLoad, numPointsUsed); + + downholePositionMax = positionMax(downholePosition, downholeLoad, numPointsUsed); + downholeLoadMax = loadMax(downholePosition, downholeLoad, numPointsUsed); + downholePositionMin = positionMin(downholePosition, downholeLoad, numPointsUsed); + downholeLoadMin = loadMin(downholePosition, downholeLoad, numPointsUsed); + + surfaceStrokeLength = surfacePositionMax.getPosition() - surfacePositionMin.getPosition(); + downholeGrossStrokeLength = downholePositionMax.getPosition() - downholePositionMin.getPosition(); + downholeLoadSpan = downholeLoadMax.getLoad() - downholeLoadMin.getLoad(); + + double dxSurf = (surfacePositionMax.getPosition() - surfacePositionMin.getPosition()) / (float) numSlices; + double dxDown = (downholePositionMax.getPosition() - downholePositionMin.getPosition()) / (float) numSlices; + + pumpHorsepower = 0.0; + polishedRodHorsepower = 0.0; + double dhDistanceTop = 0.0; + double dhDistanceBottom = 0.0; + + for (int i = 1; i < numSlices+1; i++) + { + double suPosTarget = surfacePositionMin.getPosition() + ((double) i * dxSurf); + double dhPosTarget = downholePositionMin.getPosition() + ((double) i * dxDown); + double suLoadAtTargetTop = 0.0; + double suLoadAtTargetBottom = 0.0; + double dhLoadAtTargetTop = 0.0; + double dhLoadAtTargetBottom = 0.0; + + for(int j = 0; j < numPointsUsed - 1; j++) + { + if (downholePosition[j] <= dhPosTarget && downholePosition[j+1] > dhPosTarget){ + dhLoadAtTargetTop = lineResolve(downholePosition[j], downholePosition[j+1], downholeLoad[j], downholeLoad[j+1], dhPosTarget); + } + + if (downholePosition[j] > dhPosTarget && downholePosition[j+1] >= dhPosTarget){ + dhLoadAtTargetBottom = lineResolve(downholePosition[j], downholePosition[j+1], downholeLoad[j], downholeLoad[j+1], dhPosTarget); + } + + if (surfacePosition[j] <= suPosTarget && surfacePosition[j+1] > suPosTarget){ + suLoadAtTargetTop = lineResolve(surfacePosition[j], surfacePosition[j+1], surfaceLoad[j], surfaceLoad[j+1], suPosTarget); + } + + if (surfacePosition[j] > suPosTarget && surfacePosition[j+1] >= suPosTarget){ + suLoadAtTargetBottom = lineResolve(surfacePosition[j], surfacePosition[j+1], surfaceLoad[j], surfaceLoad[j+1], suPosTarget); + } + } + + polishedRodHorsepower += (dxSurf / 12.0) * (suLoadAtTargetTop - suLoadAtTargetBottom) * (strokeSpeed / 33000.0); + pumpHorsepower += (dxDown / 12.0) * (dhLoadAtTargetTop - dhLoadAtTargetBottom) * (strokeSpeed / 33000.0); + + double tDistance = distanceToLine(dhPosTarget, dhLoadAtTargetTop); + double bDistance = distanceToLine(dhPosTarget, dhLoadAtTargetBottom); + + if (tDistance > dhDistanceTop) + { + dhDistanceTop = tDistance; + topCorner.set(dhPosTarget, dhLoadAtTargetTop); + } + + if (bDistance > dhDistanceBottom) + { + dhDistanceBottom = bDistance; + bottomCorner.set(dhPosTarget, dhLoadAtTargetBottom); + } + } + + downholeAdjustedGrossStrokeLength = downholePositionMax.getPosition() - topCorner.getPosition(); + downholeNetStrokeLength = bottomCorner.getPosition() - downholePositionMin.getPosition(); + fillageCalculated = (downholeNetStrokeLength / downholeAdjustedGrossStrokeLength) * 100.0; + fillageEstimated =(downholeNetStrokeLength / downholeGrossStrokeLength) * 100.0; + fluidBblMoved = downholeNetStrokeLength * pumpArea * 0.00010307; + fluidBblMovedAdjusted = fluidBblMoved * kFactor; + oilBblMoved = fluidBblMoved * oilBBLRatio; + waterBblMoved = fluidBblMoved * waterBBLRatio; + gasMcfMoved = fluidBblMoved * gasMCFRatio; + + + if (fillageEstimated > 100) + fillageEstimated = 100.0; + + if (fillageEstimated < 0.0) + fillageEstimated = 0.0; + + if (fillageCalculated > 100) + fillageCalculated = 100.0; + + if (fillageCalculated < 0.0) + fillageCalculated = 0.0; + + fluidLoad = downholeLoadSpan - frictionEstimate; + pumpIntakePressure = fluidGradient * rodDepth - (fluidLoad / pumpArea); + //printf("PIP = %f * %f - (%f / %f) = %f\n", fluidGradient, rodDepth, fluidLoad, pumpArea, pumpIntakePressure); + fluidLevel = pumpIntakePressure / fluidGradient; + tubingMovement = 12 * (rodDepth - anchorDepth) * fluidLoad / (30500000 * tubingCSA); + structuralLoading = (surfaceLoadMax.getLoad() / (structuralRating * 100)) * 100; + +} + +Card::~Card() { + // TODO Auto-generated destructor stub +} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Card.h b/src/Card.h new file mode 100644 index 0000000..dd715e6 --- /dev/null +++ b/src/Card.h @@ -0,0 +1,119 @@ +/* + * Card.h + * + * Created on: Jul 3, 2017 + * Author: patrickjmcd + */ + +#ifndef CARD_H_ +#define CARD_H_ + +#include "LPPair.h" +#include +#include +#include +#include +#include +#include + +static const int maxPoints = 1500; + +class Card { +public: + Card(long strokeNumber); + Card(); + double surfacePosition[maxPoints], surfaceLoad[maxPoints], downholePosition[maxPoints], downholeLoad[maxPoints]; + void setSurfacePosition(int i, double position); + void setSurfaceLoad(int i, double load); + void setDownholePosition(int i, double position); + void setDownholeLoad(int i, double load); + void setNumPointsUsed(int i); + + LPPair getSurfacePositionMax(); + LPPair getSurfaceLoadMax(); + LPPair getSurfacePositionMin(); + LPPair getSurfaceLoadMin(); + + LPPair getDownholePositionMax(); + LPPair getDownholeLoadMax(); + LPPair getDownholePositionMin(); + LPPair getDownholeLoadMin(); + + long getStrokeNumber(); + double getSurfaceStrokeLength(); + double getDownholeNetStrokeLength(); + double getDownholeGrossStrokeLength(); + double getDownholeAdjustedGrossStrokeLength(); + double getDownholeLoadSpan(); + double getFluidLoad(); + double getFillageEstimated(); + double getFillageCalculated(); + double getTubingMovement(); + double getStructuralLoading(); + double getPumpIntakePressure(); + double getFluidLevel(); + double getStrokeSpeed(); + double getPolishedRodHorsepower(); + double getPumpHorsepower(); + double getFluidBblMoved(); + double getFluidBblMovedAdjusted(); + double getWaterBblMoved(); + double getOilBblMoved(); + double getGasMcfMoved(); + int getNumPointsUsed(); + void calcStrokeData(int numSlices, double fluidGradient, double rodDepth, double anchorDepth, double tubingCSA, + double pumpArea, double frictionEstimate, double structuralRating, + double kFactor, double waterBBLRatio, double oilBBLRatio, double gasMCFRatio); + void printCard(std::string printType, bool printDataTableToo); + virtual ~Card(); + + +private: + // Card Points + int numPointsUsed; + + // Card Data + long strokeNumber; + LPPair surfacePositionMax, surfacePositionMin, surfaceLoadMax, surfaceLoadMin; + LPPair downholePositionMax, downholePositionMin, downholeLoadMax, downholeLoadMin; + LPPair topCorner, bottomCorner; + + double surfaceStrokeLength; + double downholeNetStrokeLength; + double downholeGrossStrokeLength; + double downholeAdjustedGrossStrokeLength; + double downholeLoadSpan; + double fluidLoad; + double pumpIntakePressure; + double fluidLevel; + double fillageEstimated; + double fillageCalculated; + double tubingMovement; + double strokeSpeed; + + double structuralLoading; + + double polishedRodHorsepower; + double pumpHorsepower; + double fluidBblMoved; + double fluidBblMovedAdjusted; + double waterBblMoved; + double oilBblMoved; + double gasMcfMoved; + + std::chrono::milliseconds strokeStartTime; + + double lineResolve(double x1, double x2, double y1, double y2, double xTest); + LPPair positionMax(double* positionArr, double* loadArr, int arrSize); + LPPair positionMin(double* positionArr, double* loadArr, int arrSize); + LPPair loadMax(double* positionArr, double* loadArr, int arrSize); + LPPair loadMin(double* positionArr, double* loadArr, int arrSize); + + double distanceToLine(double pos, double load); + void calculateSpm(); + + + +}; + +#endif /* CARD_H_ */ diff --git a/src/Database.cpp b/src/Database.cpp new file mode 100644 index 0000000..a9c591a --- /dev/null +++ b/src/Database.cpp @@ -0,0 +1,450 @@ +// +// Database.cpp +// POCpp +// +// Created by Patrick McDonagh on 7/5/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#include "Database.h" + +Database::Database() { + pocDb = mongoClient["poc"]; + + cardCollection = pocDb["cards"]; + bsoncxx::builder::stream::document cardCollectionIndexBuilder; + cardCollectionIndexBuilder << "timestamp" << 1 << "strokeNumber" << 1; + cardCollection.create_index(cardCollectionIndexBuilder.view() , {}); + + wellDataCollection = pocDb["measurements"]; + bsoncxx::builder::stream::document wellDataCollectionIndexBuilder; + wellDataCollectionIndexBuilder << "dateStored" << 1 << "tagName" << 1; + wellDataCollection.create_index(wellDataCollectionIndexBuilder.view() , {}); + + gaugeOffCollection = pocDb["gaugeOff"]; + bsoncxx::builder::stream::document gaugeOffCollectionIndexBuilder; + gaugeOffCollectionIndexBuilder << "timestamp" << 1 << "tagName" << 1; + gaugeOffCollection.create_index(gaugeOffCollectionIndexBuilder.view() , {}); + + wellTestCollection = pocDb["wellTests"]; + bsoncxx::builder::stream::document wellTestCollectionIndexBuilder; + wellTestCollectionIndexBuilder << "testStartTime" << 1; + wellTestCollection.create_index(wellTestCollectionIndexBuilder.view() , {}); + + fluidShotsCollection = pocDb["fluidShots"]; + bsoncxx::builder::stream::document justTimestampIndexBuilder; + justTimestampIndexBuilder << "timestamp" << 1; + fluidShotsCollection.create_index(justTimestampIndexBuilder.view() , {}); + + runStatusCollection = pocDb["runStatus"]; + runStatusCollection.create_index(justTimestampIndexBuilder.view() , {}); + + wellConfigCollection = pocDb["wellConfiguration"]; + wellConfigCollection.create_index(justTimestampIndexBuilder.view() , {}); + + setpointCollection = pocDb["setpoints"]; + bsoncxx::builder::stream::document setpointCollectionIndexBuilder; + setpointCollectionIndexBuilder << "name" << 1; + setpointCollection.create_index(setpointCollectionIndexBuilder.view() , {}); +} + +long Database::getLastStrokeNumber(){ +// db.getCollection('cards').aggregate( +// [{ $group: {_id: "strokeNumber", +// lastStroke: {$last : "$strokeNumber"} +// }}] +// ) + long lastStroke = 0; + + mongocxx::pipeline stages; + bsoncxx::builder::stream::document group_stage; + + + group_stage << "_id" + << "strokeNumber" + << "lastStroke" << open_document << "$last" << "$strokeNumber" << close_document; + + stages.group(group_stage.view()); + + mongocxx::cursor cursor = cardCollection.aggregate(stages); + for (auto&& doc : cursor) { + bsoncxx::document::element lastStrokeElement = doc["lastStroke"]; + lastStroke = lastStrokeElement.get_int64(); + } + + return lastStroke; +} + +long Database::newCard(Card &inpCard){ + int numPoints = inpCard.getNumPointsUsed(); + double s_p[numPoints]; + double s_l[numPoints]; + double d_p[numPoints]; + double d_l[numPoints]; + + bsoncxx::types::b_date timestamp = bsoncxx::types::b_date {std::chrono::duration_cast< std::chrono::milliseconds >( + std::chrono::system_clock::now().time_since_epoch() + )}; + + bsoncxx::types::b_int64 strokeNumber = bsoncxx::types::b_int64{inpCard.getStrokeNumber()}; + + + for(int i = 0; i < numPoints; i++ ) { + s_p[i] = inpCard.surfacePosition[i]; + s_l[i] = inpCard.surfaceLoad[i]; + d_p[i] = inpCard.downholePosition[i]; + d_l[i] = inpCard.downholeLoad[i]; + } + + bsoncxx::builder::stream::document doc_value; + doc_value << "strokeNumber" << strokeNumber; + + auto in_sp_array = doc_value << "surfacePosition" << bsoncxx::builder::stream::open_array; + for (auto&& e : s_p) { + in_sp_array = in_sp_array << e; + } + auto after_sp_array = in_sp_array << bsoncxx::builder::stream::close_array; + + auto in_sl_array = after_sp_array << "surfaceLoad" << bsoncxx::builder::stream::open_array; + for (auto&& e : s_l) { + in_sl_array = in_sl_array << e; + } + auto after_sl_array = in_sl_array << bsoncxx::builder::stream::close_array; + + auto in_dp_array = after_sl_array << "downholePosition" << bsoncxx::builder::stream::open_array; + for (auto&& e : d_p) { + in_dp_array = in_dp_array << e; + } + auto after_dp_array = in_dp_array << bsoncxx::builder::stream::close_array; + + auto in_dl_array = after_dp_array << "downholeLoad" << bsoncxx::builder::stream::open_array; + for (auto&& e : d_l) { + in_dl_array = in_dl_array << e; + } + auto after_dl_array = in_dl_array << bsoncxx::builder::stream::close_array; + after_dl_array << "timestamp" << timestamp; + bsoncxx::document::value doc = after_dl_array << bsoncxx::builder::stream::finalize; + auto result = cardCollection.insert_one(doc.view()); + + if (result->inserted_id().type() == bsoncxx::type::k_oid) { + bsoncxx::oid id = result->inserted_id().get_oid().value; + std::string id_str = id.to_string(); + std::cout << "Inserted id: " << id_str << " for stroke " << strokeNumber << std::endl; + } else { + std::cout << "Inserted id was not an OID type" << std::endl; + } + + return cardCollection.count({}); +} + +long Database::newMeasurement(Measurement &inpMeasurement){ + + time_t rawtime; + struct tm *tmTimestamp, *tmDate; + time (&rawtime); + tmTimestamp = gmtime(&rawtime); + tmDate = gmtime(&rawtime); + + std::string valString = "values." + std::to_string(tmTimestamp->tm_hour) + "." +std::to_string(tmTimestamp->tm_min); + + tmDate->tm_hour = 0; + tmDate->tm_min = 0; + tmDate->tm_sec = 0; + + time_t rawDate = mktime(tmDate); + std::chrono::system_clock::time_point date_point = std::chrono::system_clock::from_time_t(rawDate); + bsoncxx::types::b_date datestamp = bsoncxx::types::b_date{date_point}; + + + bsoncxx::builder::stream::document doc_value; + doc_value << "$set" << bsoncxx::builder::stream::open_document; + doc_value << valString << inpMeasurement.getCurrentValue(); + doc_value << "currentValue" << inpMeasurement.getCurrentValue(); + doc_value << "maxValue" << inpMeasurement.getDailyMax(); + doc_value << "minValue" << inpMeasurement.getDailyMin(); + doc_value << "averageValue" << inpMeasurement.getAverage(); + doc_value << "totalValue" << inpMeasurement.getTotal(); + doc_value << "numMeasurements" << bsoncxx::types::b_int64{inpMeasurement.getNumMeasurements()}; + doc_value << "units" << inpMeasurement.getUnits(); + doc_value << "storeDelta" << inpMeasurement.getSendDelta(); + doc_value << "storeTime" << bsoncxx::types::b_int64{inpMeasurement.getSendTimeDelta()}; + doc_value << "useTotal" << inpMeasurement.getUseTotal(); + doc_value << "useAverage" << inpMeasurement.getUseAverage(); + doc_value << "dateStored"<< datestamp; + doc_value << bsoncxx::builder::stream::close_document; + + bsoncxx::document::value doc = doc_value << bsoncxx::builder::stream::finalize; + + bsoncxx::builder::stream::document filterBuilder; + filterBuilder << "tagName" << inpMeasurement.getTagName(); + filterBuilder << "dateStored" << datestamp; + bsoncxx::document::value filterDoc = filterBuilder << bsoncxx::builder::stream::finalize; + + mongocxx::options::update updOptions; + updOptions.upsert(true); + + + wellDataCollection.update_one(filterDoc.view(), doc.view(), updOptions); + + std::cout << "Stored " << inpMeasurement.getCurrentValue() << " for " <tm_hour = 0; + tmDate->tm_min = 0; + tmDate->tm_sec = 0; + + time_t rawDate = mktime(tmDate); + std::chrono::system_clock::time_point date_point = std::chrono::system_clock::from_time_t(rawDate); + bsoncxx::types::b_date datestamp = bsoncxx::types::b_date{date_point}; + + if (testDate == datestamp){ + return true; + } + return false; +} + +int Database::getLastStoredMeasurementAndUpdate(Measurement &inpMeasurement){ + int measurementFound = 0; + mongocxx::options::find opts; + bsoncxx::builder::stream::document filterBuilder, sortBuilder; + filterBuilder << "tagName" << inpMeasurement.getTagName(); + sortBuilder << "dateStored" << -1; + + opts.sort(sortBuilder.view()); + opts.limit(1); + + mongocxx::cursor mCursor = wellDataCollection.find(filterBuilder.view(), opts); + for (auto&& doc : mCursor) { + double average = doc["averageValue"].get_double(); + double total = doc["totalValue"].get_double(); + double dailyMax = doc["maxValue"].get_double(); + double dailyMin = doc["minValue"].get_double(); + double sendDelta = doc["storeDelta"].get_double(); + long sendTimeDelta = (long) doc["storeTime"].get_int64(); + double lastSentValue = doc["currentValue"].get_double(); + long numMeasurements = doc["numMeasurements"].get_int64(); + + bsoncxx::types::b_date dateStored = doc["dateStored"].get_date(); + + if (isToday(dateStored)){ + inpMeasurement.setFromDatabase(average, total, dailyMin, dailyMax, sendDelta, sendTimeDelta, lastSentValue, numMeasurements); + std::cout << inpMeasurement.getTagName() << " retrieved from database!" << std::endl; + measurementFound = 1; + } else { + std::cout << inpMeasurement.getTagName() << " value is too old in database." << std::endl; + } + } + + return measurementFound; +} + +long Database::newDailyTotal(Measurement &inpMeasurement){ + bsoncxx::builder::stream::document totalBuilder; + + bsoncxx::types::b_date timestamp = bsoncxx::types::b_date {std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch())}; + + totalBuilder << "tagName" << inpMeasurement.getTagName(); + totalBuilder << "currentValue" << inpMeasurement.getCurrentValue(); + totalBuilder << "maxDailyValue" << inpMeasurement.getDailyMax(); + totalBuilder << "minDailyValue" << inpMeasurement.getDailyMin(); + totalBuilder << "dailyAverage" << inpMeasurement.getAverage(); + totalBuilder << "dailyTotal" << inpMeasurement.getTotal(); + totalBuilder << "timestamp"<< timestamp; + + gaugeOffCollection.insert_one(totalBuilder.view()); + return gaugeOffCollection.count({}); + +} + +double Database::getPreviousDailyProductionTotal(std::chrono::milliseconds timestamp){ + double productionTotal = -1; + bsoncxx::types::b_date bsonTimestamp = bsoncxx::types::b_date{timestamp}; + + bsoncxx::builder::stream::document findBuilder, sortBuilder; + findBuilder << "tagName" << "Fluid Produced"; + findBuilder << "$lte" << bsoncxx::builder::stream::open_document; + findBuilder << "timestamp" << bsonTimestamp; + findBuilder << bsoncxx::builder::stream::close_document; + + sortBuilder << "timestamp" << -1; + + mongocxx::options::find opts; + opts.sort(sortBuilder.view()); + opts.limit(1); + + mongocxx::cursor wellTestCursor = wellDataCollection.find(findBuilder.view(), opts); + for (auto&& doc : wellTestCursor) { + productionTotal = doc["dailyTotal"].get_double(); + } + return productionTotal; +}; + +long Database::newWellTest(WellTest inp){ + + bsoncxx::types::b_date bsonTimestamp = bsoncxx::types::b_date{inp.getTestCompletedTimestamp()}; + + bsoncxx::builder::stream::document wellTestBuilder; + wellTestBuilder << "testCompletedTimestamp" << bsonTimestamp; + wellTestBuilder << "testHours" << inp.getTestHours(); + wellTestBuilder << "testTotalBbl" << inp.getTotalFluidBbl(); + wellTestBuilder << "testOilBbl" << inp.getTestOilBbl(); + wellTestBuilder << "testWaterBbl" << inp.getTestWaterBbl(); + wellTestBuilder << "testGasMcf" << inp.getTestGasMcf(); + wellTestBuilder << "kFactor" << inp.getKFactor(); + wellTestBuilder << "oilRatio" << inp.getOilRatio(); + wellTestBuilder << "waterRatio" << inp.getWaterRatio(); + wellTestBuilder << "gasMcfRatio" << inp.getGasMcfRatio(); + wellTestCollection.insert_one(wellTestBuilder.view()); + return wellTestCollection.count({}); + +} + +WellTest Database::getPreviousWellTest(std::chrono::milliseconds timeParameter){ + WellTest foundTest; + bsoncxx::builder::stream::document filterBuilder, sortBuilder; + filterBuilder << "testCompletedTimestamp" << bsoncxx::builder::stream::open_document; + filterBuilder << "$lte" << bsoncxx::types::b_date{timeParameter}; + filterBuilder << bsoncxx::builder::stream::close_document; + + sortBuilder << "testCompletedTimeStamp" << -1; + mongocxx::options::find opts; + opts.sort(sortBuilder.view()); + opts.limit(1); + + mongocxx::cursor wellTestCursor = wellTestCollection.find(filterBuilder.view(), opts); + for (auto&& doc : wellTestCursor) { + bsoncxx::types::b_date testCompletedTimestampDate =doc["testCompletedTimestamp"].get_date(); + std::chrono::milliseconds testCompletedTimestamp = std::chrono::milliseconds{}; + double testHours = doc["testHours"].get_double(); + double testTotalBbl = doc["testTotalBbl"].get_double(); + double testOilBbl = doc["testOilBbl"].get_double(); + double testWaterBbl = doc["testWaterBbl"].get_double(); + double testGasMcf = doc["testGasMcf"].get_double(); + double kFactor = doc["kFactor"].get_double(); + double oilRatio = doc["oilRatio"].get_double(); + double waterRatio = doc["waterRatio"].get_double(); + double gasMcfRatio = doc["gasMcfRatio"].get_double(); + + foundTest.initFromDatabase(testCompletedTimestamp, testHours, testTotalBbl, testOilBbl, testWaterBbl, testGasMcf, kFactor, oilRatio, waterRatio, gasMcfRatio); + } + return foundTest; +}; + +double Database::getLatestKFactor(){ + double kFactor = 1; + bsoncxx::builder::stream::document sortBuilder; + sortBuilder << "testCompletedTimestamp" << -1; + mongocxx::options::find opts; + opts.sort(sortBuilder.view()); + opts.limit(1); + + mongocxx::cursor wellTestCursor = wellTestCollection.find({}, opts); + for (auto&& doc : wellTestCursor) { + kFactor = doc["kFactor"].get_double(); + } + return kFactor; +} + +long Database::newFluidShot(FluidShot inp){ + bsoncxx::types::b_date timestamp = bsoncxx::types::b_date {std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch())}; + + bsoncxx::builder::stream::document fluidShotBuilder; + + fluidShotBuilder << "timestamp" << timestamp; + fluidShotBuilder << "fluidLevel" << inp.getFluidLevel(); + fluidShotBuilder << "pumpIntakePressure" << inp.getPumpIntakePressure(); + fluidShotBuilder << "frictionEstimate" << inp.getFrictionEstimate(); + fluidShotBuilder << "fluidGradient" << inp.getFluidGradient(); + + fluidShotsCollection.insert_one(fluidShotBuilder.view()); + return fluidShotsCollection.count({}); +} + +double Database::getLatestFrictionEstimate(){ + double frictionEstimate = 1; + bsoncxx::builder::stream::document sortBuilder; + sortBuilder << "timestamp" << -1; + mongocxx::options::find opts; + opts.sort(sortBuilder.view()); + opts.limit(1); + + mongocxx::cursor fluidShotCursor = fluidShotsCollection.find({}, opts); + for (auto&& doc : fluidShotCursor) { + frictionEstimate = doc["frictionEstimate"].get_double(); + } + return frictionEstimate; +} + +long Database::newRunStatus(std::string runStatus, std::string initiator){ + bsoncxx::types::b_date timestamp = bsoncxx::types::b_date {std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch())}; + + bsoncxx::builder::stream::document runStatusBuilder; + + runStatusBuilder << "timestamp" << timestamp; + runStatusBuilder << "status" << runStatus; + runStatusBuilder << "initiator" << initiator; + + runStatusCollection.insert_one(runStatusBuilder.view()); + return runStatusCollection.count({}); +} + + + +// FUNCTION TESTS + +void testNewCard(Database &db){ + long nextStroke = db.getLastStrokeNumber() + 1; + + Card newCard(nextStroke); + for (int i = 0; i < 100; i++){ + newCard.setSurfacePosition(i, (double)i); + newCard.setSurfaceLoad(i, (double)i * 200); + newCard.setDownholePosition(i, 100 - (double)i); + newCard.setDownholeLoad(i, (double)i * -100); + } + newCard.setNumPointsUsed(100); + std::cout << db.newCard(newCard) << std::endl; +} + +void testNewMeasurement(Database &db){ + Measurement newMeasurement("Test Measurement"); + newMeasurement.setUseTotal(true); + newMeasurement.setUseAverage(true); + newMeasurement.setFromDatabase(1.0, 100.0, 50, 0, 0.5, 600, 25, 10); + std::cout << db.newMeasurement(newMeasurement) < +#include +#include + +#include +#include +#include + +#include +#include + + + +#include "Card.h" +#include "Measurement.h" +#include "WellTest.h" +#include "FluidShot.h" + +using bsoncxx::builder::stream::close_array; +using bsoncxx::builder::stream::close_document; +using bsoncxx::builder::stream::document; +using bsoncxx::builder::stream::finalize; +using bsoncxx::builder::stream::open_array; +using bsoncxx::builder::stream::open_document; + +class Database{ +private: + std::string pocDatabase = "poc"; +// mongocxx::instance mongoInstance{}; +// mongocxx::uri mongoUri; +// mongocxx::client mongoClient; + mongocxx::instance instance{}; + mongocxx::client mongoClient{mongocxx::uri{"mongodb://poc_www:HenryPump1903@localhost/?authSource=poc"}}; + mongocxx::database pocDb; + + + mongocxx::collection cardCollection, wellDataCollection, gaugeOffCollection, wellTestCollection, + fluidShotsCollection, runStatusCollection, wellConfigCollection, setpointCollection; + void initCollections(); + +public: + Database(); + long getLastStrokeNumber(); + long newCard(Card &inpCard); + long newMeasurement(Measurement &inpMeasurement); + int getLastStoredMeasurementAndUpdate(Measurement &inpMeasurement); + long newDailyTotal(Measurement &inpMeasurement); + double getPreviousDailyProductionTotal(std::chrono::milliseconds timestamp); + long newWellTest(WellTest inp); + WellTest getPreviousWellTest(std::chrono::milliseconds timeParameter); + double getLatestKFactor(); + long newFluidShot(FluidShot inp); + double getLatestFrictionEstimate(); + long newRunStatus(std::string runStatus, std::string initiator); + +}; + +#endif /* Database_hpp */ diff --git a/src/DigitalIn.cpp b/src/DigitalIn.cpp new file mode 100644 index 0000000..1198083 --- /dev/null +++ b/src/DigitalIn.cpp @@ -0,0 +1,60 @@ +/* + * DigitalIn.cpp + * + * Created on: Jun 27, 2017 + * Author: patrickjmcd + */ + +#include "DigitalIn.h" + +DigitalIn::DigitalIn(int channel) { + this->channel = channel; + value = -1; + channelMux[0] = MUX_VALUES[channel][0]; + channelMux[1] = MUX_VALUES[channel][1]; + channelMux[2] = MUX_VALUES[channel][2]; +} + +int DigitalIn::read(MuxSetup *mux){ + mux->set(channelMux[0], channelMux[1], channelMux[2]); + value = mux->readDigital(); + return value; +} + +DigitalIn::~DigitalIn() { + // TODO Auto-generated destructor stub +} + +int main(){ + MuxSetup mux; + + DigitalIn dI1(1); + DigitalIn dI2(2); + DigitalIn dI3(3); + DigitalIn dI4(4); + DigitalIn dI5(5); + DigitalIn dI6(6); + DigitalIn dI7(7); + DigitalIn dI8(8); + + int d1v = dI1.read(&mux); + int d2v = dI2.read(&mux); + int d3v = dI3.read(&mux); + int d4v = dI4.read(&mux); + int d5v = dI5.read(&mux); + int d6v = dI6.read(&mux); + int d7v = dI7.read(&mux); + int d8v = dI8.read(&mux); + + std::cout << "DigIn 1: " << d1v << std::endl; + std::cout << "DigIn 2: " << d2v << std::endl; + std::cout << "DigIn 3: " << d3v << std::endl; + std::cout << "DigIn 4: " << d4v << std::endl; + std::cout << "DigIn 5: " << d5v << std::endl; + std::cout << "DigIn 6: " << d6v << std::endl; + std::cout << "DigIn 7: " << d7v << std::endl; + std::cout << "DigIn 8: " << d8v << std::endl; + + return 1; +} + diff --git a/src/DigitalIn.h b/src/DigitalIn.h new file mode 100644 index 0000000..b3689e2 --- /dev/null +++ b/src/DigitalIn.h @@ -0,0 +1,25 @@ +/* + * DigitalIn.h + * + * Created on: Jun 27, 2017 + * Author: patrickjmcd + */ + +#ifndef DIGITALIN_H_ +#define DIGITALIN_H_ + +#include "MuxSetup.h" + +class DigitalIn { +private: + int channel; + int value; + int channelMux[3]; + +public: + DigitalIn(int channel); + int read(MuxSetup *mux); + virtual ~DigitalIn(); +}; + +#endif /* DIGITALIN_H_ */ diff --git a/src/DigitalOut.cpp b/src/DigitalOut.cpp new file mode 100644 index 0000000..6f9a6dc --- /dev/null +++ b/src/DigitalOut.cpp @@ -0,0 +1,91 @@ +/* + * DigitalOut.cpp + * + * Created on: Jun 26, 2017 + * Author: patrickjmcd + */ + +#include "DigitalOut.h" + +DigitalOut::DigitalOut(int chan) { + // TODO Auto-generated constructor stub + switch (chan){ + case 1: + channel = 29; + break; + case 2: + channel = 28; + break; + case 3: + channel = 27; + break; + case 4: + channel = 26; + break; + case 5: + channel = 6; + break; + case 6: + channel = 5; + break; + case 7: + channel = 4; + break; + case 8: + channel = 1; + break; + default: + channel = 0; +// std::cout << "Cannot setup channel " << chan; + break; + } + pin = new mraa::Gpio(channel); + pin->dir(mraa::DIR_OUT); + +} + +void DigitalOut::write(int value){ + pin->write(value); +} + +DigitalOut::~DigitalOut() { + // TODO Auto-generated destructor stub + pin->write(0); +} + +int main(){ + DigitalOut dO1(1); + DigitalOut dO2(2); + DigitalOut dO3(3); + DigitalOut dO4(4); + DigitalOut dO5(5); + DigitalOut dO6(6); + + dO1.write(1); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO2.write(1); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO3.write(1); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO4.write(1); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO5.write(1); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO6.write(1); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO6.write(0); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO5.write(0); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO4.write(0); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO3.write(0); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO2.write(0); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + dO1.write(0); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + +} + + diff --git a/src/DigitalOut.h b/src/DigitalOut.h new file mode 100644 index 0000000..17b5852 --- /dev/null +++ b/src/DigitalOut.h @@ -0,0 +1,28 @@ +/* + * DigitalOut.h + * + * Created on: Jun 26, 2017 + * Author: patrickjmcd + */ + +#ifndef DIGITALOUT_H_ +#define DIGITALOUT_H_ + +#include "mraa.hpp" +#include +#include +#include +#include + +class DigitalOut { +private: + int channel; + mraa::Gpio* pin; + +public: + DigitalOut(int chan); + void write(int val); + virtual ~DigitalOut(); +}; + +#endif /* DIGITALOUT_H_ */ diff --git a/src/FluidShot.cpp b/src/FluidShot.cpp new file mode 100644 index 0000000..44433cc --- /dev/null +++ b/src/FluidShot.cpp @@ -0,0 +1,40 @@ +// +// FluidShot.cpp +// POCpp +// +// Created by Patrick McDonagh on 7/7/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#include "FluidShot.h" + + +FluidShot::FluidShot(double fluidLevel, double fluidGradient, double downholeLoadSpan, double totalDepth, double pumpArea){ + this->fluidLevel = fluidLevel; + pumpIntakePressure = fluidLevel * fluidGradient; + + frictionEstimate = downholeLoadSpan - (fluidGradient * totalDepth - pumpIntakePressure) * pumpArea; +} + +double FluidShot::getFluidLevel(){ + return fluidLevel; +} + +double FluidShot::getPumpIntakePressure(){ + return pumpIntakePressure; +} + +double FluidShot::getFluidGradient(){ + return fluidGradient; +} + +double FluidShot::getFrictionEstimate(){ + return frictionEstimate; +} + +void FluidShot::initFromDatabase(double fluidLevel, double pumpIntakePressure, double fluidGradient, double frictionEstimate){ + this->fluidLevel = fluidLevel; + this->pumpIntakePressure = pumpIntakePressure; + this->fluidGradient = fluidGradient; + this->frictionEstimate = frictionEstimate; +} diff --git a/src/FluidShot.h b/src/FluidShot.h new file mode 100644 index 0000000..f1907d4 --- /dev/null +++ b/src/FluidShot.h @@ -0,0 +1,32 @@ +// +// FluidShot.hpp +// POCpp +// +// Created by Patrick McDonagh on 7/7/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#ifndef FluidShot_h +#define FluidShot_h + +#include + +class FluidShot{ +public: + FluidShot(double fluidLevel, double fluidGradient, double downholeLoadSpan, double totalDepth, double pumpArea); + double getFluidLevel(); + double getPumpIntakePressure(); + double getFluidGradient(); + double getFrictionEstimate(); + void initFromDatabase(double fluidLevel, double pumpIntakePressure, double fluidGradient, double frictionEstimate); + +private: + double fluidLevel; + double pumpIntakePressure; + double fluidGradient; + double frictionEstimate; +}; + + + +#endif /* FluidShot_h */ diff --git a/src/LPPair.cpp b/src/LPPair.cpp new file mode 100644 index 0000000..8102a90 --- /dev/null +++ b/src/LPPair.cpp @@ -0,0 +1,30 @@ +/* + * LPPair.cpp + * + * Created on: Jul 3, 2017 + * Author: patrickjmcd + */ + +#include "LPPair.h" + +LPPair::LPPair(double position, double load) { + this->position = position; + this->load = load; +} + +double LPPair::getLoad(){ + return load; +} + +double LPPair::getPosition(){ + return position; +} + +void LPPair::set(double position, double load){ + this->position = position; + this->load = load; +} + +LPPair::~LPPair() { + // TODO Auto-generated destructor stub +} diff --git a/src/LPPair.h b/src/LPPair.h new file mode 100644 index 0000000..63dc9ee --- /dev/null +++ b/src/LPPair.h @@ -0,0 +1,26 @@ +/* + * LPPair.h + * + * Created on: Jul 3, 2017 + * Author: patrickjmcd + */ + +#ifndef LPPAIR_H_ +#define LPPAIR_H_ + +#include + +class LPPair { +public: + LPPair(double position, double load); + double getPosition(); + double getLoad(); + void set(double position, double load); + virtual ~LPPair(); + +private: + double position; + double load; +}; + +#endif /* LPPAIR_H_ */ diff --git a/src/LPStatus.cpp b/src/LPStatus.cpp new file mode 100644 index 0000000..fb7626b --- /dev/null +++ b/src/LPStatus.cpp @@ -0,0 +1,31 @@ +/* + * LPStatus.cpp + * + * Created on: Jul 3, 2017 + * Author: patrickjmcd + */ + +#include "LPStatus.h" + +LPStatus::LPStatus(double position, double load, int status) { + this->position = position; + this->load = load; + this->status = status; +} + +double LPStatus::getPosition(){ + return position; +} + +double LPStatus::getLoad(){ + return load; +} + +int LPStatus::getStatus(){ + return status; +} + +LPStatus::~LPStatus() { + // TODO Auto-generated destructor stub +} + diff --git a/src/LPStatus.h b/src/LPStatus.h new file mode 100644 index 0000000..d3b4626 --- /dev/null +++ b/src/LPStatus.h @@ -0,0 +1,24 @@ +/* + * LPStatus.h + * + * Created on: Jul 3, 2017 + * Author: patrickjmcd + */ + +#ifndef LPSTATUS_H_ +#define LPSTATUS_H_ + +class LPStatus { +public: + LPStatus(double position, double load, int status); + double getPosition(); + double getLoad(); + int getStatus(); + virtual ~LPStatus(); + +private: + double position, load; + int status; +}; + +#endif /* LPSTATUS_H_ */ diff --git a/src/Measurement.cpp b/src/Measurement.cpp new file mode 100644 index 0000000..615e759 --- /dev/null +++ b/src/Measurement.cpp @@ -0,0 +1,169 @@ +// +// Measurement.cpp +// POCpp +// +// Created by Patrick McDonagh on 7/6/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#include "Measurement.h" + +Measurement::Measurement(std::string tagName){ + this-> tagName = tagName; + + average = 0; + total = 0; + numMeasurements = 0; + dailyMax = -__DBL_MAX__; + dailyMin = __DBL_MAX__; + + lastSentValue = 0.0; + lastSentTimestamp = 0; + +} + +void shiftright (double myarray[], int size) +{ + double temp; + + for (int i=0; i<(size -1); i++) + { + temp = myarray[size-1]; + myarray[size-1] = myarray[i]; + myarray[i] = temp; + } +} + +double Measurement::getCurrentValue(){ + return currentValue; +} + +double Measurement::getLastValue(){ + return lastValue; +} + +double Measurement::getAverage(){ + return average; +} + +double Measurement::getTotal(){ + return total; +} + +long Measurement::getNumMeasurements(){ + return numMeasurements; +} + +std::string Measurement::getTagName(){ + return tagName; +} + +double Measurement::getDailyMin(){ + return dailyMin; +} + +double Measurement::getDailyMax(){ + return dailyMax; +} + +double Measurement::getSendDelta(){ + return sendDelta; +} + +void Measurement::setSendDelta(double sendDelta){ + this->sendDelta = sendDelta; +} + +long Measurement::getSendTimeDelta(){ + return sendTimeDelta; +} + +void Measurement::setSendTimeDelta(long sendTimeDelta){ + this->sendTimeDelta = sendTimeDelta; +} + +std::string Measurement::getUnits(){ + return units; +} + +void Measurement::setUnits(std::string units){ + this->units = units; +} + +bool Measurement::getUseTotal(){ + return useTotal; +} + +void Measurement::setUseTotal(bool useTotal){ + this->useTotal = useTotal; +} + +bool Measurement::getUseAverage(){ + return useAverage; +} + +void Measurement::setUseAverage(bool useAverage){ + this->useAverage = useAverage; +} + +void Measurement::setFromDatabase(double average, double total, double dailyMin, double dailyMax, double sendDelta, long sendTimeDelta, double lastSentValue, long numMeasurements){ + this->average = average; + this->total = total; + this->dailyMin = dailyMin; + this->dailyMax = dailyMax; + this->sendDelta = sendDelta; + this->sendTimeDelta = sendTimeDelta; + this->lastSentValue = lastSentValue; + this->numMeasurements = numMeasurements; +} + +int Measurement::update(double value){ + int reportValue = 0; + long currentTimestamp = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + + lastValue = currentValue; + currentValue = value; + + numMeasurements = numMeasurements + 1; + average = average * (((double)numMeasurements - 1)/(double)numMeasurements) + (currentValue / (double)numMeasurements); + total = total + value; + + dailyMax = std::max(dailyMax, currentValue); + dailyMin = std::min(dailyMin, currentValue); + + if(std::abs(currentValue - lastSentValue) > sendDelta){ + reportValue = 1; + } else if ((currentTimestamp - lastSentTimestamp) > (sendTimeDelta)){ + reportValue = 2; + } + + if (reportValue > 0){ + lastSentValue = currentValue; + lastSentTimestamp = currentTimestamp; + } + return reportValue; +} +void Measurement::endOfDay(){ + shiftright(totalHistory, 100); + shiftright(averageHistory, 100); + + totalHistory[0] = total; + averageHistory[0] = average; + + total = 0; + average = 0; + dailyMax = -__DBL_MAX__; + dailyMin = __DBL_MAX__; + numMeasurements = 0; +} + + + + + + + + + + + diff --git a/src/Measurement.h b/src/Measurement.h new file mode 100644 index 0000000..c9179ea --- /dev/null +++ b/src/Measurement.h @@ -0,0 +1,67 @@ +// +// Measurement.hpp +// POCpp +// +// Created by Patrick McDonagh on 7/6/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#ifndef Measurement_hpp +#define Measurement_hpp + +#include +#include +#include +#include +#include + +class Measurement{ + +private: + std::string tagName; + double currentValue; + double lastValue; + double average; + double total; + double dailyMax; + double dailyMin; + double totalHistory[30]; + double averageHistory[30]; + long numMeasurements; + double lastSentValue; + double sendDelta; + long lastSentTimestamp; + long sendTimeDelta; + std::string units; + bool useTotal; + bool useAverage; + +public: + Measurement(std::string tagName); + double getCurrentValue(); + double getLastValue(); + double getAverage(); + double getTotal(); + long getNumMeasurements(); + std::string getTagName(); + double getDailyMin(); + double getDailyMax(); + double getSendDelta(); + void setSendDelta(double sendDelta); + long getSendTimeDelta(); + void setSendTimeDelta(long sendTimeDelta); + std::string getUnits(); + void setUnits(std::string units); + bool getUseTotal(); + void setUseTotal(bool useTotal); + bool getUseAverage(); + void setUseAverage(bool useAverage); + void setFromDatabase(double average, double total, double dailyMin, double dailyMax, double sendDelta, long sendTimeDelta, double lastSentValue, long numMeasurements); + int update(double value); + void endOfDay(); + + +}; + + +#endif /* Measurement_hpp */ diff --git a/src/MuxSetup.cpp b/src/MuxSetup.cpp new file mode 100644 index 0000000..d62b337 --- /dev/null +++ b/src/MuxSetup.cpp @@ -0,0 +1,99 @@ +/* + * MuxSetup.cpp + * + * Created on: Jun 27, 2017 + * Author: patrickjmcd + */ + +#include "MuxSetup.h" + +int PIN_MUX_1 = 21; +int PIN_MUX_2 = 22; +int PIN_MUX_3 = 23; +int PIN_DIGITAL_READ = 24; +int PIN_ANOUT_TRIGGER = 4; + +int SPI_CHANNEL = 0; + +MuxSetup::MuxSetup() { + // TODO Auto-generated constructor stub + + mux1value = 0; + mux2value = 0; + mux3value = 0; + + pinMux1 = new mraa::Gpio(PIN_MUX_1); + mraa::Result response = pinMux1->dir(mraa::DIR_OUT); + + pinMux2 = new mraa::Gpio(PIN_MUX_2); + response = pinMux2->dir(mraa::DIR_OUT); + + pinMux3 = new mraa::Gpio(PIN_MUX_3); + response = pinMux3->dir(mraa::DIR_OUT); + + pinDigitalRead = new mraa::Gpio(PIN_DIGITAL_READ); + response = pinDigitalRead->dir(mraa::DIR_OUT); + + pinAnOutTrigger = new mraa::Gpio(PIN_ANOUT_TRIGGER); + response = pinAnOutTrigger->dir(mraa::DIR_OUT); + + + + spi = new mraa::Spi(SPI_CHANNEL); + + pinAnOutTrigger->write(1); + +} + +int MuxSetup::apply(){ + pinMux1->write(mux1value); + pinMux2->write(mux2value); + pinMux3->write(mux3value); + + return mux1value + mux2value * 2 + mux3value * 4; +} + +int MuxSetup::set(int v1, int v2, int v3){ + + mux1value = v1; + mux2value = v2; + mux3value = v3; + return apply(); +} + +int MuxSetup::readDigital(){ + return pinDigitalRead->read(); +} + +int MuxSetup::readAnalog(){ + + uint8_t zero[] = {0x00, 0x00, 0x000}; + uint8_t* recv = spi->write(zero, 3); + int a = recv[0]; + int b = recv[1]; + int c = recv[2]; + std::cout << a << " - " << b << " - " << c << std::endl; + + if (c == 13){ + int x = a * 256; + x = x + b; + return x; + } else { + return -1; + } +} + +void MuxSetup::preAnalogWrite(){ + pinAnOutTrigger->write(0); +} + +void MuxSetup::postAnalogWrite(){ + pinAnOutTrigger->write(1); +} + +MuxSetup::~MuxSetup() { + // TODO Auto-generated destructor stub +} + + + diff --git a/src/MuxSetup.h b/src/MuxSetup.h new file mode 100644 index 0000000..d2baf45 --- /dev/null +++ b/src/MuxSetup.h @@ -0,0 +1,54 @@ +/* + * MuxSetup.h + * + * Created on: Jun 27, 2017 + * Author: patrickjmcd + */ + +#ifndef MUXSETUP_H_ +#define MUXSETUP_H_ + +#include "mraa.hpp" + + +#include + + +const int MUX_VALUES[9][3] = { + {0,0,0}, + {0,0,0}, + {1,0,0}, + {0,1,0}, + {1,1,0}, + {0,0,1}, + {1,0,1}, + {0,1,1}, + {1,1,1}, +}; + +class MuxSetup { +public: + + MuxSetup(); + int set(int v1, int v2, int v3); + void preAnalogWrite(); + void postAnalogWrite(); + int readAnalog(); + int readDigital(); + int writeDigital(int val); + virtual ~MuxSetup(); + + +private: + int apply(); + int mux1value, mux2value, mux3value; + mraa::Gpio* pinMux1; + mraa::Gpio* pinMux2; + mraa::Gpio* pinMux3; + mraa::Gpio* pinDigitalRead; + mraa::Gpio* pinAnOutTrigger; + mraa::Spi* spi; + +}; + +#endif /* MUXSETUP_H_ */ diff --git a/src/Well.cpp b/src/Well.cpp new file mode 100644 index 0000000..5271a82 --- /dev/null +++ b/src/Well.cpp @@ -0,0 +1,45 @@ +// +// Well.cpp +// POCpp +// +// Created by Patrick McDonagh on 7/7/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#include "Well.h" + +Well::Well(): + inclinometer(1, 0, 65535, 0, 145), + loadCell(2, 0, 65535, 0, 50000), + strokeSpeed("Stroke Speed"), + downholeGrossStroke("Downhole Gross Stroke"), + downholeNetStroke("Downhole Net Stroke"), + fluidLevel("Fluid Level"), + fluidLoad("Fluid Load"), + inflowRate("Inflow Rate"), + peakPolishedRodLoad("Peak Polished Rod Load"), + minPolishedRodLoad("Min Polished Rod Load"), + percentRun("Percent Run"), + polishedRodHP("Polished Rod Horsepower"), + pumpHP("Pump Horsepower"), + fluidProduced("Fluid Produced"), + fluidProducedAdjusted("Fluid Produced (Adjusted)"), + oilProduced("Oil Produced"), + waterProduced("Water Produced"), + gasProduced("Gas Produced"), + pumpIntakePressure("Pump Intake Pressure"), + surfaceStrokeLength("Surface Stroke Length"), + tubingMovement("Tubing Movement"), + pumpFillPercent("Pump Fill Percent"){ + + +} + +int Well::calibrateInclinometer(){ + std::cout << "Calibrating inclinometer..." << std::endl; + + long now = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()).count(); + + + +}; diff --git a/src/Well.h b/src/Well.h new file mode 100644 index 0000000..e2a0705 --- /dev/null +++ b/src/Well.h @@ -0,0 +1,192 @@ +// +// Well.hpp +// POCpp +// +// Created by Patrick McDonagh on 7/7/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#ifndef Well_h +#define Well_h + + +#include +#include + +#include "AnalogIn.h" +#include "Card.h" +#include "Measurement.h" +#include "Database.h" + +const static double YM_STEEL = 30.5; +const static double YM_FIBERGLASS = 7.2; + +const static int BAD_STATUS = 0; +const static int GOOD_STATUS = 1; + +const static int RUNSTATUS_STOPPED = 0; +const static int RUNSTATUS_STARTING = 1; +const static int RUNSTATUS_RUNNING = 2; +const static int RUNSTATUS_PUMPEDOFF = 3; +const static int RUNSTATUS_FAULTED = 4; +const static int RUNSTATUS_LOCKEDOUT = 5; + +const static int RUNMODE_POC = 0; +const static int RUNMODE_MANUAL = 1; +const static int RUNMODE_TIMER = 2; + +const static int DIRECTION_UNKNOWN = 0; +const static int DIRECTION_UP = 1; +const static int DIRECTION_DOWN = 2; + + +class Well{ +private: + std::string wellName; + Database db; + // IO + AnalogIn inclinometer; + AnalogIn loadCell; + MuxSetup ioMux; + double currentSurfacePosition; + double currentSurfaceLoad; + double currentDownholePosition; + double currentDownholeLoad; + + // CARDS + Card currentCard; + Card cardStorage[100]; + + // USER INPUTS + double dt; + double tubingHeadPressure; + double fluidGradient; + double stuffingBoxFriction; + int numTapers; + double tubingAnchorDepth; + double pumpDiameter; + double tubingInnerDiameter, tubingOuterDiameter; + double structuralRating; + double c[11]; + double rodLength[11]; + double rodDiameter[11]; + double rodYM[11]; + double rodWeightPerFoot[11]; + + // CALCULATED TAPER PARAMETERS + double frictionEstimate; + double theoreticalMaxFluidLoad; + double a[11]; + double area[11]; + double pressure[11]; + double buoyantForce[11]; + double buoyantForceTotal; + double stretch[11]; + double weightData[11]; + double weightDataTotal; + double annularForceData[11]; + double annularForceDataTotal; + double force[11]; + double alpha[11]; + double xOverA[11]; + double factor[11]; + int lagIndex[11]; + int lengthRequired[11]; + int centerPoint[11]; + double rodDepth[11]; + double rodDepthTotal; + double rodWeightAir[11]; + double rodWeightAirTotal; + double rodWeightFluid[11]; + double rodWeightFluidTotal; + double pumpArea; + double tubingCrossSectionalArea; + + + int runStatus; + bool permissiveOK; + long strokesSinceStart = 0; + long startupStrokes = 10; + long strokesToday = 0; + long strokesLifetime; + int pointCounter = 0; + + // DIRECTION + int direction = DIRECTION_UNKNOWN; + int lastDirection = DIRECTION_UNKNOWN; + + // RUN MODE + int runMode = RUNMODE_POC; + + + // Intermediate Variables + double topPosArray[10][500]; + double topLoadArray[10][500]; + double loadBefore = 0.0; + double loadAfter = 0.0; + double loadBefore3 = 0.0; + double loadAfter3 = 0.0; + int count[11]; + double sPositionPrevious; + + // Fluid Makeup + double fluidOilRatio; // BBL of oil per 1 BBL fluid + double fluidWaterRatio; // BBL of water per 1 BBL fluid + double fluidGasRatio; // MCF of gas per 1 BBL fluid + double kFactor = 1.0; + + std::chrono::milliseconds now; + + Measurement strokeSpeed; + Measurement downholeGrossStroke; + Measurement downholeNetStroke; + Measurement fluidLevel; + Measurement fluidLoad; + Measurement inflowRate; + Measurement peakPolishedRodLoad; + Measurement minPolishedRodLoad; + Measurement percentRun; + Measurement polishedRodHP; + Measurement pumpHP; + Measurement fluidProduced; + Measurement fluidProducedAdjusted; + Measurement oilProduced; + Measurement waterProduced; + Measurement gasProduced; + Measurement pumpIntakePressure; + Measurement surfaceStrokeLength; + Measurement tubingMovement; + Measurement pumpFillPercent; + + std::chrono::milliseconds pumpStartTime; + + // POC Mode Setpoints + double pumpOffFillPercentSetpoint; + int pumpOffStrokesSetpoint; + long pumpOffDowntimeMinutesSetpoint; + + // POC Mode Status + int lowFillageStrokes = 0; + std::chrono::milliseconds pumpedOffTime; + long minutesSincePumpOff = 0; + long minutesSincePumpOff_last = 0; + + + // Timer Mode Setpoints + long timerRunMinutesSetpoint; + long timerOffMinutesSetpoint; + + // Timer Mode status + std::chrono::milliseconds timerStopTime; + long minutesSinceTimerStop = 0; + long minutesSinceTimerStop_last = 0; + long minutesSinceTimerStart = 0; + long minutesSinceTimerStart_last = 0; + + +public: + Well(); + int calibrateInclinometer(); +}; + +#endif /* Well_h */ diff --git a/src/WellTest.cpp b/src/WellTest.cpp new file mode 100644 index 0000000..c874585 --- /dev/null +++ b/src/WellTest.cpp @@ -0,0 +1,100 @@ +// +// WellTest.cpp +// POCpp +// +// Created by Patrick McDonagh on 7/6/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#include "WellTest.h" + +WellTest::WellTest(){ + +} + +WellTest::WellTest(std::chrono::milliseconds testCompletedTimestamp, double testHours, double totalFluidBbl, double testOilBbl, double testWaterBbl, double testGasMcf, double prevDailyTotal){ + + this->testCompletedTimestamp = testCompletedTimestamp; + this->testHours = testHours; + this->totalFluidBbl = totalFluidBbl; + this->testOilBbl = testOilBbl; + this->testWaterBbl = testWaterBbl; + this->testGasMcf = testGasMcf; + + this->oilRatio = testOilBbl / totalFluidBbl; + this->waterRatio = testWaterBbl / totalFluidBbl; + this->gasMcfRatio = testGasMcf / totalFluidBbl; + + this->kFactor = 1.0; + + if(prevDailyTotal != -1.0){; + this->kFactor = totalFluidBbl / prevDailyTotal; + } else { + std::cout << "No production data in db" << std::endl; + } +} + +double WellTest::getTestHours(){ + return testHours; +} + +std::chrono::milliseconds WellTest::getTestCompletedTimestamp(){ + return testCompletedTimestamp; +} + +double WellTest::getTotalFluidBbl(){ + return totalFluidBbl; +} + +double WellTest::getTestOilBbl(){ + return testOilBbl; +} + +double WellTest::getTestWaterBbl(){ + return testWaterBbl; +} + +double WellTest::getTestGasMcf(){ + return testGasMcf; +} + +double WellTest::getKFactor(){ + return kFactor; +} + +double WellTest::getOilRatio(){ + return oilRatio; +} + +double WellTest::getWaterRatio(){ + return waterRatio; +} + +double WellTest::getGasMcfRatio(){ + return gasMcfRatio; +} + +void WellTest::initFromDatabase(std::chrono::milliseconds testCompletedTimestamp, double testHours, double totalFluidBbl, double testOilBbl, double testWaterBbl, double testGasMcf, double kFactor, double oilRatio, double waterRatio, double gasMcfRatio){ + this->testCompletedTimestamp = testCompletedTimestamp; + this->testHours = testHours; + this-> totalFluidBbl = totalFluidBbl; + this->testOilBbl = testOilBbl; + this->testWaterBbl = testWaterBbl; + this->testGasMcf = testGasMcf; + this->kFactor = kFactor; + this->oilRatio = oilRatio; + this->waterRatio = waterRatio; + this->gasMcfRatio = gasMcfRatio; + + +} + +void WellTest::print(){ + std::cout << "Well Test started at " << &testCompletedTimestamp << " lasting " << testHours << " hours"; + std::cout << "Fluid BBL: " << totalFluidBbl; + std::cout << "Oil BBL: " << testOilBbl; + std::cout << "Water BBL: " << testWaterBbl; + std::cout << "Gas MCF: " << testGasMcf; + std::cout << "New Ratio Oil/Water/Gas: " << oilRatio << "/" << waterRatio << "/" << gasMcfRatio; + std::cout << "New Correction Factor: " << kFactor; +} diff --git a/src/WellTest.h b/src/WellTest.h new file mode 100644 index 0000000..3d53875 --- /dev/null +++ b/src/WellTest.h @@ -0,0 +1,44 @@ +// +// WellTest.hpp +// POCpp +// +// Created by Patrick McDonagh on 7/6/17. +// Copyright © 2017 Henry Pump. All rights reserved. +// + +#ifndef WellTest_hpp +#define WellTest_hpp + +#include +#include +#include + +class WellTest { +public: + WellTest(); + WellTest(std::chrono::milliseconds testCompleted, double testHours, double totalFluidBbl, double testOilBbl, double testWaterBbl, double testGasMcf, double prevDailyTotal); + double getTestHours(); + std::chrono::milliseconds getTestCompletedTimestamp(); + double getTotalFluidBbl(); + double getTestOilBbl(); + double getTestWaterBbl(); + double getTestGasMcf(); + double getKFactor(); + double getOilRatio(); + double getWaterRatio(); + double getGasMcfRatio(); + void initFromDatabase(std::chrono::milliseconds testCompletedTimestamp, double testHours, double totalFluidBbl, double testOilBbl, double testWaterBbl, double testGasMcf, double kFactor, double oilRatio, double waterRatio, double gasMcfRatio); + void print(); + +private: + double testHours; + std::chrono::milliseconds testCompletedTimestamp; + + + double totalFluidBbl, testOilBbl, testWaterBbl, testGasMcf; + double kFactor, oilRatio, waterRatio, gasMcfRatio; + + +}; + +#endif /* WellTest_hpp */