228 lines
11 KiB
C++
228 lines
11 KiB
C++
#ifndef RMAPpp_H_
|
|
#define RMAPpp_H_
|
|
|
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
|
#include "RMAPCookie.h"
|
|
|
|
//SHOULDTODO: clean up includes for RMAP, should be enough to include RMAP.h but right now it's quite chaotic...
|
|
|
|
/**
|
|
* API for a Cookie/Channel based RMAP implementation.
|
|
*
|
|
* The API offers the four basic RMAP actions: sending a Read or Write command and getting the reply to each.
|
|
* As RMAP is an asynchronous protocol, these are implemented as four seperate calls. There are blocking
|
|
* calls which combine a send and get call using a timeout, but these are "real" blocking, looping in between
|
|
* the calls.
|
|
*
|
|
* Cookies are used to contain Information between a send[Read,Write]Command and a get[Read,Write]Reply call,
|
|
* one can think of them like *nix file descriptors. A cookie is valid from a sendX call until the related getX
|
|
* call. That means if a cookie is used in a getX call, the reply to the sendX call the cookie was used with
|
|
* previously is returned.
|
|
* Depending on the underlying RMAPChannel implementation, a cookie can also be valid for more than one getX
|
|
* call, but this should not be assumed generally.
|
|
* A cookie encapsulates information like the RMAP Channel to use, as well as the RMAP Address
|
|
* and a Command Mask used for specifying which RMAP capabilities are used.
|
|
* Cookies are created without interaction with this API, there is no open() call. The RMAP implementation
|
|
* will initialize all fields which are not set by the cookie's constructor.
|
|
*
|
|
* The RMAP implementation relies on Channels. A channel is used to construct the RMAP Headers and handle the
|
|
* protocol. It is access via the RMAPChannelIF. Thus it is possible to use different Implementations which only
|
|
* need to implement the RMAPChannelIF. A channel is also responsible for accessing the lower layers, for example
|
|
* a SPaceWire transport layer.
|
|
*
|
|
* There is one RMAP Channel per physical device. The cookie-channel as well as the device-channel assignment
|
|
* can be changed at runtime to allow for example redundancy switching. This API is static as the information which
|
|
* channel to use is contained within the cookie.
|
|
*/
|
|
class RMAP: public HasReturnvaluesIF {
|
|
public:
|
|
static const uint8_t INTERFACE_ID = CLASS_ID::RMAP_CHANNEL;
|
|
|
|
//static const ReturnValue_t COMMAND_OK = MAKE_RETURN_CODE(0x00);
|
|
static const ReturnValue_t COMMAND_NO_DESCRIPTORS_AVAILABLE =
|
|
MAKE_RETURN_CODE(0xE1); //no descriptors available for sending command; command was not sent
|
|
static const ReturnValue_t COMMAND_BUFFER_FULL = MAKE_RETURN_CODE(0xE2); //no receiver buffer available for expected len; command was not sent
|
|
static const ReturnValue_t COMMAND_CHANNEL_OUT_OF_RANGE = MAKE_RETURN_CODE(
|
|
0xE3); //The cookie points to an invalid channel; command was not sent
|
|
//Replaced by DeviceCommunicationIF::TOO_MUCH_DATA static const ReturnValue_t COMMAND_TOO_BIG = MAKE_RETURN_CODE(0xE4); //the data that was to be sent was too long for the hw to handle (write command) or the expected len was bigger than maximal expected len (read command)
|
|
//command was not sent
|
|
//replaced by DeviceCommunicationIF::NULLPOINTER static const ReturnValue_t COMMAND_NULLPOINTER = MAKE_RETURN_CODE(0xE5); //datalen was != 0 but data was == NULL in write command, or nullpointer in read command
|
|
static const ReturnValue_t COMMAND_CHANNEL_DEACTIVATED = MAKE_RETURN_CODE(
|
|
0xE6); //the channel has no port set
|
|
static const ReturnValue_t COMMAND_PORT_OUT_OF_RANGE = MAKE_RETURN_CODE(
|
|
0xE7); //The specified port is not valid
|
|
static const ReturnValue_t COMMAND_PORT_IN_USE = MAKE_RETURN_CODE(0xE8);//The specified port is already in use
|
|
static const ReturnValue_t COMMAND_NO_CHANNEL = MAKE_RETURN_CODE(0xE9);//The cookie to work with has no channel assigned.
|
|
static const ReturnValue_t NO_HW_CRC = MAKE_RETURN_CODE(0xEA);//The SpW port does not support HW CRC generation, which is unsupported
|
|
//return values for both get_write_reply and get_read_reply
|
|
static const ReturnValue_t REPLY_NO_REPLY = MAKE_RETURN_CODE(0xD0); //no reply was received
|
|
static const ReturnValue_t REPLY_NOT_SENT = MAKE_RETURN_CODE(0xD1); //command was not sent, implies no reply
|
|
static const ReturnValue_t REPLY_NOT_YET_SENT = MAKE_RETURN_CODE(0xD2); //command is still waiting to be sent
|
|
static const ReturnValue_t REPLY_MISSMATCH = MAKE_RETURN_CODE(0xD3);//a read command was issued, but get_write_rply called, or other way round
|
|
static const ReturnValue_t REPLY_TIMEOUT = MAKE_RETURN_CODE(0xD4);//timeout
|
|
//replaced by DeviceCommunicationIF::NULLPOINTER static const ReturnValue_t REPLY_NULLPOINTER = MAKE_RETURN_CODE(0xD5);//one of the arguments in a read reply was NULL
|
|
//return values for get_reply
|
|
static const ReturnValue_t REPLY_INTERFACE_BUSY = MAKE_RETURN_CODE(
|
|
0xC0);//Interface is busy (transmission buffer still being processed)
|
|
static const ReturnValue_t REPLY_TRANSMISSION_ERROR =
|
|
MAKE_RETURN_CODE(0xC1); //Interface encountered errors during last operation, data could not be processed. (transmission error)
|
|
static const ReturnValue_t REPLY_INVALID_DATA = MAKE_RETURN_CODE(
|
|
0xC2); //Invalid data (amount / value)
|
|
static const ReturnValue_t REPLY_NOT_SUPPORTED = MAKE_RETURN_CODE(
|
|
0xC3);
|
|
|
|
//return values for reset
|
|
static const ReturnValue_t LINK_DOWN = MAKE_RETURN_CODE(0xF0);//The spw link is down
|
|
//Other SpW codes:
|
|
static const ReturnValue_t SPW_CREDIT = MAKE_RETURN_CODE(0xF1);
|
|
static const ReturnValue_t SPW_ESCAPE = MAKE_RETURN_CODE(0xF2);
|
|
static const ReturnValue_t SPW_DISCONNECT = MAKE_RETURN_CODE(0xF3);
|
|
static const ReturnValue_t SPW_PARITY = MAKE_RETURN_CODE(0xF4);
|
|
static const ReturnValue_t SPW_WRITE_SYNC = MAKE_RETURN_CODE(0xF5);
|
|
static const ReturnValue_t SPW_INVALID_ADDRESS = MAKE_RETURN_CODE(0xF6);
|
|
static const ReturnValue_t SPW_EARLY_EOP = MAKE_RETURN_CODE(0xF7);
|
|
static const ReturnValue_t SPW_DMA = MAKE_RETURN_CODE(0xF8);
|
|
static const ReturnValue_t SPW_LINK_ERROR = MAKE_RETURN_CODE(0xF9);
|
|
|
|
|
|
//RMAP standard replies
|
|
static const ReturnValue_t REPLY_OK = MAKE_RETURN_CODE(0);
|
|
static const ReturnValue_t REPLY_GENERAL_ERROR_CODE = MAKE_RETURN_CODE(1);// The detected error does not fit into the other
|
|
// error cases or the node does not support
|
|
// further distinction between the errors
|
|
static const ReturnValue_t REPLY_UNUSED_PACKET_TYPE_OR_COMMAND_CODE =
|
|
MAKE_RETURN_CODE(2); // The Header CRC was decoded correctly but
|
|
// the packet type is reserved or the command
|
|
// is not used by the RMAP protocol.
|
|
static const ReturnValue_t REPLY_INVALID_KEY = MAKE_RETURN_CODE(3); // The Header CRC was decoded correctly but
|
|
// the device key did not match that expected
|
|
// by the target user application
|
|
static const ReturnValue_t REPLY_INVALID_DATA_CRC = MAKE_RETURN_CODE(4);// Error in the CRC of the data field
|
|
static const ReturnValue_t REPLY_EARLY_EOP = MAKE_RETURN_CODE(5);// EOP marker detected before the end of the data
|
|
static const ReturnValue_t REPLY_TOO_MUCH_DATA = MAKE_RETURN_CODE(6);// More than the expected amount of data in a
|
|
// command has been received
|
|
static const ReturnValue_t REPLY_EEP = MAKE_RETURN_CODE(7); // EEP marker detected immediately after the
|
|
// header CRC or during the transfer of data
|
|
// and Data CRC or immediately thereafter.
|
|
// Indicates that there was a communication
|
|
// failure of some sort on the network
|
|
static const ReturnValue_t REPLY_RESERVED = MAKE_RETURN_CODE(8);// Reserved
|
|
static const ReturnValue_t REPLY_VERIFY_BUFFER_OVERRUN = MAKE_RETURN_CODE(
|
|
9); // The verify before write bit of the command
|
|
// was set so that the data field was buffered in
|
|
// order to verify the Data CRC before
|
|
// transferring the data to target memory. The
|
|
// data field was longer than able to fit inside
|
|
// the verify buffer resulting in a buffer overrun
|
|
// Note that the command is not executed in
|
|
// this case
|
|
static const ReturnValue_t REPLY_COMMAND_NOT_IMPLEMENTED_OR_NOT_AUTHORISED =
|
|
MAKE_RETURN_CODE(10);// The target user application did not authorise
|
|
// the requested operation. This may be because
|
|
// the command requested has not been
|
|
// implemented
|
|
static const ReturnValue_t REPLY_RMW_DATA_LENGTH_ERROR = MAKE_RETURN_CODE(
|
|
11); // The amount of data in a RMW command is
|
|
// invalid (0x01 0x03 0x05 0x07 or greater
|
|
// than 0x08)
|
|
static const ReturnValue_t REPLY_INVALID_TARGET_LOGICAL_ADDRESS =
|
|
MAKE_RETURN_CODE(12); // The Header CRC was decoded correctly but
|
|
// the Target Logical Address was not the value
|
|
// expected by the target
|
|
|
|
/**
|
|
* Resets the underlying channel.
|
|
*
|
|
* @param cookie The cookie which points to the channel to reset
|
|
* @return
|
|
*/
|
|
static ReturnValue_t reset(RMAPCookie *cookie);
|
|
|
|
/**
|
|
* send an RMAP write command
|
|
*
|
|
* datalen is only 24bit wide, rest will be ignored
|
|
* IMPORTANT: the data buffer must be datalen+1 large, as the driver might
|
|
* write a CRC sum at data[datalen]
|
|
* if you want to send an empty packet, just do datalen = 0 and data = NULL
|
|
*
|
|
* @param cookie The cookie to write to
|
|
* @param buffer the data to write
|
|
* @param length length of data
|
|
* @return
|
|
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in write command
|
|
* - return codes of RMAPChannelIF::sendCommand()
|
|
*/
|
|
static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, uint8_t* buffer,
|
|
uint32_t length);
|
|
|
|
/**
|
|
* get the reply to a write command
|
|
*
|
|
* @param cookie the cookie the command was sent with
|
|
* @return
|
|
* - @c REPLY_MISSMATCH a read command was issued, but getWriteReply called
|
|
* - return codes of RMAPChannelIF::getReply()
|
|
*/
|
|
static ReturnValue_t getWriteReply(RMAPCookie *cookie);
|
|
|
|
/**
|
|
* @see sendWriteCommand()
|
|
* @see getWriteReply()
|
|
*
|
|
* @param timeout_us the time after the function returns, if no reply was received
|
|
*
|
|
* @return
|
|
* - All of sendWriteCommand()
|
|
* - All of getWriteReply()
|
|
* - @c REPLY_TIMEOUT timeout
|
|
*/
|
|
static ReturnValue_t writeBlocking(RMAPCookie *cookie, uint8_t* buffer,
|
|
uint32_t length, uint32_t timeout_us);
|
|
|
|
/**
|
|
* send an RMAP read command
|
|
*
|
|
* @param cookie to cookie to read from
|
|
* @param expLength the expected maximum length of the reply
|
|
* @return
|
|
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in write command, or nullpointer in read command
|
|
* - return codes of RMAPChannelIF::sendCommand()
|
|
*/
|
|
static ReturnValue_t sendReadCommand(RMAPCookie *cookie,
|
|
uint32_t expLength);
|
|
|
|
/**
|
|
* get a reply to an RMAP read command
|
|
*
|
|
* @param cookie the cookie that was read from
|
|
* @param[out] buffer the location of the data
|
|
* @param[out] size size of the data
|
|
* @return
|
|
* - @c COMMAND_NULLPOINTER buffer or size was NULL
|
|
* - @c REPLY_MISSMATCH a write command was issued, but getReadReply called
|
|
* - return codes of RMAPChannelIF::getReply()
|
|
*/
|
|
static ReturnValue_t getReadReply(RMAPCookie *cookie, uint8_t **buffer,
|
|
uint32_t *size);
|
|
|
|
/**
|
|
* @see sendReadCommand()
|
|
* @see getReadReply()
|
|
*
|
|
* @param timeout_us the time after the function returns, if no reply was received
|
|
*
|
|
* @return
|
|
* - All of sendReadCommand()
|
|
* - All of getReadReply()
|
|
* - @c REPLY_TIMEOUT timeout
|
|
*/
|
|
static ReturnValue_t readBlocking(RMAPCookie *cookie, uint32_t expLength,
|
|
uint8_t** buffer, uint32_t *size, uint32_t timeout_us);
|
|
|
|
protected:
|
|
RMAP();
|
|
};
|
|
|
|
#endif /* RMAPpp_H_ */
|