diff --git a/build-API.sh b/build-API.sh index 3efa949..07c175b 100644 --- a/build-API.sh +++ b/build-API.sh @@ -22,6 +22,7 @@ rm include_tmp.h cat include/functions.h >> gnublin.h +cat drivers/driver.h >> gnublin.h cat drivers/gpio.h >> gnublin.h cat drivers/i2c.h >> gnublin.h cat drivers/spi.h >> gnublin.h @@ -52,6 +53,7 @@ echo "//******************************************** cat include/functions.cpp >> gnublin.cpp +cat drivers/driver.cpp >> gnublin.cpp cat drivers/gpio.cpp >> gnublin.cpp cat drivers/i2c.cpp >> gnublin.cpp cat drivers/spi.cpp >> gnublin.cpp diff --git a/drivers/adc.cpp b/drivers/adc.cpp index 0e43ec2..a0252c6 100644 --- a/drivers/adc.cpp +++ b/drivers/adc.cpp @@ -18,45 +18,9 @@ gnublin_adc::gnublin_adc(){ sleep(1); } file.close(); - error_flag = false; + clearError(); } -//-------------fail------------- -/** @~english -* @brief Returns the error flag. -* -* If something went wrong, the flag is true. -* @return bool error_flag -* -* @~german -* @brief Gibt das Error Flag zurück. -* -* Falls das Error Flag in der Klasse gesetzt wurde, wird true zurück gegeben, anderenfalls false. -* @return bool error_flag -*/ -bool gnublin_adc::fail(){ - return error_flag; -} - - -//-------------getErrorMessage------------- -/** @~english -* @brief Get the last Error Message. -* -* This Funktion returns the last Error Message, which occurred in that Class. -* @return ErrorMessage as c-string -* -* @~german -* @brief Gibt die letzte Error Nachricht zurück. -* -* Diese Funktion gibt die Letzte Error Nachricht zurück, welche in dieser Klasse gespeichert wurde. -* @return ErrorMessage als c-string -*/ -const char *gnublin_adc::getErrorMessage(){ - return ErrorMessage.c_str(); -} - - //-------------getValue------------- /** @~english * @brief Get Value. @@ -78,16 +42,14 @@ int gnublin_adc::getValue(int pin){ std::string pin_str = numberToString(pin); std::string device = "/dev/lpc313x_adc"; std::ofstream file(device.c_str()); - if (file < 0) { - error_flag = true; - return -1; - } + if (file < 0) + return setErrorMessage("Unable to open "+device); file << pin_str; file.close(); std::ifstream dev_file(device.c_str()); dev_file >> value; dev_file.close(); - error_flag = false; + clearError(); return hexstringToNumber(value); } @@ -126,7 +88,7 @@ int gnublin_adc::getVoltage(int pin){ * @return Erfolg: 1, Fehler: -1 */ int gnublin_adc::setReference(int ref){ - error_flag = false; + clearError(); return 1; } diff --git a/drivers/adc.h b/drivers/adc.h index f744c37..1cc8663 100644 --- a/drivers/adc.h +++ b/drivers/adc.h @@ -15,17 +15,14 @@ * * Mit der gnublin_adc API lassen sich die GPAs auf dem GNUBLIN einfach aus dem eigenem Programm heraus auslesen. */ -class gnublin_adc { +class gnublin_adc : public gnublin_driver { public: gnublin_adc(); int getValue(int pin); int getVoltage(int pin); int setReference(int ref); - bool fail(); - const char *getErrorMessage(); private: - bool error_flag; - std::string ErrorMessage; + void onError() {}; }; #endif diff --git a/drivers/driver.cpp b/drivers/driver.cpp new file mode 100644 index 0000000..93e5988 --- /dev/null +++ b/drivers/driver.cpp @@ -0,0 +1,87 @@ +#include "driver.h" + +//******************************************************************* +//Class for accessing GNUBLIN i2c Bus +//******************************************************************* + +//------------------Konstruktor------------------ +/** @~english +* @brief Sets the error_flag to "false" and the devicefile to "/dev/i2c-1" +* +* @~german +* @brief Setzt das error_flag auf "false" und das devicefile auf standardmäßig "/dev/i2c-1" +* +*/ +gnublin_driver::gnublin_driver() +{ + error_flag=false; + ErrorMessage=""; +} + +//------------------error messaging------------------ +/** @~english +* @brief Called by the constructors to initialize class variables. +* +* @param message String contents that describe the error. +* @return failure: -1 +* +* @~german +* @brief Wird von den Konstruktoren der Klasse Variablen zu initialisieren. +* +* @param message String Inhalte, die den Fehler beschreiben. +* @return failure: -1 +* +*/ +int gnublin_driver::setErrorMessage(std::string message) +{ + ErrorMessage=message; + error_flag=true; + return -1; +} + +//------------------error messaging------------------ +/** @~english +* @brief Resets the error_flag and other associated details. +* +* @~german +* @brief Setzt die error_flag und anderen damit verbundenen Informationen. +* +*/ +void gnublin_driver::clearError() +{ + ErrorMessage=""; + error_flag=false; +} + +//-------------------------------Fail------------------------------- +/** @~english +* @brief returns the error flag to check if the last operation went wrong +* +* @return error_flag as boolean +* +* @~german +* @brief Gibt das error_flag zurück um zu überprüfen ob die vorangegangene Operation einen Fehler auweist +* +* @return error_flag als bool +*/ +bool gnublin_driver::fail(){ + return error_flag; +} + +//-------------get Error Message------------- +/** @~english +* @brief Get the last Error Message. +* +* This function returns the last Error Message, which occurred in that Class. +* @return ErrorMessage as c-string +* +* @~german +* @brief Gibt die letzte Error Nachricht zurück. +* +* Diese Funktion gibt die Letzte Error Nachricht zurück, welche in dieser Klasse gespeichert wurde. +* @return ErrorMessage als c-string +*/ +const char *gnublin_driver::getErrorMessage(){ + return ErrorMessage.c_str(); +} + diff --git a/drivers/driver.h b/drivers/driver.h new file mode 100644 index 0000000..2d682a1 --- /dev/null +++ b/drivers/driver.h @@ -0,0 +1,28 @@ +#include "../include/includes.h" +//******************************************************************* +//Class for accessing GNUBLIN i2c Bus +//******************************************************************* +/** +* @class gnublin_i2c +* @~english +* @brief Class for accessing GNUBLIN i2c bus +* +* The GNUBLIN I2C bus can easily accessed with this class +* @~german +* @brief Klasse für den zugriff auf den GNUBLIN I2C Bus +* +* Die GNUBLIN I2C Klasse gewährt einfachen Zugriff auf den I2C Bus +*/ + +class gnublin_driver { + bool error_flag; + std::string ErrorMessage; + virtual void onError() = 0; +protected: + gnublin_driver(); +public: + bool fail(); + int setErrorMessage(std::string message); + const char *getErrorMessage(); + void clearError(); +}; diff --git a/drivers/gpio.cpp b/drivers/gpio.cpp index b639134..36619c8 100644 --- a/drivers/gpio.cpp +++ b/drivers/gpio.cpp @@ -1,4 +1,5 @@ #include "gpio.h" +#include "driver.h" /** @~english * @brief Reset the ErrorFlag. @@ -7,8 +8,7 @@ * @brief Setzt das ErrorFlag zurück. * */ -gnublin_gpio::gnublin_gpio(){ - error_flag = false; +gnublin_gpio::gnublin_gpio() : gnublin_driver() { } @@ -29,49 +29,15 @@ int gnublin_gpio::unexport(int pin){ std::string pin_str = numberToString(pin); std::string dir = "/sys/class/gpio/unexport"; std::ofstream file (dir.c_str()); - if (file < 0) { - error_flag = true; - return -1; - } + if (file < 0) + return setErrorMessage("Unable to open " + dir +"\n"); file << pin_str; file.close(); - error_flag = false; + clearError(); return 1; } -/** @~english -* @brief Returns the error flag. -* -* If something went wrong, the flag is true. -* @return bool error_flag -* -* @~german -* @brief Gibt das Error Flag zurück. -* -* Falls das Error Flag in der Klasse gesetzt wurde, wird true zurück gegeben, anderenfalls false. -* @return bool error_flag -*/ -bool gnublin_gpio::fail(){ - return error_flag; -} - -/** @~english -* @brief Get the last Error Message. -* -* This Funktion returns the last Error Message, which occurred in that Class. -* @return ErrorMessage as c-string -* -* @~german -* @brief Gibt die letzte Error Nachricht zurück. -* -* Diese Funktion gibt die Letzte Error Nachricht zurück, welche in dieser Klasse gespeichert wurde. -* @return ErrorMessage als c-string -*/ -const char *gnublin_gpio::getErrorMessage(){ - return ErrorMessage.c_str(); -} - /** @~english * @brief Change the PinMode. * @@ -94,31 +60,26 @@ const char *gnublin_gpio::getErrorMessage(){ */ int gnublin_gpio::pinMode(int pin, std::string direction){ #if (BOARD != RASPBERRY_PI) - if (pin == 4 && direction == "out"){ - error_flag = true; - return -1; - } + if (pin == 4 && direction == "out") + return setErrorMessage("Pin 4 can not be set to 'out'\n"); #endif std::string pin_str = numberToString(pin); std::string dir = "/sys/class/gpio/export"; std::ofstream file (dir.c_str()); - if (file < 0) { - error_flag = true; - return -1; - } + if (file < 0) + return setErrorMessage("Unable to open " + dir + "\n"); file << pin; file.close(); dir = "/sys/class/gpio/gpio" + pin_str + "/direction"; file.open(dir.c_str()); - if (file < 0) { - error_flag = true; - return -1; - } + if (file < 0) + return setErrorMessage("Unable to open " + dir + "\n"); file << direction; file.close(); - error_flag = false; + + clearError(); return 1; } @@ -141,27 +102,21 @@ int gnublin_gpio::pinMode(int pin, std::string direction){ */ int gnublin_gpio::digitalWrite(int pin, int value){ #if (BOARD != RASPBERRY_PI) - if (pin == 4){ - error_flag = true; - return -1; - } + if (pin == 4) + return setErrorMessage("Pin 4 is not available for usage\n"); #endif - if (value != 0 && value != 1){ - error_flag = true; - return -1; - } + if (value != 0 && value != 1) + return setErrorMessage("Value ["+numberToString(value)+"] must be 0 or 1\n"); std::string value_str = numberToString(value); std::string pin_str = numberToString(pin); std::string dir = "/sys/class/gpio/gpio" + pin_str + "/value"; std::ofstream file (dir.c_str()); - if (file < 0) { - error_flag = true; - return -1; - } + if (file < 0) + return setErrorMessage("Unable to open " + dir + "\n"); file << value_str; file.close(); - error_flag = false; + clearError(); return 1; } @@ -185,13 +140,11 @@ int gnublin_gpio::digitalRead(int pin) { std::string pin_str = numberToString(pin); std::string device = "/sys/class/gpio/gpio" + pin_str + "/value"; std::ifstream file(device.c_str()); - if (file < 0){ - error_flag = true; - return -1; - } + if (file < 0) + return setErrorMessage("Unable to open " + device + "\n"); file >> value; file.close(); - error_flag = false; + clearError(); return stringToNumber(value); } diff --git a/drivers/gpio.h b/drivers/gpio.h index 4fbbbe0..0fb7a9e 100644 --- a/drivers/gpio.h +++ b/drivers/gpio.h @@ -1,5 +1,4 @@ #include "../include/includes.h" - /** * @class gnublin_gpio * @~english @@ -11,16 +10,12 @@ * * Mit der gnublin_gpio API lassen sich die GPIO-Ports auf dem GNUBLIN einfach aus dem eigenem Programm heraus ansteuern. */ -class gnublin_gpio { +class gnublin_gpio : public gnublin_driver { public: gnublin_gpio(); - bool fail(); int pinMode(int pin, std::string direction); //Defines GPIO as INPUT or OUTPUT int digitalWrite(int pin, int value); //Writes value on GPIO int digitalRead(int pin); //Reads value from GPIO int unexport(int pin); - const char *getErrorMessage(); - private: - bool error_flag; - std::string ErrorMessage; + void onError() {}; }; diff --git a/drivers/i2c.cpp b/drivers/i2c.cpp index 867e105..dc7a698 100644 --- a/drivers/i2c.cpp +++ b/drivers/i2c.cpp @@ -4,33 +4,149 @@ //Class for accessing GNUBLIN i2c Bus //******************************************************************* -//------------------Konstruktor------------------ +//------------------local defines----------------- /** @~english -* @brief Sets the error_flag to "false" and the devicefile to "/dev/i2c-1" +* @brief creates macro reference for default device "/dev/i2c-1" * * @~german -* @brief Setzt das error_flag auf "false" und das devicefile auf standardmäßig "/dev/i2c-1" +* @brief schafft Makro Referenz für Standard-Gerät "/ dev/i2c-1" * */ -gnublin_i2c::gnublin_i2c() +#define DEFAULTDEVICE "/dev/i2c-1" + +//------------------Konstruktor------------------ +/** @~english +* @brief Sets the devicefile to "/dev/i2c-1" +* +* @~german +* @brief Setzt das devicefile auf standardmäßig "/dev/i2c-1" +* +*/ +gnublin_i2c::gnublin_i2c() : gnublin_driver() { - devicefile="/dev/i2c-1"; - error_flag=false; + init(DEFAULTDEVICE, -1); } -//-------------------------------Fail------------------------------- -/** @~english -* @brief returns the error flag to check if the last operation went wrong +//------------------Konstruktor------------------ +/** @~english +* @brief Sets the devicefile to "/dev/i2c-1" * -* @return error_flag as boolean +* @~german +* @brief Setzt das devicefile auf standardmäßig "/dev/i2c-1" * -* @~german -* @brief Gibt das error_flag zurück um zu überprüfen ob die vorangegangene Operation einen Fehler auweist +*/ +gnublin_i2c::gnublin_i2c(int Address) : gnublin_driver() +{ + init(DEFAULTDEVICE, Address); +} + +//------------------Konstruktor------------------ +/** @~english +* @brief Sets the devicefile to "/dev/i2c-1" +* +* @~german +* @brief Setzt das devicefile auf standardmäßig "/dev/i2c-1" +* +*/ +gnublin_i2c::gnublin_i2c(std::string Devicefile, int Address) : gnublin_driver() +{ + init(Devicefile, Address); +} + +//------------------destructor------------------ +/** @~english +* @brief Closes the file handle +* +* @~german +* @brief Schließt die Datei Griff * -* @return error_flag als bool */ -bool gnublin_i2c::fail(){ - return error_flag; +gnublin_i2c::~gnublin_i2c() +{ + close_fd(); +} + +//------------------init------------------ +/** @~english +* @brief Called by the constructors to initialize class variables. +* +* @~german +* @brief Wird von den Konstruktoren der Klasse Variablen zu initialisieren. +* +*/ +void gnublin_i2c::init(std::string Devicefile, int Address) +{ + devicefile=Devicefile; + slave_address = Address; + fd = 0; +} + +//------------------Error message------------------ +/** @~english +* @brief Closes the file if open and resets the variable. +* called from base class when error message is set +* +* @~german +* @brief Schließt die Datei, wenn offen und setzt die Variable. +* Wird aufgerufen, wenn Fehlermeldung Basisklasse eingestellt ist. +* +*/ +void gnublin_i2c::onError() +{ + close_fd(); +} + +//------------------close file descriptor------------------ +/** @~english +* @brief Closes the file if open and resets the variable. +* +* @~german +* @brief Schließt die Datei, wenn offen und setzt die Variable. +* +*/ +void gnublin_i2c::close_fd() +{ + if (fd) { + close(fd); + fd = 0; + } +} + +//------------------open file descriptor------------------ +/** @~english +* @brief if a file is already open it is closed first. A new file is opened +* and io operations defined based on the class values for devicefile +* and slave_address. +* +* @return failure: -1 +* +* @~german +* @brief wenn eine Datei bereits geöffnet ist, wird es zunächst geschlossen. +* Eine neue Datei wird geöffnet und IO-Operationen werden auf Basis der Klasse +* Werte für Device-Datei und Slave_Address definiert. +* +* @return failure: -1 +* +*/ +int gnublin_i2c::open_fd() +{ + clearError(); + + if (fd) { + close_fd(); + fd = 0; + } + + if (slave_address == -1) + return setErrorMessage("ERROR slave address is not set\n"); + + if ((fd = open(devicefile.c_str(), O_RDWR)) < 0) + return setErrorMessage("ERROR opening: " + devicefile + "\n"); + + if (ioctl(fd, I2C_SLAVE, slave_address) < 0) + return setErrorMessage("ERROR address: " + numberToString(slave_address) + "\n"); + + return 0; } //-------------set Address------------- @@ -39,15 +155,18 @@ bool gnublin_i2c::fail(){ * * With this function you can set the individual I2C Slave-Address. * @param Address new I2C slave Address +* @return failure: -1 * * @~german * @brief Setzt die i2c slave Adresse * * Mit dieser Funktion kann die individuelle I2C Slave-Adresse gesetzt werden. * @param Address neue I2C slave Adresse +* @return failure: -1 */ -void gnublin_i2c::setAddress(int Address){ +int gnublin_i2c::setAddress(int Address){ slave_address = Address; + return open_fd(); } //-------------get Address------------- @@ -67,38 +186,24 @@ int gnublin_i2c::getAddress(){ return slave_address; } -//-------------get Error Message------------- -/** @~english -* @brief Get the last Error Message. -* -* This function returns the last Error Message, which occurred in that Class. -* @return ErrorMessage as c-string -* -* @~german -* @brief Gibt die letzte Error Nachricht zurück. -* -* Diese Funktion gibt die Letzte Error Nachricht zurück, welche in dieser Klasse gespeichert wurde. -* @return ErrorMessage als c-string -*/ -const char *gnublin_i2c::getErrorMessage(){ - return ErrorMessage.c_str(); -} - //-------------------set devicefile---------------- /** @~english * @brief set i2c the device file. default is "/dev/i2c-1" * * This function sets the devicefile you want to access. by default "/dev/i2c-1" is set. * @param filename path to the devicefile e.g. "/dev/i2c-0" +* @return failure: -1 * * @~german * @brief setzt die I2C Device Datei. Standard ist die "/dev/i2c-1" * * Diese Funktion setzt die Geräte Datei, auf die man zugreifen möchte. Standardmäßig ist bereits "/dev/i2c-1" gesetzt. * @param filename Dateipfad zur Geräte Datei, z.B. "/dev/i2c-0" +* @return failure: -1 */ -void gnublin_i2c::setDevicefile(std::string filename){ +int gnublin_i2c::setDevicefile(std::string filename){ devicefile = filename; + return open_fd(); } @@ -126,32 +231,21 @@ void gnublin_i2c::setDevicefile(std::string filename){ * @return Erfolg: 1, Misserfolg: -1 */ int gnublin_i2c::receive(unsigned char *RxBuf, int length){ - error_flag=false; - int fd; + if (RxBuf == 0) + return setErrorMessage("Receive method received a null TxBuf pointer.\n"); + if (length < 1) + return setErrorMessage("Receive method received an invalid buffer length.\n"); - if ((fd = open(devicefile.c_str(), O_RDWR)) < 0) { - ErrorMessage="ERROR opening: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (ioctl(fd, I2C_SLAVE, slave_address) < 0) { - ErrorMessage="ERROR address: " + numberToString(slave_address) + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (read(fd, RxBuf, length) != length){ - ErrorMessage="i2c read error! Address: " + numberToString(slave_address) + " dev file: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } + if (!fd) + if (open_fd() == -1) + return -1; + + clearError(); + + if (read(fd, RxBuf, length) != length) + return setErrorMessage("i2c read error! Address: " + numberToString(slave_address) + " dev file: " + devicefile + "\n"); - close(fd); return 1; } @@ -187,39 +281,24 @@ int gnublin_i2c::receive(unsigned char *RxBuf, int length){ * @return Erfolg: 1, Misserfolg: -1 */ int gnublin_i2c::receive(unsigned char RegisterAddress, unsigned char *RxBuf, int length){ - error_flag=false; - int fd; - - if ((fd = open(devicefile.c_str(), O_RDWR)) < 0) { - ErrorMessage="ERROR opening: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (ioctl(fd, I2C_SLAVE, slave_address) < 0) { - ErrorMessage="ERROR address: " + numberToString(slave_address) + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (write(fd, &RegisterAddress, 1) != 1){ - ErrorMessage="i2c write error!\n"; - error_flag=true; - close(fd); - return -1; - } + if (RxBuf == 0) + return setErrorMessage("Receive method received a null TxBuf pointer.\n"); + if (length < 1) + return setErrorMessage("Receive method received an invalid buffer length.\n"); - if (read(fd, RxBuf, length) != length){ - ErrorMessage="i2c read error! Address: " + numberToString(slave_address) + " dev file: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } + if (!fd) + if (open_fd() == -1) + return -1; + + clearError(); + + if (write(fd, &RegisterAddress, 1) != 1) + return setErrorMessage("i2c write error!\n"); + + if (read(fd, RxBuf, length) != length) + return setErrorMessage("i2c read error! Address: " + numberToString(slave_address) + " dev file: " + devicefile + "\n"); - close(fd); return 1; } @@ -247,31 +326,21 @@ int gnublin_i2c::receive(unsigned char RegisterAddress, unsigned char *RxBuf, in * @return Erfolg: 1, Misserfolg: -1 */ int gnublin_i2c::send(unsigned char *TxBuf, int length){ - error_flag=false; - int fd; - - if ((fd = open(devicefile.c_str(), O_RDWR)) < 0) { - ErrorMessage="ERROR opening: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (ioctl(fd, I2C_SLAVE, slave_address) < 0) { - ErrorMessage="ERROR address: " + numberToString(slave_address) + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if(write(fd, TxBuf, length) != length){ - ErrorMessage="i2c write error!\n"; - error_flag=true; - close(fd); - return -1; - } - close(fd); + if (TxBuf == 0) + return setErrorMessage("Send method received a null TxBuf pointer.\n"); + if (length < 1) + return setErrorMessage("Send method received an invalid buffer length.\n"); + + if (!fd) + if (open_fd() == -1) + return -1; + + clearError(); + + if(write(fd, TxBuf, length) != length) + return setErrorMessage("i2c write error!\n"); + return 1; } @@ -307,38 +376,24 @@ int gnublin_i2c::send(unsigned char *TxBuf, int length){ * @return Erfolg: 1, Misserfolg: -1 */ int gnublin_i2c::send(unsigned char RegisterAddress, unsigned char *TxBuf, int length){ - error_flag=false; - int fd, i; - unsigned char data[length+1]; - data[0]=RegisterAddress; - - for ( i = 0; i < length ; i++ ) { - data[ i + 1 ] = (char)TxBuf[ i ]; - } - - if ((fd = open(devicefile.c_str(), O_RDWR)) < 0) { - ErrorMessage="ERROR opening: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (ioctl(fd, I2C_SLAVE, slave_address) < 0) { - ErrorMessage="ERROR address: " + numberToString(slave_address) + "\n"; - error_flag=true; - close(fd); - return -1; - } - - - if(write(fd, data, length+1) != length+1){ - ErrorMessage="i2c write error!\n"; - error_flag=true; - close(fd); + + if (TxBuf == 0) + return setErrorMessage("Send method received a null TxBuf pointer.\n"); + if (length < 1) + return setErrorMessage("Send method received an invalid buffer length.\n"); + + if (!fd) + if (open_fd() == -1) + return -1; + + clearError(); + + if (send(RegisterAddress) == -1) return -1; - } - close(fd); + if(write(fd, TxBuf, length) != length) + return setErrorMessage("i2c write error!\n"); + return 1; } @@ -363,33 +418,16 @@ int gnublin_i2c::send(unsigned char RegisterAddress, unsigned char *TxBuf, int l * @param value Byte das gesendet wird. * @return Erfolg: 1, Misserfolg: -1 */ -int gnublin_i2c::send(int value){ - error_flag=false; - int buffer[1]; - buffer[0]=value; - int fd; - - if ((fd = open(devicefile.c_str(), O_RDWR)) < 0) { - ErrorMessage="ERROR opening: " + devicefile + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if (ioctl(fd, I2C_SLAVE, slave_address) < 0) { - ErrorMessage="ERROR address: " + numberToString(slave_address) + "\n"; - error_flag=true; - close(fd); - return -1; - } - - if(write(fd, buffer, 1) != 1){ - ErrorMessage="i2c write error!\n"; - error_flag=true; - close(fd); - return -1; - } +int gnublin_i2c::send(unsigned char value){ + + if (!fd) + if (open_fd() == -1) + return -1; + + clearError(); + + if(write(fd, &value, 1) != 1) + return setErrorMessage("i2c write error!\n"); - close(fd); return 1; } diff --git a/drivers/i2c.h b/drivers/i2c.h index 107a73b..eb2abfe 100644 --- a/drivers/i2c.h +++ b/drivers/i2c.h @@ -1,4 +1,5 @@ #include "../include/includes.h" +#include "driver.h" //******************************************************************* //Class for accessing GNUBLIN i2c Bus //******************************************************************* @@ -14,21 +15,25 @@ * Die GNUBLIN I2C Klasse gewährt einfachen Zugriff auf den I2C Bus */ -class gnublin_i2c { - bool error_flag; +class gnublin_i2c : public gnublin_driver { int slave_address; std::string devicefile; - std::string ErrorMessage; + int fd; + int open_fd(); + void close_fd(); + void init(std::string DeviceFile, int Address); + void onError(); public: gnublin_i2c(); - bool fail(); - void setAddress(int Address); + gnublin_i2c(int Address); + gnublin_i2c(std::string DeviceFile, int Address); + ~gnublin_i2c(); + int setAddress(int Address); int getAddress(); - const char *getErrorMessage(); - void setDevicefile(std::string filename); + int setDevicefile(std::string filename); int receive(unsigned char *RxBuf, int length); int receive(unsigned char RegisterAddress, unsigned char *RxBuf, int length); int send(unsigned char *TxBuf, int length); int send(unsigned char RegisterAddress, unsigned char *TxBuf, int length); - int send(int value); + int send(unsigned char value); }; diff --git a/drivers/spi.cpp b/drivers/spi.cpp index a608709..8f61d12 100644 --- a/drivers/spi.cpp +++ b/drivers/spi.cpp @@ -1,6 +1,5 @@ #include "spi.h" - //*************************************************************************** // Class for accessing the SPI-Bus //*************************************************************************** @@ -19,8 +18,8 @@ * GNUBLIN: CS = 11 * RASPBERRY PI: CS = 0 */ -gnublin_spi::gnublin_spi(){ - error_flag = false; +gnublin_spi::gnublin_spi() : gnublin_driver() +{ #if BOARD == RASPBERRY_PI std::string device = "/dev/spidev0.0"; #else @@ -35,6 +34,8 @@ gnublin_spi::gnublin_spi(){ #endif sleep(1); fd = open(device.c_str(), O_RDWR); + if (fd < 0) + setErrorMessage("Unable to open file "+device+"\n"); } } @@ -45,41 +46,6 @@ gnublin_spi::~gnublin_spi(){ close(fd); } - -//******************** fail() *********************************************** -/** -* @~english -* @brief Returns the errorflag to detect error in the previous called method. -* -* @return error_flag -* -* @~german -* @brief Gibt das errorflag zurück, um Fehler in der zuvor aufgerugfenen Methode zu erkennen. -* -* @return error_flag -*/ -bool gnublin_spi::fail(){ - return error_flag; -} - - -//-------------get Error Message------------- -/** -* @~english -* @brief Returns the ErrorMessage of the previous error if one exist. -* -* @return ErrorMessage as C-String -* -* @~german -* @brief Gibt die Fehlernachricht des zuvor aufgetretenen Fehlers zurück, wenn weine exisitert. -* -* @return ErrorMessage als C-String -*/ -const char *gnublin_spi::getErrorMessage(){ - return ErrorMessage.c_str(); -} - - //*********************** setCS ********************************************* /** @@ -108,12 +74,10 @@ int gnublin_spi::setCS(int cs){ system(command.c_str()); sleep(1); fd = open(device.c_str(), O_RDWR); - if (fd < 0){ - error_flag = true; - return -1; - } + if (fd < 0) + return setErrorMessage("Unable to open file "+device+"\n"); } - error_flag = false; + clearError(); return 1; } @@ -134,11 +98,9 @@ int gnublin_spi::setCS(int cs){ * @return 1 bei Erfolg, -1 im Fehlerfall */ int gnublin_spi::setMode(unsigned char mode){ - if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return 1; } @@ -158,11 +120,9 @@ int gnublin_spi::setMode(unsigned char mode){ */ int gnublin_spi::getMode(){ __u8 mode; - if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return mode; } @@ -183,11 +143,9 @@ int gnublin_spi::getMode(){ * @return 1 bei Erfolg, -1 im Fehlerfall */ int gnublin_spi::setLSB(unsigned char lsb){ - if (ioctl(fd, SPI_IOC_WR_LSB_FIRST, &lsb) < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_WR_LSB_FIRST, &lsb) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return 1; } @@ -207,11 +165,9 @@ int gnublin_spi::setLSB(unsigned char lsb){ */ int gnublin_spi::getLSB(){ __u8 lsb; - if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) { - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return lsb; } @@ -232,11 +188,9 @@ int gnublin_spi::getLSB(){ * @return 1 bei Erfolg, -1 im Fehlerfall */ int gnublin_spi::setLength(unsigned char bits){ - if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return 1; } @@ -256,11 +210,9 @@ int gnublin_spi::setLength(unsigned char bits){ */ int gnublin_spi::getLength(){ __u8 bits; - if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return bits; } @@ -281,11 +233,9 @@ int gnublin_spi::getLength(){ * @return 1 bei Erfolg, -1 im Fehlerfall */ int gnublin_spi::setSpeed(unsigned int speed){ - if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0){ - error_flag = true; - return -1; - } - error_flag = true; + if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return 1; } @@ -305,11 +255,9 @@ int gnublin_spi::setSpeed(unsigned int speed){ */ int gnublin_spi::getSpeed(){ __u32 speed; - if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) + return setErrorMessage("ioctl failed."); + clearError(); return speed; } @@ -331,11 +279,9 @@ int gnublin_spi::getSpeed(){ * @return 1 bei Erfolg, -1 im Fehlerfall */ int gnublin_spi::receive(char* buffer, int len){ - if (read(fd, buffer, len) < 0) { - error_flag = true; - return -1; - } - error_flag = false; + if (read(fd, buffer, len) < 0) + return setErrorMessage("read failed."); + clearError(); return 1; } @@ -366,11 +312,9 @@ int gnublin_spi::send(unsigned char* tx, int length){ xfer.speed_hz = 0; xfer.bits_per_word = 0; status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer); - if ( status < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if ( status < 0) + return setErrorMessage("ioctl status shows failure."); + clearError(); return 1; } @@ -414,11 +358,9 @@ int gnublin_spi::message(unsigned char* tx, int tx_length, unsigned char* rx, in xfer[1].bits_per_word = 0; status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer); - if (status < 0){ - error_flag = true; - return -1; - } - error_flag = false; + if (status < 0) + return setErrorMessage("ioctl status shows failure."); + clearError(); return 1; } diff --git a/drivers/spi.h b/drivers/spi.h index 81d521e..3e80fff 100644 --- a/drivers/spi.h +++ b/drivers/spi.h @@ -1,5 +1,5 @@ #include "../include/includes.h" - +#include "driver.h" //*************************************************************************** // Class for accessing the SPI-Bus //*************************************************************************** @@ -15,7 +15,7 @@ * * Diese Klasse ermöglicht das Senden und Empfangen von Daten über den SPI-Bus. */ -class gnublin_spi{ +class gnublin_spi : gnublin_driver { public: gnublin_spi(); ~gnublin_spi(); @@ -31,11 +31,7 @@ class gnublin_spi{ int send(unsigned char* tx, int length); int setCS(int cs); int message(unsigned char* tx, int tx_length, unsigned char* rx, int rx_length); - const char *getErrorMessage(); - bool fail(); private: int fd; - bool error_flag; - std::string ErrorMessage; - + void onError() {}; };