2020-08-18 13:09:15 +02:00
# ifndef RMAPpp_H_
# define RMAPpp_H_
# include "../returnvalues/HasReturnvaluesIF.h"
# include "../rmap/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 24 bit 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 , const uint8_t * buffer ,
size_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 ,
size_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_ */