parent
37539d3f06
commit
7edfa19d78
Binary file not shown.
@ -0,0 +1,551 @@
|
|||||||
|
#include "gpio.hpp"
|
||||||
|
#include "../../systems/systemCall.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define PIN_COUNT 26
|
||||||
|
|
||||||
|
class Gpio::gpioImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t pinCount = PIN_COUNT;
|
||||||
|
char buffer[50];
|
||||||
|
uint8_t currentPin = 0;
|
||||||
|
int ck = 0;
|
||||||
|
|
||||||
|
std::ifstream bufFile;
|
||||||
|
|
||||||
|
pinDefinition pins[PIN_COUNT + 1];
|
||||||
|
|
||||||
|
gpioImpl()
|
||||||
|
{
|
||||||
|
checkCurrentPins();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFunction(uint8_t gpioNo, Gpio::pinFunction function)
|
||||||
|
{
|
||||||
|
pinInitiate(gpioNo);
|
||||||
|
|
||||||
|
switch(pins[gpioNo].function)
|
||||||
|
{
|
||||||
|
case passive:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case gpio:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case i2c:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case spi:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case pwm:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case pcm:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case uart:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case eeprom:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
case clk:
|
||||||
|
pins[gpioNo].function = function;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMode(uint8_t gpioNo, Gpio::pinMode mode)
|
||||||
|
{
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case input:
|
||||||
|
sprintf(buffer, "echo \"in\" > /sys/class/gpio/gpio%d/direction",gpioNo);
|
||||||
|
pins[gpioNo].mode = mode;
|
||||||
|
system(buffer);
|
||||||
|
break;
|
||||||
|
case output:
|
||||||
|
sprintf(buffer, "echo \"out\" > /sys/class/gpio/gpio%d/direction",gpioNo);
|
||||||
|
pins[gpioNo].mode = mode;
|
||||||
|
system(buffer);
|
||||||
|
break;
|
||||||
|
case analog:
|
||||||
|
std::cout << "No analog pins are awailable for raspberry" << std::endl;
|
||||||
|
break;
|
||||||
|
case alternate:
|
||||||
|
default :
|
||||||
|
throwError(__LINE__,notValidMode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOutputState(uint8_t gpioNo, Gpio::pinState state)
|
||||||
|
{
|
||||||
|
std::cout << "This version of the code doesn't allow pin output Stage configuration for the raspberry" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPullUpDonw(uint8_t gpioNo, Gpio::pinPullUpDown resistance)
|
||||||
|
{
|
||||||
|
std::cout << "This version of the code doesn't allow Pull up or Pull donw configurations for the raspberry" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSpeed(uint8_t gpioNo, Gpio::pinSpeed speed)
|
||||||
|
{
|
||||||
|
std::cout << "This version of the code doesn't allow pin speed changes for the raspberry" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config(uint8_t gpioNo,Gpio::pinFunction function, Gpio::pinMode mode, Gpio::pinState state, Gpio::pinPullUpDown resistance, Gpio::pinSpeed speed)
|
||||||
|
{
|
||||||
|
pinInitiate(gpioNo);
|
||||||
|
setFunction(gpioNo, function);
|
||||||
|
setMode(gpioNo, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int8_t readPin(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
if(pins[gpioNo].mode == undefined)
|
||||||
|
{
|
||||||
|
throwError(__LINE__,pinNotDeclared);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(pins[gpioNo].function == gpio)
|
||||||
|
{
|
||||||
|
sprintf(buffer,"/sys/class/gpio/gpio%d/value",gpioNo);
|
||||||
|
bufFile.open(buffer,std::ios::in);
|
||||||
|
if(bufFile.is_open())
|
||||||
|
{
|
||||||
|
bufFile.read(buffer,3);
|
||||||
|
bufFile.read(buffer,1);
|
||||||
|
|
||||||
|
if(buffer[0] == '1')
|
||||||
|
{
|
||||||
|
bufFile.close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (buffer[0] == '0')
|
||||||
|
{
|
||||||
|
bufFile.close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throwError(__LINE__, pinNotGpio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writePin(uint8_t gpioNo, uint8_t value)
|
||||||
|
{
|
||||||
|
if(pins[gpioNo].mode == undefined)
|
||||||
|
{
|
||||||
|
throwError(__LINE__,pinNotDeclared);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(pins[gpioNo].function == gpio)
|
||||||
|
{
|
||||||
|
if(value == 0)
|
||||||
|
{
|
||||||
|
sprintf(buffer, "echo \"%d\" > /sys/class/gpio/gpio%d/value",value,gpioNo);
|
||||||
|
system(buffer);
|
||||||
|
}
|
||||||
|
else if (value == 1)
|
||||||
|
{
|
||||||
|
sprintf(buffer, "echo \"%d\" > /sys/class/gpio/gpio%d/value",value,gpioNo);
|
||||||
|
system(buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throwError(__LINE__,notValidOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throwError(__LINE__, pinNotGpio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t readRange(uint8_t start, uint8_t stop)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeRange(uint8_t start, uint8_t stop, uint16_t value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pinInitiate(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
if(gpioNo <= PIN_COUNT)
|
||||||
|
{
|
||||||
|
sprintf(buffer,"[ -d /sys/class/gpio/gpio%d ]",gpioNo); // retunrs null if directory exists
|
||||||
|
ck = system(buffer);
|
||||||
|
if( ck != 0)
|
||||||
|
{
|
||||||
|
sprintf(buffer, "echo \"%d\" > /sys/class/gpio/export",gpioNo);
|
||||||
|
ck = system(buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Pin already initiated"<< std::endl;
|
||||||
|
std::cout << " - ";
|
||||||
|
pinPrintInfo(gpioNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throwError(__LINE__,pinOutOfRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pinUninitiate(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
if(gpioNo <= PIN_COUNT)
|
||||||
|
{
|
||||||
|
sprintf(buffer,"[ -d /sys/class/gpio/gpio%d ]",gpioNo); // retunrs null if directory exists
|
||||||
|
ck = system(buffer);
|
||||||
|
if( ck == 0)
|
||||||
|
{
|
||||||
|
sprintf(buffer, "echo \"%d\" > /sys/class/gpio/unexport",gpioNo);
|
||||||
|
system(buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throwError(__LINE__,pinNotDeclared);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throwError(__LINE__,pinOutOfRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkCurrentPins()
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
for( i = 0; i < PIN_COUNT; i++)
|
||||||
|
{
|
||||||
|
sprintf(buffer,"[ -d /sys/class/gpio/gpio%d ]",i); // retunrs null if directory exists
|
||||||
|
ck = system(buffer);
|
||||||
|
if( ck == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Pin: "<< unsigned(i) << " Exists " << std::endl;
|
||||||
|
sprintf(buffer,"/sys/class/gpio/gpio%d/direction",i);
|
||||||
|
bufFile.open(buffer,std::ios::in);
|
||||||
|
if(bufFile.is_open())
|
||||||
|
{
|
||||||
|
bufFile.read(buffer,3);
|
||||||
|
|
||||||
|
if(buffer[0] == 'i')
|
||||||
|
{
|
||||||
|
if (buffer[1] == 'n')
|
||||||
|
{
|
||||||
|
pins[i].mode = input; // init of the direction and the rest as a stanard gpio pin.
|
||||||
|
pins[i].state = openDrain;
|
||||||
|
pins[i].pud = none;
|
||||||
|
pins[i].speed = normal;
|
||||||
|
pins[i].interrupt = disabled;
|
||||||
|
pins[i].function = gpio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (buffer[0] == 'o')
|
||||||
|
{
|
||||||
|
if(buffer[1] == 'u')
|
||||||
|
{
|
||||||
|
if(buffer[2] == 't')
|
||||||
|
{
|
||||||
|
pins[i].mode = output;
|
||||||
|
pins[i].state = openDrain;
|
||||||
|
pins[i].pud = none;
|
||||||
|
pins[i].speed = normal;
|
||||||
|
pins[i].interrupt = disabled;
|
||||||
|
pins[i].function = gpio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bufFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pinList() // Lists allthe pins whom their mode in not set to undefined.
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < PIN_COUNT; i++)
|
||||||
|
{
|
||||||
|
if(pins[i].mode != undefined)
|
||||||
|
{
|
||||||
|
std::cout << "|Pin "<< unsigned(i) <<" already exists and will be initialized as default GPIO|" << std::endl;
|
||||||
|
pinPrintInfo(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pinPrintInfo(uint8_t gpioNo) // a graphical arrangement to see the cunnrently acive pins
|
||||||
|
{
|
||||||
|
std::cout << "Pin No: " << unsigned(gpioNo);
|
||||||
|
switch(pins[gpioNo].mode)
|
||||||
|
{
|
||||||
|
|
||||||
|
case undefined:
|
||||||
|
std::cout << "| Mode: Undefined\t";
|
||||||
|
break;
|
||||||
|
case input:
|
||||||
|
std::cout << "| Mode: Input\t";
|
||||||
|
break;
|
||||||
|
case output:
|
||||||
|
std::cout << "| Mode: Output\t";
|
||||||
|
break;
|
||||||
|
case analog:
|
||||||
|
std::cout << "| Mode: Analog\t";
|
||||||
|
break;
|
||||||
|
case alternate:
|
||||||
|
std::cout << "| Mode: Alternate\t";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pins[gpioNo].state)
|
||||||
|
{
|
||||||
|
|
||||||
|
case floating:
|
||||||
|
std::cout << "| State: Floating ";
|
||||||
|
break;
|
||||||
|
case pushPull:
|
||||||
|
std::cout << "| State: Push-Pull ";
|
||||||
|
break;
|
||||||
|
case openDrain:
|
||||||
|
std::cout << "| State: Open Drain ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pins[gpioNo].pud)
|
||||||
|
{
|
||||||
|
|
||||||
|
case none:
|
||||||
|
std::cout << "| Pud: None ";
|
||||||
|
break;
|
||||||
|
case pullUp:
|
||||||
|
std::cout << "| Pud: Pull-up ";
|
||||||
|
break;
|
||||||
|
case pullDown:
|
||||||
|
std::cout << "| Pud: Pull-down ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pins[gpioNo].speed)
|
||||||
|
{
|
||||||
|
|
||||||
|
case slow:
|
||||||
|
std::cout << "| Speed: Slow ";
|
||||||
|
break;
|
||||||
|
case normal:
|
||||||
|
std::cout << "| Speed: Normal ";
|
||||||
|
break;
|
||||||
|
case fast:
|
||||||
|
std::cout << "| Speed: Fast ";
|
||||||
|
break;
|
||||||
|
case veryFast:
|
||||||
|
std::cout << "| Speed: Very Fast ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pins[gpioNo].interrupt)
|
||||||
|
{
|
||||||
|
|
||||||
|
case disabled:
|
||||||
|
std::cout << "| Interrupt: No ";
|
||||||
|
break;
|
||||||
|
case enabled:
|
||||||
|
std::cout << "| Interrupt: Yes ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pins[gpioNo].function)
|
||||||
|
{
|
||||||
|
case passive:
|
||||||
|
std::cout << "| Function: NONE";
|
||||||
|
break;
|
||||||
|
case gpio:
|
||||||
|
std::cout << "| Function: GPIO";
|
||||||
|
break;
|
||||||
|
case i2c:
|
||||||
|
std::cout << "| Function: I2C";
|
||||||
|
break;
|
||||||
|
case spi:
|
||||||
|
std::cout << "| Function: SPI";
|
||||||
|
break;
|
||||||
|
case pwm:
|
||||||
|
std::cout << "| Function: PWM";
|
||||||
|
break;
|
||||||
|
case pcm:
|
||||||
|
std::cout << "| Function: PCM";
|
||||||
|
break;
|
||||||
|
case uart:
|
||||||
|
std::cout << "| Function: UART";
|
||||||
|
break;
|
||||||
|
case eeprom:
|
||||||
|
std::cout << "| Function: EEPROM";
|
||||||
|
break;
|
||||||
|
case clk:
|
||||||
|
std::cout << "| Function: CLK";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
std::cout << "|" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void throwError(uint16_t line, Gpio::errors errNo)
|
||||||
|
{
|
||||||
|
std::cout << "Error GPIO.C | Code Line: "<< unsigned(line) << " | Error No: "<< errNo << " | Description: ";
|
||||||
|
switch(errNo)
|
||||||
|
{
|
||||||
|
|
||||||
|
case notValidMode:
|
||||||
|
std::cout << "notValidMode";
|
||||||
|
break;
|
||||||
|
case notValidOut:
|
||||||
|
std::cout << "notValidOut";
|
||||||
|
break;
|
||||||
|
case pinOutOfRange:
|
||||||
|
std::cout << "pinOutOfRange";
|
||||||
|
break;
|
||||||
|
case pinNotDeclared:
|
||||||
|
std::cout << "pinNotDeclared";
|
||||||
|
break;
|
||||||
|
case pinNotReachable:
|
||||||
|
std::cout << "pinNotReachable";
|
||||||
|
break;
|
||||||
|
case pinNoPullUpDown:
|
||||||
|
std::cout << "pinNoPullUpDown";
|
||||||
|
break;
|
||||||
|
case pinNotAnalog:
|
||||||
|
std::cout << "pinNotAnalog";
|
||||||
|
break;
|
||||||
|
case pinNotDigital:
|
||||||
|
std::cout << "pinNotDigital";
|
||||||
|
break;
|
||||||
|
case pinTooFast:
|
||||||
|
std::cout << "pinTooFast";
|
||||||
|
break;
|
||||||
|
case pinBocked:
|
||||||
|
std::cout << "pinBocked";
|
||||||
|
break;
|
||||||
|
case pinAlreadyUsed:
|
||||||
|
std::cout << "pinAlreadyUsed";
|
||||||
|
break;
|
||||||
|
case pinNotGpio:
|
||||||
|
std::cout << "pinAlreadyUsed";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout << "Unhandled Error";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
std::cout << " |" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Gpio::Gpio():gpioPimpl(new gpioImpl()){}
|
||||||
|
Gpio::~Gpio(){}
|
||||||
|
|
||||||
|
void Gpio::setFunction(uint8_t gpioNo, Gpio::pinFunction function)
|
||||||
|
{
|
||||||
|
return gpioPimpl->setFunction(gpioNo, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setMode(uint8_t gpioNo, Gpio::pinMode mode)
|
||||||
|
{
|
||||||
|
return gpioPimpl->setMode(gpioNo, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setOutputState(uint8_t gpioNo, Gpio::pinState state)
|
||||||
|
{
|
||||||
|
return gpioPimpl->setOutputState(gpioNo,state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setPullUpDonw(uint8_t gpioNo, Gpio::pinPullUpDown resistance)
|
||||||
|
{
|
||||||
|
return gpioPimpl->setPullUpDonw(gpioNo,resistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::setSpeed(uint8_t gpioNo, Gpio::pinSpeed speed)
|
||||||
|
{
|
||||||
|
return gpioPimpl->setSpeed(gpioNo, speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::config(uint8_t gpioNo,Gpio::pinFunction function, Gpio::pinMode mode, Gpio::pinState state, Gpio::pinPullUpDown resistance, Gpio::pinSpeed speed)
|
||||||
|
{
|
||||||
|
return gpioPimpl->config(gpioNo,function ,mode,state,resistance,speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Gpio::readPin(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
return gpioPimpl->readPin(gpioNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::writePin(uint8_t gpioNo, uint8_t value)
|
||||||
|
{
|
||||||
|
return gpioPimpl->writePin(gpioNo, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Gpio::readRange(uint8_t start, uint8_t stop)
|
||||||
|
{
|
||||||
|
return gpioPimpl->readRange(start,stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::writeRange(uint8_t start, uint8_t stop, uint16_t value)
|
||||||
|
{
|
||||||
|
return gpioPimpl->writeRange(start,stop,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::pinInitiate(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
return gpioPimpl->pinInitiate(gpioNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::pinUninitiate(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
return gpioPimpl->pinUninitiate(gpioNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::checkCurrentPins()
|
||||||
|
{
|
||||||
|
return gpioPimpl->checkCurrentPins();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::pinList()
|
||||||
|
{
|
||||||
|
return gpioPimpl->pinList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::pinPrintInfo(uint8_t gpioNo)
|
||||||
|
{
|
||||||
|
return gpioPimpl->pinPrintInfo(gpioNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gpio::throwError(uint16_t line, Gpio::errors error)
|
||||||
|
{
|
||||||
|
return gpioPimpl->throwError(line, error);
|
||||||
|
}
|
Loading…
Reference in new issue