release 0.0.1 of fsfw added as a core
This commit is contained in:
89
fsfw/rmap/RMAP.cpp
Normal file
89
fsfw/rmap/RMAP.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "../devicehandlers/DeviceCommunicationIF.h"
|
||||
#include "rmapStructs.h"
|
||||
#include "RMAP.h"
|
||||
#include "RMAPChannelIF.h"
|
||||
#include <stddef.h>
|
||||
|
||||
ReturnValue_t RMAP::reset(RMAPCookie* cookie) {
|
||||
return cookie->getChannel()->reset();
|
||||
}
|
||||
|
||||
RMAP::RMAP(){
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RMAP::sendWriteCommand(RMAPCookie *cookie, uint8_t* buffer,
|
||||
uint32_t length) {
|
||||
uint8_t instruction;
|
||||
|
||||
if ((buffer == NULL) && (length != 0)) {
|
||||
return DeviceCommunicationIF::NULLPOINTER;
|
||||
}
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
instruction = RMAPIds::RMAP_COMMAND_WRITE | cookie->getCommandMask();
|
||||
return cookie->getChannel()->sendCommand(cookie, instruction, buffer,
|
||||
length);
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RMAP::getWriteReply(RMAPCookie *cookie) {
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
if (cookie->getHeader()->instruction & (1 << RMAPIds::RMAP_COMMAND_BIT_WRITE)) {
|
||||
return cookie->getChannel()->getReply(cookie, NULL, NULL);
|
||||
} else {
|
||||
return REPLY_MISSMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t RMAP::writeBlocking(RMAPCookie *cookie, uint8_t* buffer,
|
||||
uint32_t length, uint32_t timeout_us) {
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
return cookie->getChannel()->sendCommandBlocking(cookie, buffer, length,
|
||||
NULL, NULL, timeout_us);
|
||||
|
||||
}
|
||||
ReturnValue_t RMAP::sendReadCommand(RMAPCookie *cookie, uint32_t expLength) {
|
||||
uint8_t command;
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
command = RMAPIds::RMAP_COMMAND_READ
|
||||
| (cookie->getCommandMask() & ~(1 << RMAPIds::RMAP_COMMAND_BIT_VERIFY));
|
||||
|
||||
return cookie->getChannel()->sendCommand(cookie, command, NULL, expLength);
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RMAP::getReadReply(RMAPCookie *cookie, uint8_t **buffer,
|
||||
uint32_t *size) {
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
if (buffer == NULL || size == NULL) {
|
||||
return DeviceCommunicationIF::NULLPOINTER;
|
||||
}
|
||||
if (cookie->getHeader()->instruction & (1 << RMAPIds::RMAP_COMMAND_BIT_WRITE)) {
|
||||
return REPLY_MISSMATCH;
|
||||
} else {
|
||||
return cookie->getChannel()->getReply(cookie, buffer, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RMAP::readBlocking(RMAPCookie *cookie, uint32_t expLength,
|
||||
uint8_t** buffer, uint32_t *size, uint32_t timeout_us) {
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
if (buffer == NULL || size == NULL) {
|
||||
return DeviceCommunicationIF::NULLPOINTER;
|
||||
}
|
||||
return cookie->getChannel()->sendCommandBlocking(cookie, NULL, expLength,
|
||||
buffer, size, timeout_us);
|
||||
}
|
227
fsfw/rmap/RMAP.h
Normal file
227
fsfw/rmap/RMAP.h
Normal file
@ -0,0 +1,227 @@
|
||||
#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_ */
|
115
fsfw/rmap/RMAPChannelIF.h
Normal file
115
fsfw/rmap/RMAPChannelIF.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef RMAPCHANNELIF_H_
|
||||
#define RMAPCHANNELIF_H_
|
||||
|
||||
#include "RMAPCookie.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
class RMAPChannelIF {
|
||||
public:
|
||||
virtual ~RMAPChannelIF(){};
|
||||
/**
|
||||
* Reset an RMAP channel
|
||||
*
|
||||
* Clears the receive buffer (all received messages are deleted) and resets the descriptor table.
|
||||
* Also checks for errors in the descriptors and submits them to FDIR (aka stdout)
|
||||
*
|
||||
* @param channel to reset
|
||||
*
|
||||
* @return
|
||||
* - @c LINK_DOWN when the link is down and all replies were missed
|
||||
* - @c COMMAND_CHANNEL_DEACTIVATED if the channel's port is NULL
|
||||
* - @c RETURN_OK else
|
||||
*/
|
||||
virtual ReturnValue_t reset()=0;
|
||||
|
||||
/**
|
||||
* Check if a channel is active (ie has a port)
|
||||
*
|
||||
* @param channel_nr
|
||||
* @return
|
||||
* - @c COMMAND_OK if channel is active
|
||||
* - @c COMMAND_CHANNEL_DEACTIVATED if channel is deactivated
|
||||
*/
|
||||
virtual ReturnValue_t isActive()=0;
|
||||
|
||||
/**
|
||||
* Assign a SpaceWire port to the Channel
|
||||
*
|
||||
* @param port Number of the port. SpaceWire devices are mapped to port numbers to allow checking of the validity
|
||||
* @param dest_addr the destination address used by all packets sent from this channel
|
||||
* @param src_addr the source address used by all packets sent from this channel and used when checking incoming packets
|
||||
* @return
|
||||
* - @c COMMAND_OK if port was changed
|
||||
* - @c COMMAND_PORT_OUT_OF_RANGE if the port is invalid
|
||||
*/
|
||||
virtual ReturnValue_t setPort(int8_t port, uint8_t dest_addr,
|
||||
uint8_t src_addr)=0;
|
||||
|
||||
/**
|
||||
* Assign a SpaceWire port to the Channel
|
||||
*
|
||||
* same as setPort(int8_t port, uint8_t dest_addr, uint8_t src_addr), only the addresses are left unchanged
|
||||
*
|
||||
* @param port Number of the port. SpaceWire devices are mapped to port numbers to allow checking of the validity
|
||||
* @return
|
||||
* - @c COMMAND_OK if port was changed
|
||||
* - @c COMMAND_PORT_OUT_OF_RANGE if the port is invalid
|
||||
*/
|
||||
virtual ReturnValue_t setPort(int8_t port)=0;
|
||||
|
||||
/**
|
||||
* Send an RMAP command
|
||||
*
|
||||
* @param cookie the cookie used with this call
|
||||
* @param instruction the instruction byte that will be sent (this defines if it is a read or write command)
|
||||
* @param data data to be sent
|
||||
* @param datalen length of data
|
||||
* @return
|
||||
* - @c RETURN_OK
|
||||
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending command; command was not sent
|
||||
* - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len; command was not sent
|
||||
* - @c COMMAND_TOO_BIG 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
|
||||
* - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set
|
||||
* - @c NOT_SUPPORTED if you dont feel like implementing something...
|
||||
*/
|
||||
virtual ReturnValue_t sendCommand(RMAPCookie *cookie, uint8_t instruction,
|
||||
uint8_t *data, uint32_t datalen)=0;
|
||||
|
||||
/**
|
||||
* get the reply to an rmap command
|
||||
*
|
||||
* @param cookie the cookie the command was sent with
|
||||
* @param databuffer a pointer to a pointer the location of the reply will be written to
|
||||
* @param len a pointer to the variable the length of the reply will be written to
|
||||
* @return
|
||||
* - @c REPLY_NO_REPLY no reply was received
|
||||
* - @c REPLY_NOT_SENT command was not sent, implies no reply
|
||||
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent
|
||||
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still being processed)
|
||||
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last operation, data could not be processed. (transmission error)
|
||||
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)
|
||||
* - @c WRITE_REPLY_NOT_SUPPORTED
|
||||
* - all RMAP standard replies
|
||||
*/
|
||||
virtual ReturnValue_t getReply(RMAPCookie *cookie, uint8_t **databuffer,
|
||||
uint32_t *len)=0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cookie
|
||||
* @param data
|
||||
* @param datalen
|
||||
* @param databuffer
|
||||
* @param len
|
||||
* @param timeout_us
|
||||
* @return
|
||||
* - all replies of sendCommand() and getReply()
|
||||
* - @c REPLY_TIMEOUT timeout
|
||||
*/
|
||||
virtual ReturnValue_t sendCommandBlocking(RMAPCookie *cookie, uint8_t *data,
|
||||
uint32_t datalen, uint8_t **databuffer, uint32_t *len,
|
||||
uint32_t timeout_us)=0;
|
||||
|
||||
};
|
||||
|
||||
#endif /* RMAPCHANNELIF_H_ */
|
124
fsfw/rmap/RMAPCookie.cpp
Normal file
124
fsfw/rmap/RMAPCookie.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "RMAPChannelIF.h"
|
||||
#include "RMAPCookie.h"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
RMAPCookie::RMAPCookie() {
|
||||
this->header.dest_address = 0;
|
||||
this->header.protocol = 0x01;
|
||||
this->header.instruction = 0;
|
||||
this->header.dest_key = 0;
|
||||
this->header.source_address = 0;
|
||||
this->header.tid_h = 0;
|
||||
this->header.tid_l = 0;
|
||||
this->header.extended_address = 0;
|
||||
this->header.address_hh = 0;
|
||||
this->header.address_h = 0;
|
||||
this->header.address_l = 0;
|
||||
this->header.address_ll = 0;
|
||||
this->header.datalen_h = 0;
|
||||
this->header.datalen_m = 0;
|
||||
this->header.datalen_l = 0;
|
||||
this->header.header_crc = 0;
|
||||
this->channel = NULL;
|
||||
this->command_mask = 0;
|
||||
|
||||
this->dataCRC = 0;
|
||||
|
||||
this->maxReplyLen = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RMAPCookie::RMAPCookie(uint32_t set_address, uint8_t set_extended_address,
|
||||
RMAPChannelIF *set_channel, uint8_t set_command_mask, uint32_t maxReplyLen) {
|
||||
this->header.dest_address = 0;
|
||||
this->header.protocol = 0x01;
|
||||
this->header.instruction = 0;
|
||||
this->header.dest_key = 0;
|
||||
this->header.source_address = 0;
|
||||
this->header.tid_h = 0;
|
||||
this->header.tid_l = 0;
|
||||
this->header.extended_address = set_extended_address;
|
||||
setAddress(set_address);
|
||||
this->header.datalen_h = 0;
|
||||
this->header.datalen_m = 0;
|
||||
this->header.datalen_l = 0;
|
||||
this->header.header_crc = 0;
|
||||
this->channel = set_channel;
|
||||
this->command_mask = set_command_mask;
|
||||
this->dataCRC = 0;
|
||||
|
||||
this->maxReplyLen = maxReplyLen;
|
||||
}
|
||||
|
||||
|
||||
void RMAPCookie::setAddress(uint32_t address) {
|
||||
this->header.address_hh = (address & 0xFF000000) >> 24;
|
||||
this->header.address_h = (address & 0x00FF0000) >> 16;
|
||||
this->header.address_l = (address & 0x0000FF00) >> 8;
|
||||
this->header.address_ll = address & 0x000000FF;
|
||||
}
|
||||
|
||||
void RMAPCookie::setExtendedAddress(uint8_t extendedAddress) {
|
||||
this->header.extended_address = extendedAddress;
|
||||
}
|
||||
|
||||
void RMAPCookie::setChannel(RMAPChannelIF *channel) {
|
||||
this->channel = channel;
|
||||
}
|
||||
|
||||
void RMAPCookie::setCommandMask(uint8_t commandMask) {
|
||||
this->command_mask = commandMask;
|
||||
}
|
||||
|
||||
uint32_t RMAPCookie::getAddress() {
|
||||
return (header.address_hh << 24) + (header.address_h << 16)
|
||||
+ (header.address_l << 8) + (header.address_ll);
|
||||
}
|
||||
|
||||
uint8_t RMAPCookie::getExtendedAddress() {
|
||||
return header.extended_address;
|
||||
}
|
||||
|
||||
RMAPChannelIF *RMAPCookie::getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
uint8_t RMAPCookie::getCommandMask() {
|
||||
return command_mask;
|
||||
}
|
||||
|
||||
RMAPCookie::~RMAPCookie() {
|
||||
|
||||
}
|
||||
|
||||
uint32_t RMAPCookie::getMaxReplyLen() const {
|
||||
return maxReplyLen;
|
||||
}
|
||||
|
||||
void RMAPCookie::setMaxReplyLen(uint32_t maxReplyLen) {
|
||||
this->maxReplyLen = maxReplyLen;
|
||||
}
|
||||
|
||||
RMAPStructs::rmap_cmd_header* RMAPCookie::getHeader(){
|
||||
return &this->header;
|
||||
}
|
||||
|
||||
uint16_t RMAPCookie::getTransactionIdentifier() const {
|
||||
return static_cast<uint16_t>((header.tid_h << 8) | (header.tid_l));
|
||||
}
|
||||
|
||||
void RMAPCookie::setTransactionIdentifier(uint16_t id_) {
|
||||
header.tid_l = id_ & 0xFF;
|
||||
header.tid_h = (id_ >> 8 ) & 0xFF;
|
||||
}
|
||||
|
||||
uint32_t RMAPCookie::getDataLength() const {
|
||||
return static_cast<uint32_t>(header.datalen_h << 16 | header.datalen_m << 8 | header.datalen_l);
|
||||
}
|
||||
void RMAPCookie::setDataLength(uint32_t length_) {
|
||||
header.datalen_l = length_ & 0xff;
|
||||
header.datalen_m = (length_ >> 8) & 0xff;
|
||||
header.datalen_h = (length_ >> 16) & 0xff;
|
||||
}
|
58
fsfw/rmap/RMAPCookie.h
Normal file
58
fsfw/rmap/RMAPCookie.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef RMAPCOOKIE_H_
|
||||
#define RMAPCOOKIE_H_
|
||||
|
||||
#include "../devicehandlers/CookieIF.h"
|
||||
#include "rmapStructs.h"
|
||||
|
||||
class RMAPChannelIF;
|
||||
|
||||
class RMAPCookie : public CookieIF {
|
||||
public:
|
||||
//To Uli: Sorry, I need an empty ctor to initialize an array of cookies.
|
||||
RMAPCookie();
|
||||
|
||||
RMAPCookie(uint32_t set_address, uint8_t set_extended_address,
|
||||
RMAPChannelIF *set_channel, uint8_t set_command_mask, uint32_t maxReplyLen = 0);
|
||||
virtual ~RMAPCookie();
|
||||
|
||||
|
||||
void setAddress(uint32_t address);
|
||||
uint32_t getAddress();
|
||||
|
||||
void setExtendedAddress(uint8_t);
|
||||
uint8_t getExtendedAddress();
|
||||
|
||||
void setChannel(RMAPChannelIF *channel);
|
||||
RMAPChannelIF *getChannel();
|
||||
|
||||
void setCommandMask(uint8_t commandMask);
|
||||
uint8_t getCommandMask();
|
||||
|
||||
uint32_t getMaxReplyLen() const;
|
||||
void setMaxReplyLen(uint32_t maxReplyLen);
|
||||
|
||||
uint16_t getTransactionIdentifier() const;
|
||||
void setTransactionIdentifier(uint16_t id_);
|
||||
|
||||
RMAPStructs::rmap_cmd_header* getHeader();
|
||||
|
||||
uint32_t getDataLength() const;
|
||||
void setDataLength(uint32_t lenght_);
|
||||
|
||||
uint8_t getDataCrc() const {
|
||||
return dataCRC;
|
||||
}
|
||||
|
||||
void setDataCrc(uint8_t dataCrc) {
|
||||
dataCRC = dataCrc;
|
||||
}
|
||||
|
||||
protected:
|
||||
RMAPStructs::rmap_cmd_header header;
|
||||
RMAPChannelIF *channel;
|
||||
uint8_t command_mask;
|
||||
uint32_t maxReplyLen;
|
||||
uint8_t dataCRC;
|
||||
};
|
||||
|
||||
#endif /* RMAPCOOKIE_H_ */
|
47
fsfw/rmap/RmapDeviceCommunicationIF.cpp
Normal file
47
fsfw/rmap/RmapDeviceCommunicationIF.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "RmapDeviceCommunicationIF.h"
|
||||
#include "RMAP.h"
|
||||
|
||||
//TODO Cast here are all potential bugs
|
||||
RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() {
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(CookieIF* cookie,
|
||||
uint8_t* data, uint32_t len) {
|
||||
return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(CookieIF* cookie) {
|
||||
return RMAP::getWriteReply((RMAPCookie *) cookie);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage(
|
||||
CookieIF* cookie) {
|
||||
return RMAP::sendReadCommand((RMAPCookie *) cookie,
|
||||
((RMAPCookie *) cookie)->getMaxReplyLen());
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(CookieIF* cookie,
|
||||
uint8_t** buffer, uint32_t* size) {
|
||||
return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::setAddress(CookieIF* cookie,
|
||||
uint32_t address) {
|
||||
|
||||
((RMAPCookie *) cookie)->setAddress(address);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t RmapDeviceCommunicationIF::getAddress(CookieIF* cookie) {
|
||||
return ((RMAPCookie *) cookie)->getAddress();
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::setParameter(CookieIF* cookie,
|
||||
uint32_t parameter) {
|
||||
//TODO Empty?
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint32_t RmapDeviceCommunicationIF::getParameter(CookieIF* cookie) {
|
||||
return 0;
|
||||
}
|
80
fsfw/rmap/RmapDeviceCommunicationIF.h
Normal file
80
fsfw/rmap/RmapDeviceCommunicationIF.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_
|
||||
#define MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_
|
||||
|
||||
#include "../devicehandlers/DeviceCommunicationIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class is a implementation of a DeviceCommunicationIF for RMAP calls. It expects RMAPCookies or a derived class of RMAPCookies
|
||||
*
|
||||
* @details The open, close and reOpen calls are mission specific
|
||||
* The open call might return any child of RMAPCookies
|
||||
*
|
||||
* \ingroup rmap
|
||||
*/
|
||||
class RmapDeviceCommunicationIF: public DeviceCommunicationIF {
|
||||
|
||||
public:
|
||||
virtual ~RmapDeviceCommunicationIF();
|
||||
|
||||
|
||||
/**
|
||||
* This method is mission specific as the open call will return a mission specific cookie
|
||||
*
|
||||
* @param cookie A cookie, can be mission specific subclass of RMAP Cookie
|
||||
* @param address The address of the RMAP Cookie
|
||||
* @param maxReplyLen Maximum length of expected reply
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t open(CookieIF **cookie, uint32_t address,
|
||||
uint32_t maxReplyLen) = 0;
|
||||
|
||||
/**
|
||||
* Use an existing cookie to open a connection to a new DeviceCommunication.
|
||||
* The previous connection must not be closed.
|
||||
* If the returnvalue is not RETURN_OK, the cookie is unchanged and
|
||||
* can be used with the previous connection.
|
||||
*
|
||||
* @param cookie
|
||||
* @param address
|
||||
* @param maxReplyLen
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t reOpen(CookieIF *cookie, uint32_t address,
|
||||
uint32_t maxReplyLen) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Closing call of connection and memory free of cookie. Mission dependent call
|
||||
* @param cookie
|
||||
*/
|
||||
virtual void close(CookieIF *cookie) = 0;
|
||||
|
||||
//SHOULDDO can data be const?
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param cookie Expects an RMAPCookie or derived from RMAPCookie Class
|
||||
* @param data Data to be send
|
||||
* @param len Length of the data to be send
|
||||
* @return - Return codes of RMAP::sendWriteCommand()
|
||||
*/
|
||||
virtual ReturnValue_t sendMessage(CookieIF *cookie, uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
virtual ReturnValue_t getSendSuccess(CookieIF *cookie);
|
||||
|
||||
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie);
|
||||
|
||||
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||
uint32_t *size);
|
||||
|
||||
virtual ReturnValue_t setAddress(CookieIF *cookie, uint32_t address);
|
||||
|
||||
virtual uint32_t getAddress(CookieIF *cookie);
|
||||
|
||||
virtual ReturnValue_t setParameter(CookieIF *cookie, uint32_t parameter);
|
||||
|
||||
virtual uint32_t getParameter(CookieIF *cookie);
|
||||
};
|
||||
|
||||
#endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */
|
98
fsfw/rmap/rmapStructs.h
Normal file
98
fsfw/rmap/rmapStructs.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef RMAPSTRUCTS_H_
|
||||
#define RMAPSTRUCTS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//SHOULDDO: having the defines within a namespace would be nice. Problem are the defines referencing the previous define, eg RMAP_COMMAND_WRITE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// RMAP command bits
|
||||
//#define RMAP_COMMAND_BIT_INCREMENT 2
|
||||
//#define RMAP_COMMAND_BIT_REPLY 3
|
||||
//#define RMAP_COMMAND_BIT_WRITE 5
|
||||
//#define RMAP_COMMAND_BIT_VERIFY 4
|
||||
//#define RMAP_COMMAND_BIT 6
|
||||
|
||||
namespace RMAPIds{
|
||||
|
||||
static const uint8_t RMAP_COMMAND_BIT_INCREMENT = 2;
|
||||
static const uint8_t RMAP_COMMAND_BIT_REPLY = 3;
|
||||
static const uint8_t RMAP_COMMAND_BIT_WRITE = 5;
|
||||
static const uint8_t RMAP_COMMAND_BIT_VERIFY = 4;
|
||||
static const uint8_t RMAP_COMMAND_BIT = 6;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// RMAP commands
|
||||
static const uint8_t RMAP_COMMAND_WRITE = ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY));
|
||||
static const uint8_t RMAP_COMMAND_READ = ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY));
|
||||
static const uint8_t RMAP_REPLY_WRITE = ((1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY));
|
||||
static const uint8_t RMAP_REPLY_READ = ((1<<RMAP_COMMAND_BIT_REPLY));
|
||||
//#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||
//#define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY))
|
||||
//#define RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||
|
||||
//#define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||
//#define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY))
|
||||
//#define RMAP_REPLY_READ ((1<<RMAP_COMMAND_BIT_REPLY))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// useful info
|
||||
static const uint8_t RMAP_COMMAND_HEADER_LEN = 16;
|
||||
static const uint8_t RMAP_WRITE_REPLY_HEADER_LEN = 8;
|
||||
static const uint8_t RMAP_READ_REPLY_HEADER_LEN = 12;
|
||||
static const uint8_t RMAP_DATA_FOOTER_SIZE = 1; //SIZE OF CRC
|
||||
//#define RMAP_COMMAND_HEADER_LEN 16
|
||||
//#define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||
//#define RMAP_READ_REPLY_HEADER_LEN 12
|
||||
|
||||
}
|
||||
|
||||
namespace RMAPStructs {
|
||||
struct rmap_cmd_header {
|
||||
uint8_t dest_address;
|
||||
uint8_t protocol;
|
||||
uint8_t instruction;
|
||||
uint8_t dest_key;
|
||||
uint8_t source_address;
|
||||
uint8_t tid_h;
|
||||
uint8_t tid_l;
|
||||
uint8_t extended_address;
|
||||
uint8_t address_hh;
|
||||
uint8_t address_h;
|
||||
uint8_t address_l;
|
||||
uint8_t address_ll;
|
||||
uint8_t datalen_h;
|
||||
uint8_t datalen_m;
|
||||
uint8_t datalen_l;
|
||||
uint8_t header_crc;
|
||||
};
|
||||
|
||||
struct rmap_read_reply_header {
|
||||
uint8_t dest_address;
|
||||
uint8_t protocol;
|
||||
uint8_t instruction;
|
||||
uint8_t status;
|
||||
uint8_t source_address;
|
||||
uint8_t tid_h;
|
||||
uint8_t tid_l;
|
||||
uint8_t reserved;
|
||||
uint8_t datalen_h;
|
||||
uint8_t datalen_m;
|
||||
uint8_t datalen_l;
|
||||
uint8_t header_crc;
|
||||
};
|
||||
|
||||
struct rmap_write_reply_header {
|
||||
uint8_t dest_address;
|
||||
uint8_t protocol;
|
||||
uint8_t instruction;
|
||||
uint8_t status;
|
||||
uint8_t source_address;
|
||||
uint8_t tid_h;
|
||||
uint8_t tid_l;
|
||||
uint8_t header_crc;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* RMAPSTRUCTS_H_ */
|
Reference in New Issue
Block a user