blob: 7d1c79cad498cb6022b28862f51c7641ecd060e7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 fortiss GmbH
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Monika Wenger, Alois Zoitl - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "processinterface.h"
#include <extevhandlerhelper.h>
CPiFaceProcessInterface::CPiFaceProcessInterface(forte::core::CFBContainer &paContainer,
const SFBInterfaceSpec *paInterfaceSpec,
const CStringDictionary::TStringId paInstanceNameId) :
CProcessInterfaceBase(paContainer, paInterfaceSpec, paInstanceNameId),
mPin(0){
}
CPiFaceProcessInterface::~CPiFaceProcessInterface(){
deinitialise();
}
bool CPiFaceProcessInterface::initialise(bool paIsInput, CEventChainExecutionThread *const paECET) {
bool retVal = false;
if(paInput){
getExtEvHandler<CPiFaceIOHandler>(*this).registerIXFB(this);
}
QO() = QI();
if(!getExtEvHandler<CPiFaceIOHandler>(*this).isAlive()){
getExtEvHandler<CPiFaceIOHandler>(*this).start();
}
CIEC_INT pinNum;
if((-1 != pinNum.fromString(PARAMS().getValue())) && (8 > pinNum)){
mPin = pinNum;
retVal = true;
}
return retVal;
}
bool CPiFaceProcessInterface::deinitialise(){
getExtEvHandler<CPiFaceIOHandler>(*this).unregisterIXFB(this);
return true;
}
bool CPiFaceProcessInterface::getValue(long paValue){
return 0 != (paValue & (1 << mPin));
}
bool CPiFaceProcessInterface::readPin(){
//We don't need to do anything in readPin output update is handled as part of checkInputData
return true;
}
bool CPiFaceProcessInterface::writePin(){
getExtEvHandler<CPiFaceIOHandler>(*this).updateWriteData(OUT_X(), mPin);
return true;
}
bool CPiFaceProcessInterface::checkInputData(long paValue){
bool retval = false;
bool newValue = getValue(paValue);
if(newValue != IN_X()){
IN_X() = newValue;
retval = true;
}
return retval;
}
/********************************************************************************************
*** CPiFaceProcessInterface::CPiFaceIOHandler
********************************************************************************************/
DEFINE_HANDLER(CPiFaceProcessInterface::CPiFaceIOHandler)
CPiFaceProcessInterface::CPiFaceIOHandler::CPiFaceIOHandler(CDeviceExecution& paDeviceExecution) : CExternalEventHandler(paDeviceExecution), mOutBuffer(0){
}
CPiFaceProcessInterface::CPiFaceIOHandler::~CPiFaceIOHandler(){
}
void CPiFaceProcessInterface::CPiFaceIOHandler::run(){
//this gives as the default values of Mode0, Speed 1000000, and Bitsperword 8 which wed need also for piFace
CONMELEON::CSpiDevice spiDev("/dev/spidev0.0"); //TODO correctly setup SPI interface
setupPiFaceIOChip(spiDev);
if(spiDev.isOpen()){
TForteUInt8 inBuffer;
while(isAlive()){
CThread::sleepThread(10);
writePiFaceRegister(spiDev, eGPIOPortA, mOutBuffer); //update outputs
inBuffer = readInputs(spiDev);
spiDev.read(&inBuffer, 1);
updateReadData(inBuffer);
}
}
else{
DEVLOG_ERROR("SPI interface has not been opened!n");
}
}
void CPiFaceProcessInterface::CPiFaceIOHandler::registerIXFB(CPiFaceProcessInterface *paFB){
mReadFBListSync.lock();
mReadFBList.pushBack(paFB);
mReadFBListSync.unlock();
}
void CPiFaceProcessInterface::CPiFaceIOHandler::unregisterIXFB(CPiFaceProcessInterface *paFB){
mReadFBListSync.lock();
TReadFBContainer::Iterator itRunner(mReadFBList.begin());
TReadFBContainer::Iterator itRefNode(mReadFBList.end());
TReadFBContainer::Iterator itEnd(mReadFBList.end());
while(itRunner != itEnd){
if(*itRunner == paFB){
if(itRefNode == itEnd){
mReadFBList.popFront();
}
else{
mReadFBList.eraseAfter(itRefNode);
}
break;
}
itRefNode = itRunner;
++itRunner;
}
mReadFBListSync.unlock();
}
void CPiFaceProcessInterface::CPiFaceIOHandler::updateReadData(TForteUInt8 paInBuffer){
TReadFBContainer::Iterator itEnd(mReadFBList.end());
for(TReadFBContainer::Iterator itRunner = mReadFBList.begin(); itRunner != itEnd; ++itRunner){
if((*itRunner)->checkInputData(paInBuffer)){
startNewEventChain(*itRunner);
}
}
}
void CPiFaceProcessInterface::CPiFaceIOHandler::updateWriteData(bool paValue, int paPin){
if(true == paValue){
mOutBuffer |= static_cast<TForteUInt8>(1 << paPin);
}
else{
mOutBuffer &= static_cast<TForteUInt8>(~(1 << paPin));
}
}
void CPiFaceProcessInterface::CPiFaceIOHandler::enableHandler(){
}
void CPiFaceProcessInterface::CPiFaceIOHandler::disableHandler(){
}
void CPiFaceProcessInterface::CPiFaceIOHandler::setPriority(int){
}
int CPiFaceProcessInterface::CPiFaceIOHandler::getPriority() const{
return 0;
}
void CPiFaceProcessInterface::CPiFaceIOHandler::setupPiFaceIOChip(CONMELEON::CSpiDevice &paDev){
writePiFaceRegister(paDev, eIOConfiguration, 8);
writePiFaceRegister(paDev, eIODirectionPortA, 0); //set all port A pins as outputs
writePiFaceRegister(paDev, eIODirectionPortB, 0xFF); //set all port B pins as inputs
writePiFaceRegister(paDev, eGPIOPullupResistorsPortB, 0xFF); //enable for all port B pins the pull up resistors
}
TForteByte CPiFaceProcessInterface::CPiFaceIOHandler::readInputs(CONMELEON::CSpiDevice &paDev){
unsigned char txBuf[3] = {scmPiFaceWrite, eGPIOPortB, 0};
unsigned char rxBuf[3] = {0, 0 ,0 };
paDev.transfer(txBuf, rxBuf, 3);
return static_cast<TForteByte>(~rxBuf[2]);
}
void CPiFaceProcessInterface::CPiFaceIOHandler::writePiFaceRegister(CONMELEON::CSpiDevice &paDev, EPiFaceRegister paRegister, TForteByte paValue){
unsigned char txBuf[3] = {scmPiFaceWrite, paRegister, paValue};
unsigned char rxBuf[3];
paDev.transfer(txBuf, rxBuf, 3);
}