Commit 4ec9c73474d49c84d293fd0053fccae7b60242b3

Authored by Geoffrey Hunter
0 parents

Initial commit. serial-port-cpp library has basic functions up and running.

.cproject 0 → 100644
  1 +++ a/.cproject
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<?fileVersion 4.0.0?>
  3 +
  4 +<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
  5 + <storageModule moduleId="org.eclipse.cdt.core.settings">
  6 + <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1434179845">
  7 + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1434179845" moduleId="org.eclipse.cdt.core.settings" name="Debug">
  8 + <externalSettings/>
  9 + <extensions>
  10 + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
  11 + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  12 + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
  13 + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  14 + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  15 + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  16 + </extensions>
  17 + </storageModule>
  18 + <storageModule moduleId="cdtBuildSystem" version="4.0.0">
  19 + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1434179845" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
  20 + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1434179845." name="/" resourcePath="">
  21 + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1266764326" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
  22 + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.753834071" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
  23 + <builder buildPath="${workspace_loc:/serial-port-cpp}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.145411499" managedBuildOn="true" name="Gnu Make Builder.Debug" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
  24 + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1266840873" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
  25 + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1606617381" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
  26 + <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1135398162" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
  27 + <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1374695701" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
  28 + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2071854206" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
  29 + </tool>
  30 + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.856044512" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
  31 + <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1946954569" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
  32 + <option id="gnu.c.compiler.exe.debug.option.debugging.level.171918039" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
  33 + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.578162411" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
  34 + </tool>
  35 + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.874795535" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
  36 + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1041263527" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
  37 + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.883666878" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
  38 + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
  39 + <additionalInput kind="additionalinput" paths="$(LIBS)"/>
  40 + </inputType>
  41 + </tool>
  42 + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.339286544" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
  43 + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1800711142" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
  44 + </tool>
  45 + </toolChain>
  46 + </folderInfo>
  47 + </configuration>
  48 + </storageModule>
  49 + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
  50 + </cconfiguration>
  51 + <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.457871666">
  52 + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.457871666" moduleId="org.eclipse.cdt.core.settings" name="Release">
  53 + <externalSettings/>
  54 + <extensions>
  55 + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
  56 + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  57 + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
  58 + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  59 + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  60 + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
  61 + </extensions>
  62 + </storageModule>
  63 + <storageModule moduleId="cdtBuildSystem" version="4.0.0">
  64 + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.457871666" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
  65 + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.457871666." name="/" resourcePath="">
  66 + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.409895619" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
  67 + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1193567911" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
  68 + <builder buildPath="${workspace_loc:/serial-port-cpp}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1071856767" managedBuildOn="true" name="Gnu Make Builder.Release" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
  69 + <tool id="cdt.managedbuild.tool.gnu.archiver.base.172329860" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
  70 + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.150242263" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
  71 + <option id="gnu.cpp.compiler.exe.release.option.optimization.level.2067054569" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
  72 + <option id="gnu.cpp.compiler.exe.release.option.debugging.level.1786443037" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
  73 + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1665355821" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
  74 + </tool>
  75 + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1282472662" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
  76 + <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.442630623" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
  77 + <option id="gnu.c.compiler.exe.release.option.debugging.level.396767700" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
  78 + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.228423099" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
  79 + </tool>
  80 + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.428566658" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
  81 + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1163261937" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
  82 + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.854514091" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
  83 + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
  84 + <additionalInput kind="additionalinput" paths="$(LIBS)"/>
  85 + </inputType>
  86 + </tool>
  87 + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.752097052" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
  88 + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.935633559" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
  89 + </tool>
  90 + </toolChain>
  91 + </folderInfo>
  92 + </configuration>
  93 + </storageModule>
  94 + </cconfiguration>
  95 + </storageModule>
  96 + <storageModule moduleId="cdtBuildSystem" version="4.0.0">
  97 + <project id="serial-port-cpp.cdt.managedbuild.target.gnu.exe.525128155" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
  98 + </storageModule>
  99 + <storageModule moduleId="scannerConfiguration">
  100 + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
  101 + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.457871666;cdt.managedbuild.config.gnu.exe.release.457871666.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.150242263;cdt.managedbuild.tool.gnu.cpp.compiler.input.1665355821">
  102 + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
  103 + </scannerConfigBuildInfo>
  104 + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1434179845;cdt.managedbuild.config.gnu.exe.debug.1434179845.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1606617381;cdt.managedbuild.tool.gnu.cpp.compiler.input.2071854206">
  105 + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
  106 + </scannerConfigBuildInfo>
  107 + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.457871666;cdt.managedbuild.config.gnu.exe.release.457871666.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1282472662;cdt.managedbuild.tool.gnu.c.compiler.input.228423099">
  108 + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
  109 + </scannerConfigBuildInfo>
  110 + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1434179845;cdt.managedbuild.config.gnu.exe.debug.1434179845.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.856044512;cdt.managedbuild.tool.gnu.c.compiler.input.578162411">
  111 + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
  112 + </scannerConfigBuildInfo>
  113 + </storageModule>
  114 + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
  115 +</cproject>
... ...
.project 0 → 100644
  1 +++ a/.project
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<projectDescription>
  3 + <name>serial-port-cpp</name>
  4 + <comment></comment>
  5 + <projects>
  6 + </projects>
  7 + <buildSpec>
  8 + <buildCommand>
  9 + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
  10 + <triggers>clean,full,incremental,</triggers>
  11 + <arguments>
  12 + </arguments>
  13 + </buildCommand>
  14 + <buildCommand>
  15 + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
  16 + <triggers>full,incremental,</triggers>
  17 + <arguments>
  18 + </arguments>
  19 + </buildCommand>
  20 + </buildSpec>
  21 + <natures>
  22 + <nature>org.eclipse.cdt.core.cnature</nature>
  23 + <nature>org.eclipse.cdt.core.ccnature</nature>
  24 + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
  25 + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
  26 + </natures>
  27 +</projectDescription>
... ...
README.rst 0 → 100644
  1 +++ a/README.rst
  1 +==============================================================
  2 +serial-port-cpp
  3 +==============================================================
  4 +
  5 +----------------------------------
  6 +Serial port library written in C++
  7 +----------------------------------
  8 +
  9 +.. image:: https://api.travis-ci.org/gbmhunter/serial-port-cpp.png?branch=master
  10 + :target: https://travis-ci.org/gbmhunter/serial-port-cpp
  11 +
  12 +- Author: gbmhunter <gbmhunter@gmail.com> (http://www.cladlab.com)
  13 +- Created: 2014/01/07
  14 +- Last Modified: 2014/05/15
  15 +- Version: v1.0.0.0
  16 +- Company: CladLabs
  17 +- Project: Free Code Libraries
  18 +- Language: C++
  19 +- Compiler: GCC
  20 +- uC Model: n/a
  21 +- Computer Architecture: n/a
  22 +- Operating System: n/a
  23 +- Documentation Format: Doxygen
  24 +- License: GPLv3
  25 +
  26 +.. role:: bash(code)
  27 + :language: bash
  28 +
  29 +Description
  30 +===========
  31 +
  32 +Library for communicating with COM ports on a Linux system.
  33 +
  34 +Uses fstream to the file I/O.
  35 +
  36 +Installation
  37 +============
  38 +
  39 +1. Clone the git repo onto your local storage.
  40 +
  41 +2. Run `make all` to compile and run unit tests. Do not worry about error messages being printed when unit tests are run, the unit tests are designed to specifically cause errors to test the response.
  42 +
  43 +3. To include serial-port-cpp into your embedded (or otherwise) firmware/software project, copy the repo into your project folder (or other suitable place), include the file "/api/SerialPortApi.hpp" from your C++ code, and make sure to compile all the files within "/src/".
  44 +
  45 +
  46 +Dependencies
  47 +============
  48 +
  49 +The following table lists all of the libraries dependencies.
  50 +
  51 +====================== ==================== ======================================================================
  52 +Dependency Delivery Usage
  53 +====================== ==================== ======================================================================
  54 +<stdio.h> Standard C library snprintf()
  55 +====================== ==================== ======================================================================
  56 +
  57 +Issues
  58 +======
  59 +
  60 +See GitHub Issues.
  61 +
  62 +Usage
  63 +=====
  64 +
  65 +In main.c add...
  66 +
  67 +::
  68 +
  69 +
  70 +
  71 +
  72 + int main()
  73 + {
  74 +
  75 +
  76 + }
  77 +
  78 +
  79 +
  80 +FAQ
  81 +===
  82 +
  83 +1. My code stalls when calling functions like :code:`SerialPort::Read()`. This is probably because the library is set up to do a blocking read, and not enough characters have been received to allow :code:`SerialPort::Read()` to return. Use :code:`SerialPort::SetNumCharsToWait()` to determine how many characters to wait for before returning (set to 0 for non-blocking mode).
  84 +
  85 +
  86 +Changelog
  87 +=========
  88 +
  89 +========= ========== ===================================================================================================
  90 +Version Date Comment
  91 +========= ========== ===================================================================================================
  92 +v1.0.0.0 2013/05/15 Initial commit. serial-port-cpp library has basic functions up and running.
  93 +========= ========== ===================================================================================================
0 94 \ No newline at end of file
... ...
api/SerialPortApi.hpp 0 → 100644
  1 +++ a/api/SerialPortApi.hpp
  1 +//!
  2 +//! @file SerialPortApi.hpp
  3 +//! @author Geoffrey Hunter <gbmhunter@gmail.com> (www.cladlab.com)
  4 +//! @created 2014/05/15
  5 +//! @last-modified 2014/05/15
  6 +//! @brief File which contains all the API definitions needed to use the serial-port-cpp library.
  7 +//! @details
  8 +//! See README.rst in repo root dir for more info.
  9 +
  10 +// Header guard
  11 +#ifndef SERIAL_PORT_SERIAL_PORT_API_H
  12 +#define SERIAL_PORT_SERIAL_PORT_API_H
  13 +
  14 +// User headers
  15 +#include "../include/SerialPort.hpp"
  16 +
  17 +#endif // #ifndef SERIAL_PORT_SERIAL_PORT_API_H
... ...
include/Config.hpp 0 → 100644
  1 +++ a/include/Config.hpp
  1 +//!
  2 +//! @file Config.hpp
  3 +//! @author Geoffrey Hunter <gbmhunter@gmail.com> ()
  4 +//! @created 2014/01/07
  5 +//! @last-modified 2014/01/07
  6 +//! @brief Config file for the ComPort library.
  7 +//! @details
  8 +//! See README.rst in repo root dir for more info.
  9 +
  10 +
  11 +namespace SerialPort
  12 +{
  13 +
  14 +
  15 +}
... ...
include/SerialPort.hpp 0 → 100644
  1 +++ a/include/SerialPort.hpp
  1 +//!
  2 +//! @file SerialPort.hpp
  3 +//! @author Geoffrey Hunter <gbmhunter@gmail.com> ()
  4 +//! @created 2014/01/07
  5 +//! @last-modified 2014/05/14
  6 +//! @brief The main serial port class.
  7 +//! @details
  8 +//! See README.rst in repo root dir for more info.
  9 +
  10 +// Header guard
  11 +#ifndef SERIAL_PORT_SERIAL_PORT_H
  12 +#define SERIAL_PORT_SERIAL_PORT_H
  13 +
  14 +// System headers
  15 +#include <fstream> // For file I/O (reading/writing to COM port)
  16 +#include <sstream>
  17 +#include <termios.h> // POSIX terminal control definitions (struct termios)
  18 +
  19 +// User headers
  20 +#include "lib/SmartPrint/include/Sp.hpp"
  21 +
  22 +namespace SerialPort
  23 +{
  24 +
  25 + //! @brief Strongly-typed enumeration of baud rates for use with the SerialPort class
  26 + enum class BaudRates
  27 + {
  28 + none,
  29 + b9600,
  30 + b57600
  31 + };
  32 +
  33 + //! @brief SerialPort object is used to perform rx/tx serial communication.
  34 + class SerialPort
  35 + {
  36 +
  37 + public:
  38 +
  39 + //! @brief Constructor
  40 + SerialPort();
  41 +
  42 + //! @brief Destructor
  43 + virtual ~SerialPort();
  44 +
  45 + //! @brief Sets the file path to use for communications. The file path must be set before Open() is called, otherwise Open() will return an error.
  46 + void SetFilePath(std::string filePath);
  47 +
  48 + void SetBaudRate(BaudRates baudRate);
  49 +
  50 + //! @brief Controls what happens when Read() is called.
  51 + //! @param numOfCharToWait Minimum number of characters to wait for before returning. Set to 0 for non-blocking mode.
  52 + void SetNumCharsToWait(uint32_t numCharsToWait);
  53 +
  54 + //! @brief Opens the COM port for use.
  55 + //! @throws {std::runtime_error} if filename has not been set.
  56 + //! {std::system_error} if system open() operation fails.
  57 + //! @note Must call this before you can configure the COM port.
  58 + void Open();
  59 +
  60 + //! @brief Sets all settings for the com port to common defaults.
  61 + void SetEverythingToCommonDefaults();
  62 +
  63 + //! @brief Closes the COM port.
  64 + void Close();
  65 +
  66 + //! @brief Sends a message over the com port.
  67 + //! @param str Reference to an string containing the characters to write to the COM port.
  68 + //! @throws {std::runtime_error} if filename has not been set.
  69 + //! {std::system_error} if system write() operation fails.
  70 + void Write(std::string* str);
  71 +
  72 + //! @brief Use to read from the COM port.
  73 + //! @param str Reference to a string that the read characters from the COM port will be saved to.
  74 + //! @throws {std::runtime_error} if filename has not been set.
  75 + //! {std::system_error} if system read() operation fails.
  76 + void Read(std::string* str);
  77 +
  78 + private:
  79 +
  80 + std::string filePath;
  81 +
  82 + BaudRates baudRate;
  83 +
  84 + //! @brief The file descriptor for the open file. This gets written to when Open() is called.
  85 + int fileDesc;
  86 +
  87 + //! @brief Object for printing debug and error messages with
  88 + SmartPrint::Sp* sp;
  89 +
  90 + //! @brief Returns a populated termios structure for the passed in file descriptor.
  91 + termios GetTermios();
  92 +
  93 + void SetTermios(termios myTermios);
  94 +
  95 + };
  96 +
  97 +} // namespace SerialPort
  98 +
  99 +#endif // #ifndef SERIAL_PORT_SERIAL_PORT_H
... ...
src/SerialPort.cpp 0 → 100644
  1 +++ a/src/SerialPort.cpp
  1 +//!
  2 +//! @file SerialPort.cpp
  3 +//! @author Geoffrey Hunter <gbmhunter@gmail.com> ()
  4 +//! @created 2014/01/07
  5 +//! @last-modified 2014/05/15
  6 +//! @brief The main serial port class.
  7 +//! @details
  8 +//! See README.rst in repo root dir for more info.
  9 +
  10 +#include <iostream>
  11 +#include <sstream>
  12 +#include <stdio.h> // Standard input/output definitions
  13 +#include <string.h> // String function definitions
  14 +#include <unistd.h> // UNIX standard function definitions
  15 +#include <fcntl.h> // File control definitions
  16 +#include <errno.h> // Error number definitions
  17 +#include <termios.h> // POSIX terminal control definitions (struct termios)
  18 +#include <system_error> // For throwing std::system_error
  19 +
  20 +#include "../include/Config.hpp"
  21 +#include "../include/SerialPort.hpp"
  22 +#include "lib/SmartPrint/api/SmartPrint.hpp"
  23 +
  24 +namespace SerialPort
  25 +{
  26 +
  27 + SerialPort::SerialPort() :
  28 + filePath(std::string()),
  29 + baudRate(BaudRates::none),
  30 + fileDesc(0),
  31 + sp(
  32 + new SmartPrint::Sp(
  33 + "Port",
  34 + &std::cout,
  35 + &SmartPrint::Colours::yellow,
  36 + &std::cout,
  37 + &SmartPrint::Colours::yellow,
  38 + &std::cerr,
  39 + &SmartPrint::Colours::red))
  40 + {
  41 + // Everything setup in initialiser list
  42 + }
  43 +
  44 + SerialPort::~SerialPort()
  45 + {
  46 +
  47 + }
  48 +
  49 + void SerialPort::SetFilePath(std::string filePath)
  50 + {
  51 + // Save a pointer to the file path
  52 + this->filePath = filePath;
  53 + }
  54 +
  55 + void SerialPort::SetBaudRate(BaudRates baudRate)
  56 + {
  57 +
  58 + // Get current termios struct
  59 + termios myTermios = this->GetTermios();
  60 +
  61 + switch(baudRate)
  62 + {
  63 + case BaudRates::none:
  64 + // Error, baud rate has not been set yet
  65 + throw std::runtime_error("Baud rate for '" + this->filePath + "' cannot be set to none.");
  66 + break;
  67 + case BaudRates::b9600:
  68 + cfsetispeed(&myTermios, B9600);
  69 + cfsetospeed(&myTermios, B9600);
  70 + break;
  71 + case BaudRates::b57600:
  72 + cfsetispeed(&myTermios, B57600);
  73 + cfsetospeed(&myTermios, B57600);
  74 + break;
  75 + }
  76 +
  77 + // Save back to file
  78 + this->SetTermios(myTermios);
  79 +
  80 + // Setting the baudrate must of been successful, so we can now store this
  81 + // new value internally. This must be done last!
  82 + this->baudRate = baudRate;
  83 + }
  84 +
  85 + void SerialPort::Open()
  86 + {
  87 +
  88 + this->sp->PrintDebug(SmartPrint::Ss() << "Attempting to open COM port \"" << this->filePath << "\".");
  89 +
  90 + if(this->filePath.size() == 0)
  91 + {
  92 + //this->sp->PrintError(SmartPrint::Ss() << "Attempted to open file when file path has not been assigned to.");
  93 + //return false;
  94 +
  95 + throw std::runtime_error("Attempted to open file when file path has not been assigned to.");
  96 + }
  97 +
  98 + // Attempt to open file
  99 + //this->fileDesc = open(this->filePath, O_RDWR | O_NOCTTY | O_NDELAY);
  100 +
  101 + // O_RDONLY for read-only, O_WRONLY for write only, O_RDWR for both read/write access
  102 + // 3rd, optional parameter is mode_t mode
  103 + this->fileDesc = open(this->filePath.c_str(), O_RDWR);
  104 +
  105 + // Check status
  106 + if (this->fileDesc == -1)
  107 + {
  108 + // Could not open COM port
  109 + //this->sp->PrintError(SmartPrint::Ss() << "Unable to open " << this->filePath << " - " << strerror(errno));
  110 + //return false;
  111 +
  112 + throw std::system_error(EFAULT, std::system_category());
  113 + }
  114 +
  115 + this->sp->PrintDebug(SmartPrint::Ss() << "COM port opened successfully.");
  116 +
  117 + // If code reaches here, open and config must of been successful
  118 +
  119 + }
  120 +
  121 + void SerialPort::SetEverythingToCommonDefaults()
  122 + {
  123 + this->sp->PrintDebug(SmartPrint::Ss() << "Configuring COM port \"" << this->filePath << "\".");
  124 +
  125 + //================== CONFIGURE ==================//
  126 +
  127 + termios tty = this->GetTermios();
  128 + /*struct termios tty;
  129 + memset(&tty, 0, sizeof(tty));
  130 +
  131 + // Get current settings (will be stored in termios structure)
  132 + if(tcgetattr(this->fileDesc, &tty) != 0)
  133 + {
  134 + // Error occurred
  135 + this->sp->PrintError(SmartPrint::Ss() << "Could not get terminal attributes for \"" << this->filePath << "\" - " << strerror(errno));
  136 + //return false;
  137 + return;
  138 + }*/
  139 +
  140 + //========================= SET UP BAUD RATES =========================//
  141 +
  142 + this->SetBaudRate(BaudRates::b57600);
  143 +
  144 + /*
  145 + switch(this->baudRate)
  146 + {
  147 + case BaudRates::none:
  148 + // Error, baud rate has not been set yet
  149 + this->sp->PrintError(SmartPrint::Ss() << "Baud rate for \"" << this->filePath << "\" has not been set.");
  150 + return;
  151 + case BaudRates::b9600:
  152 + cfsetispeed(&tty, B9600);
  153 + cfsetospeed(&tty, B9600);
  154 + break;
  155 + case BaudRates::b57600:
  156 + cfsetispeed(&tty, B57600);
  157 + cfsetospeed(&tty, B57600);
  158 + break;
  159 + }*/
  160 +
  161 + //================= (.c_cflag) ===============//
  162 +
  163 + tty.c_cflag &= ~PARENB; // No parity bit is added to the output characters
  164 + tty.c_cflag &= ~CSTOPB; // Only one stop-bit is used
  165 + tty.c_cflag &= ~CSIZE; // CSIZE is a mask for the number of bits per character
  166 + tty.c_cflag |= CS8; // Set to 8 bits per character
  167 + tty.c_cflag &= ~CRTSCTS; // Disable hadrware flow control (RTS/CTS)
  168 + tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
  169 +
  170 +
  171 + //===================== (.c_oflag) =================//
  172 +
  173 + tty.c_oflag = 0; // No remapping, no delays
  174 + tty.c_oflag &= ~OPOST; // Make raw
  175 +
  176 + //================= CONTROL CHARACTERS (.c_cc[]) ==================//
  177 +
  178 + // c_cc[WMIN] sets the number of characters to block (wait) for when read() is called.
  179 + // Set to 0 if you don't want read to block. Only meaningful when port set to non-canonical mode
  180 + //tty.c_cc[VMIN] = 1;
  181 + this->SetNumCharsToWait(1);
  182 +
  183 + // c_cc[VTIME] sets the inter-character timer, in units of 0.1s.
  184 + // Only meaningful when port is set to non-canonical mode
  185 + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
  186 +
  187 +
  188 + //======================== (.c_iflag) ====================//
  189 +
  190 + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
  191 + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
  192 +
  193 + //=========================== LOCAL MODES (c_lflag) =======================//
  194 +
  195 + // Canonical input is when read waits for EOL or EOF characters before returning. In non-canonical mode, the rate at which
  196 + // read() returns is instead controlled by c_cc[VMIN] and c_cc[VTIME]
  197 + tty.c_lflag &= ~ICANON; // Turn off canonical input, which is suitable for pass-through
  198 + tty.c_lflag &= ~ECHO; // Turn off echo
  199 + tty.c_lflag &= ~ECHOE; // Turn off echo erase (echo erase only relevant if canonical input is active)
  200 + tty.c_lflag &= ~ECHONL; //
  201 + tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters
  202 +
  203 + // Try and use raw function call
  204 + //cfmakeraw(&tty);
  205 +
  206 + this->SetTermios(tty);
  207 +
  208 + /*
  209 + // Flush port, then apply attributes
  210 + tcflush(this->fileDesc, TCIFLUSH);
  211 +
  212 + if(tcsetattr(this->fileDesc, TCSANOW, &tty) != 0)
  213 + {
  214 + // Error occurred
  215 + this->sp->PrintError(SmartPrint::Ss() << "Could not apply terminal attributes for \"" << this->filePath << "\" - " << strerror(errno));
  216 + return;
  217 + }*/
  218 + }
  219 +
  220 + void SerialPort::SetNumCharsToWait(uint32_t numCharsToWait)
  221 + {
  222 + // Get current termios struct
  223 + termios myTermios = this->GetTermios();
  224 +
  225 + // Save the number of characters to wait for
  226 + // to the control register
  227 + myTermios.c_cc[VMIN] = numCharsToWait;
  228 +
  229 + // Save termios back
  230 + this->SetTermios(myTermios);
  231 + }
  232 +
  233 + void SerialPort::Write(std::string* str)
  234 + {
  235 + if(this->fileDesc == 0)
  236 + {
  237 + //this->sp->PrintError(SmartPrint::Ss() << );
  238 + //return false;
  239 +
  240 + throw std::runtime_error("SendMsg called but file descriptor (fileDesc) was 0, indicating file has not been opened.");
  241 + }
  242 +
  243 + int writeResult = write(this->fileDesc, str->c_str(), str->size());
  244 +
  245 + // Check status
  246 + if (writeResult == -1)
  247 + {
  248 + // Could not open COM port
  249 + //this->sp->PrintError(SmartPrint::Ss() << "Unable to write to \"" << this->filePath << "\" - " << strerror(errno));
  250 + //return false;
  251 +
  252 + throw std::system_error(EFAULT, std::system_category());
  253 + }
  254 +
  255 + // If code reaches here than write must of been successful
  256 + }
  257 +
  258 + void SerialPort::Read(std::string* str)
  259 + {
  260 + if(this->fileDesc == 0)
  261 + {
  262 + //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened.");
  263 + //return false;
  264 + throw std::runtime_error("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened.");
  265 + }
  266 +
  267 + // Allocate memory for read buffer
  268 + char buf [256];
  269 + memset (&buf, '\0', sizeof buf);
  270 +
  271 + // Read from file
  272 + int n = read(this->fileDesc, &buf, sizeof(buf));
  273 +
  274 + // Error Handling
  275 + if(n < 0)
  276 + {
  277 + // Could not open COM port
  278 + //this->sp->PrintError(SmartPrint::Ss() << "Unable to read from \"" << this->filePath << "\" - " << strerror(errno));
  279 + //return false;
  280 +
  281 + throw std::system_error(EFAULT, std::system_category());
  282 + }
  283 +
  284 + if(n > 0)
  285 + {
  286 + //this->sp->PrintDebug(SmartPrint::Ss() << "\"" << n << "\" characters have been read from \"" << this->filePath << "\"");
  287 + // Characters have been read
  288 + buf[n] = '\0';
  289 + //printf("%s\r\n", buf);
  290 + str->append(buf);
  291 + //std::cout << *str << " and size of string =" << str->size() << "\r\n";
  292 + }
  293 +
  294 + // If code reaches here, read must of been successful
  295 + }
  296 +
  297 + termios SerialPort::GetTermios()
  298 + {
  299 + struct termios tty;
  300 + memset(&tty, 0, sizeof(tty));
  301 +
  302 + // Get current settings (will be stored in termios structure)
  303 + if(tcgetattr(this->fileDesc, &tty) != 0)
  304 + {
  305 + // Error occurred
  306 + this->sp->PrintError(SmartPrint::Ss() << "Could not get terminal attributes for \"" << this->filePath << "\" - " << strerror(errno));
  307 + throw std::system_error(EFAULT, std::system_category());
  308 + //return false;
  309 + }
  310 +
  311 + return tty;
  312 + }
  313 +
  314 + void SerialPort::SetTermios(termios myTermios)
  315 + {
  316 + // Flush port, then apply attributes
  317 + tcflush(this->fileDesc, TCIFLUSH);
  318 +
  319 + if(tcsetattr(this->fileDesc, TCSANOW, &myTermios) != 0)
  320 + {
  321 + // Error occurred
  322 + this->sp->PrintError(SmartPrint::Ss() << "Could not apply terminal attributes for \"" << this->filePath << "\" - " << strerror(errno));
  323 + throw std::system_error(EFAULT, std::system_category());
  324 +
  325 + }
  326 +
  327 + // Successful!
  328 + }
  329 +
  330 +} // namespace ComPort
... ...