blob: 61f50752318a768029c60255feec0eeb486ca86d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 - 2018 Johannes Messmer (admin@jomess.com), 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:
* Johannes Messmer - initial API and implementation and/or initial documentation
* Jose Cabral - Cleaning of namespaces
*******************************************************************************/
#ifndef SRC_MODULES_EMBRICK_SLAVE_SLAVE_H_
#define SRC_MODULES_EMBRICK_SLAVE_SLAVE_H_
#include <stdint.h>
#include <cstring>
#include "packages.h"
#include "handle.h"
#include <fortelist.h>
#include <stdint.h>
#include <forte_sync.h>
#include <forte_wstring.h>
#include <devlog.h>
#include <io/mapper/io_mapper.h>
class EmbrickBusHandler;
class EmbrickSlaveHandler {
public:
friend class EmbrickBusHandler;
enum SlaveStatus {
NotInitialized = 0, //!< Slave requires initialization
OK = 1, //!< Everything works as expected
Slow = 200, //!< Update frequency is too low, some errors may occurred
Interrupted = 201, //!< Slave received no master updates
Error = 202, //!< Connection has errors. Check hardware
};
enum SlaveType {
UnknownSlave = 0,
G_8Di8Do = 2181, //!< 8x Digital-Input, 24V, p-switch, 1-wire & 8x Digital-Output, 24V, p-switch, 1-wire
G_2RelNo4RelCo = 2301 //!< 2x Relay-Output, NO, potential free & 4x Relay-Output, CO, potential free
};
struct Config {
unsigned int mUpdateInterval; //!< Sets the default frequency for the data update cycle of slaves. The emBRICK slaves require at least 20 updates per minute. The default value is 25 Hz.
};
class Delegate {
public:
virtual void onSlaveStatus(SlaveStatus paStatus, SlaveStatus paOldStatus) = 0;
virtual void onSlaveDestroy() = 0;
};
void setConfig(Config paConfig);
Delegate* mDelegate;
const unsigned int mAddress;
unsigned int index() const {
return mAddress - 1;
}
const SlaveType mType;
int update();
void forceUpdate();
EmbrickSlaveHandle* getInputHandle(int paIndex) {
return getHandle(&mInputs, paIndex);
}
EmbrickSlaveHandle* getOutputHandle(int paIndex) {
return getHandle(&mOutputs, paIndex);
}
void addHandle(EmbrickSlaveHandle* paHandle) {
switch(paHandle->getDirection()){
case forte::core::io::IOMapper::In:
addHandle(&mInputs, paHandle);
break;
case forte::core::io::IOMapper::Out:
addHandle(&mOutputs, paHandle);
break;
default:
break;
}
}
void dropHandles();
unsigned char *mUpdateSendImage;
unsigned char *mUpdateReceiveImage;
CSyncObject mUpdateMutex;
protected:
static EmbrickSlaveHandler* sendInit(EmbrickBusHandler* paBus, int paAddress);
EmbrickSlaveHandler(EmbrickBusHandler* paBus, int paAddress, EmbrickSlaveInitPackage paInit);
virtual ~EmbrickSlaveHandler();
EmbrickBusHandler* mBus;
Config mConfig;
const uint8_t mDataSendLength;
const uint8_t mDataReceiveLength;
SlaveStatus mStatus;
SlaveStatus mOldStatus;
unsigned char *mUpdateReceiveImageOld;
int mUpdateErrorCounter;
static const int scmMaxUpdateErrors;
CSyncObject mHandleMutex;
typedef CSinglyLinkedList<EmbrickSlaveHandle *> TSlaveHandleList;
TSlaveHandleList mInputs;
TSlaveHandleList mOutputs;
void addHandle(TSlaveHandleList* paList, EmbrickSlaveHandle* paHandle);
EmbrickSlaveHandle* getHandle(TSlaveHandleList* list, int paIndex);
private:
//!declared but undefined copy constructor as we don't want Slaves to be directly copied.
EmbrickSlaveHandler(const EmbrickSlaveHandler&);
};
#endif /* SRC_MODULES_EMBRICK_SLAVE_SLAVE_H_ */