Adding Code for Linux
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
ReturnValue_t RMAP::reset(RMAPCookie* cookie) {
|
||||
return cookie->channel->reset();
|
||||
return cookie->getChannel()->reset();
|
||||
}
|
||||
|
||||
RMAP::RMAP(){
|
||||
@ -22,7 +22,7 @@ ReturnValue_t RMAP::sendWriteCommand(RMAPCookie *cookie, uint8_t* buffer,
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
instruction = RMAP_COMMAND_WRITE | cookie->command_mask;
|
||||
instruction = RMAPIds::RMAP_COMMAND_WRITE | cookie->getCommandMask();
|
||||
return cookie->getChannel()->sendCommand(cookie, instruction, buffer,
|
||||
length);
|
||||
|
||||
@ -32,7 +32,7 @@ ReturnValue_t RMAP::getWriteReply(RMAPCookie *cookie) {
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
if (cookie->header.instruction & (1 << RMAP_COMMAND_BIT_WRITE)) {
|
||||
if (cookie->getHeader()->instruction & (1 << RMAPIds::RMAP_COMMAND_BIT_WRITE)) {
|
||||
return cookie->getChannel()->getReply(cookie, NULL, NULL);
|
||||
} else {
|
||||
return REPLY_MISSMATCH;
|
||||
@ -53,8 +53,8 @@ ReturnValue_t RMAP::sendReadCommand(RMAPCookie *cookie, uint32_t expLength) {
|
||||
if (cookie->getChannel() == NULL) {
|
||||
return COMMAND_NO_CHANNEL;
|
||||
}
|
||||
command = RMAP_COMMAND_READ
|
||||
| (cookie->command_mask & ~(1 << RMAP_COMMAND_BIT_VERIFY));
|
||||
command = RMAPIds::RMAP_COMMAND_READ
|
||||
| (cookie->getCommandMask() & ~(1 << RMAPIds::RMAP_COMMAND_BIT_VERIFY));
|
||||
|
||||
return cookie->getChannel()->sendCommand(cookie, command, NULL, expLength);
|
||||
|
||||
@ -68,7 +68,7 @@ ReturnValue_t RMAP::getReadReply(RMAPCookie *cookie, uint8_t **buffer,
|
||||
if (buffer == NULL || size == NULL) {
|
||||
return DeviceCommunicationIF::NULLPOINTER;
|
||||
}
|
||||
if (cookie->header.instruction & (1 << RMAP_COMMAND_BIT_WRITE)) {
|
||||
if (cookie->getHeader()->instruction & (1 << RMAPIds::RMAP_COMMAND_BIT_WRITE)) {
|
||||
return REPLY_MISSMATCH;
|
||||
} else {
|
||||
return cookie->getChannel()->getReply(cookie, buffer, size);
|
||||
|
@ -1,11 +1,12 @@
|
||||
#ifndef RMAPCHANNELIF_H_
|
||||
#define RMAPCHANNELIF_H_
|
||||
|
||||
#include <framework/rmap/RMAP.h>
|
||||
#include <framework/tasks/PeriodicTaskIF.h>
|
||||
#include <framework/rmap/RMAPCookie.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
class RMAPChannelIF: public RMAP {
|
||||
class RMAPChannelIF {
|
||||
public:
|
||||
virtual ~RMAPChannelIF(){};
|
||||
/**
|
||||
* Reset an RMAP channel
|
||||
*
|
||||
@ -42,7 +43,7 @@ public:
|
||||
* - @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, PeriodicTaskIF* currentTask)=0;
|
||||
uint8_t src_addr)=0;
|
||||
|
||||
/**
|
||||
* Assign a SpaceWire port to the Channel
|
||||
@ -54,7 +55,7 @@ public:
|
||||
* - @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, PeriodicTaskIF* currentTask)=0;
|
||||
virtual ReturnValue_t setPort(int8_t port)=0;
|
||||
|
||||
/**
|
||||
* Send an RMAP command
|
||||
|
@ -20,13 +20,11 @@ RMAPCookie::RMAPCookie() {
|
||||
this->header.datalen_m = 0;
|
||||
this->header.datalen_l = 0;
|
||||
this->header.header_crc = 0;
|
||||
|
||||
|
||||
this->txdesc = NULL;
|
||||
this->rxdesc_index = 0;
|
||||
this->channel = NULL;
|
||||
this->command_mask = 0;
|
||||
|
||||
this->dataCRC = 0;
|
||||
|
||||
this->maxReplyLen = 0;
|
||||
}
|
||||
|
||||
@ -47,11 +45,9 @@ RMAPCookie::RMAPCookie(uint32_t set_address, uint8_t set_extended_address,
|
||||
this->header.datalen_m = 0;
|
||||
this->header.datalen_l = 0;
|
||||
this->header.header_crc = 0;
|
||||
|
||||
this->txdesc = NULL;
|
||||
this->rxdesc_index = 0;
|
||||
this->channel = set_channel;
|
||||
this->command_mask = set_command_mask;
|
||||
this->dataCRC = 0;
|
||||
|
||||
this->maxReplyLen = maxReplyLen;
|
||||
}
|
||||
@ -104,3 +100,25 @@ uint32_t RMAPCookie::getMaxReplyLen() const {
|
||||
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;
|
||||
}
|
||||
|
@ -7,8 +7,6 @@
|
||||
class RMAPChannelIF;
|
||||
|
||||
class RMAPCookie : public Cookie{
|
||||
friend class RMAP;
|
||||
friend class RmapSPWChannel;
|
||||
public:
|
||||
//To Uli: Sorry, I need an empty ctor to initialize an array of cookies.
|
||||
RMAPCookie();
|
||||
@ -20,24 +18,41 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
//rmap_cookie* getDeviceDescriptor();
|
||||
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;
|
||||
void *txdesc;
|
||||
uint8_t rxdesc_index;
|
||||
RMAPChannelIF *channel;
|
||||
uint8_t command_mask;
|
||||
uint32_t maxReplyLen;
|
||||
uint8_t dataCRC;
|
||||
};
|
||||
|
||||
#endif /* RMAPCOOKIE_H_ */
|
||||
|
47
rmap/RmapDeviceCommunicationIF.cpp
Normal file
47
rmap/RmapDeviceCommunicationIF.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <framework/rmap/RmapDeviceCommunicationIF.h>
|
||||
#include <framework/rmap/RMAP.h>
|
||||
|
||||
//TODO Cast here are all potential bugs
|
||||
RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() {
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(Cookie* cookie,
|
||||
uint8_t* data, uint32_t len) {
|
||||
return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(Cookie* cookie) {
|
||||
return RMAP::getWriteReply((RMAPCookie *) cookie);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage(
|
||||
Cookie* cookie) {
|
||||
return RMAP::sendReadCommand((RMAPCookie *) cookie,
|
||||
((RMAPCookie *) cookie)->getMaxReplyLen());
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(Cookie* cookie,
|
||||
uint8_t** buffer, uint32_t* size) {
|
||||
return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::setAddress(Cookie* cookie,
|
||||
uint32_t address) {
|
||||
|
||||
((RMAPCookie *) cookie)->setAddress(address);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t RmapDeviceCommunicationIF::getAddress(Cookie* cookie) {
|
||||
return ((RMAPCookie *) cookie)->getAddress();
|
||||
}
|
||||
|
||||
ReturnValue_t RmapDeviceCommunicationIF::setParameter(Cookie* cookie,
|
||||
uint32_t parameter) {
|
||||
//TODO Empty?
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint32_t RmapDeviceCommunicationIF::getParameter(Cookie* cookie) {
|
||||
return 0;
|
||||
}
|
80
rmap/RmapDeviceCommunicationIF.h
Normal file
80
rmap/RmapDeviceCommunicationIF.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_
|
||||
#define MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_
|
||||
|
||||
#include <framework/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(Cookie **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(Cookie *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(Cookie *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(Cookie *cookie, uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
virtual ReturnValue_t getSendSuccess(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
|
||||
uint32_t *size);
|
||||
|
||||
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address);
|
||||
|
||||
virtual uint32_t getAddress(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter);
|
||||
|
||||
virtual uint32_t getParameter(Cookie *cookie);
|
||||
};
|
||||
|
||||
#endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */
|
@ -1,744 +0,0 @@
|
||||
#include <framework/rmap/RmapSPWChannel.h>
|
||||
extern "C" {
|
||||
#include <bsp_flp/hw_timer/hw_timer.h>
|
||||
#include <bsp_flp/crc/crc.h>
|
||||
}
|
||||
|
||||
#include <framework/datapool/DataSet.h>
|
||||
#include <framework/datapool/PoolVariable.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//bits for the failure table
|
||||
#define RMAP_RX_FAIL_CHECKED 0
|
||||
#define RMAP_RX_FAIL_EEP 1
|
||||
#define RMAP_RX_FAIL_TRUNC 2
|
||||
#define RMAP_RX_FAIL_LEN 3
|
||||
#define RMAP_RX_FAIL_CRC 4
|
||||
#define RMAP_RX_FAIL_DST_ADDR 5
|
||||
#define RMAP_RX_FAIL_PROTO 6
|
||||
#define RMAP_RX_FAIL_INSTR_TYPE 7 //this is when the instruction byte is really wrong (must be caused by device)
|
||||
#define RMAP_RX_FAIL_INSTR 8 //this is when a wrong instruction byte was caused by a wrong instruction sent by the host and detected by the device
|
||||
#define RMAP_RX_FAIL_SRC_ADDR 9
|
||||
#define RMAP_RX_FAIL_LEN_MISSMATCH 10
|
||||
#define RMAP_RX_FAIL_WRONG_REPLY 11 //a read command was answered by a write reply or the other way round
|
||||
//pad a number so it is word aligned (32bit)
|
||||
#define BYTES2WORDS(number) (((number) +3)/4)
|
||||
|
||||
RmapSPWChannel::RmapSPWChannel(object_id_t setObjectId,
|
||||
uint16_t buffersize_words, uint32_t maxPacketSize, int8_t portNr,
|
||||
uint8_t dest_addr, uint8_t src_addr, PeriodicTaskIF* currentTask,
|
||||
datapool::opus_variable_id portVariable) :
|
||||
SystemObject(setObjectId), port(NULL), rx_index(0), max_rx(128), tx_index(
|
||||
0), max_tx(64), src_addr(src_addr), dest_addr(dest_addr), portPoolId(
|
||||
portVariable) {
|
||||
buffer = new uint32_t[buffersize_words];
|
||||
buffer_pointer = buffer;
|
||||
end_of_buffer = &buffer[buffersize_words];
|
||||
max_packet_len = maxPacketSize & 0x1FFFFFC;
|
||||
tid = 0;
|
||||
failure_table = new uint16_t[128];
|
||||
setPort(portNr, dest_addr, src_addr, currentTask);
|
||||
}
|
||||
|
||||
RmapSPWChannel::~RmapSPWChannel() {
|
||||
delete[] buffer;
|
||||
delete[] failure_table;
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::reset() {
|
||||
uint8_t link_down = 0;
|
||||
uint8_t missed, i;
|
||||
uint32_t state;
|
||||
|
||||
//check if channel has a port
|
||||
if (port == NULL) {
|
||||
return COMMAND_CHANNEL_DEACTIVATED;
|
||||
}
|
||||
|
||||
//check state of SPW
|
||||
state = spw_get_state(port);
|
||||
if (state != SPW_STATE_RUN) {
|
||||
triggerEvent(SPW_LINK_DOWN, getCurrentPortNr());
|
||||
link_down++;
|
||||
}
|
||||
//SPW link errors
|
||||
if ((state = (port->SPWSTR & 0x1de)) != 0) {
|
||||
reportSpwstr(state);
|
||||
}
|
||||
//check DMA errors
|
||||
if ((state = (port->SPWCHN & 0x180)) != 0) {
|
||||
triggerEvent(SPW_ERROR, SPW_DMA, state);
|
||||
}
|
||||
|
||||
//hard reset spw
|
||||
//only safe way to reset the descriptors
|
||||
|
||||
spw_reset(port);
|
||||
|
||||
spw_reset_rxdesc_table(port);
|
||||
spw_reset_txdesc_table(port);
|
||||
|
||||
//reset internal buffer
|
||||
buffer_pointer = buffer;
|
||||
|
||||
#ifdef LEON
|
||||
asm("flush");
|
||||
#endif
|
||||
|
||||
//check how many packets were received
|
||||
missed = 0;
|
||||
|
||||
if ((rx_index != 0)
|
||||
&& (rx_descriptor_table[rx_index - 1].word0
|
||||
& (1 << SPW_DESC_RX_ENABLE))) {
|
||||
// printf("word 0 = %08lx\n",
|
||||
// rx_descriptor_table[rx_index - 1].word0);
|
||||
for (missed = 1; missed < rx_index; missed++) {
|
||||
if (!(rx_descriptor_table[rx_index - 1 - missed].word0
|
||||
& (1 << SPW_DESC_RX_ENABLE)))
|
||||
break;
|
||||
}
|
||||
triggerEvent(RMAP_MISSED_REPLIES, missed);
|
||||
//missed is number of missed replies
|
||||
|
||||
}
|
||||
if (missed == rx_index) {
|
||||
link_down++;
|
||||
}
|
||||
|
||||
for (i = rx_index - missed; i > 0; i--) {
|
||||
if (!(failure_table[i - 1] & 1)) {
|
||||
checkRxDescPacket(&(rx_descriptor_table[i - 1]),
|
||||
&(failure_table[i - 1]));
|
||||
}
|
||||
if (failure_table[i - 1] & 0xFFFE) {
|
||||
reportFailures(failure_table[i - 1], i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
//reset descriptor counter
|
||||
rx_index = 0;
|
||||
tx_index = 0;
|
||||
|
||||
//clear all descriptors to get rid of unused ones
|
||||
spw_rx_desc *rx_desc;
|
||||
i = 0;
|
||||
for (rx_desc = rx_descriptor_table; rx_desc < &rx_descriptor_table[max_rx];
|
||||
rx_desc++) {
|
||||
rx_desc->word0 = 0;
|
||||
failure_table[i++] = 0;
|
||||
}
|
||||
spw_tx_desc *tx_desc;
|
||||
for (tx_desc = tx_descriptor_table; tx_desc < &tx_descriptor_table[max_tx];
|
||||
tx_desc++) {
|
||||
tx_desc->word0 = 0;
|
||||
}
|
||||
|
||||
//restart spw
|
||||
spw_start(port);
|
||||
|
||||
if (link_down > 1) {
|
||||
return LINK_DOWN;
|
||||
}
|
||||
return RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::isActive() {
|
||||
if (port == NULL) {
|
||||
return COMMAND_CHANNEL_DEACTIVATED;
|
||||
}
|
||||
uint32_t state = spw_get_state(port);
|
||||
if (state != SPW_STATE_RUN) {
|
||||
return LINK_DOWN;
|
||||
}
|
||||
return RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::setPort(int8_t portNr, uint8_t dest_addr,
|
||||
uint8_t src_addr, PeriodicTaskIF* currentTask) {
|
||||
|
||||
SPW_dev *new_port;
|
||||
|
||||
//only accept ports from a list or -1, which disables channel
|
||||
if (portNr >= SPW_devices.len && portNr < -1) {
|
||||
return COMMAND_PORT_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
//check if crc is enabled
|
||||
|
||||
if (portNr != -1) {
|
||||
new_port = SPW_devices.devices[portNr];
|
||||
if (!spw_crc_enabled(new_port)) {
|
||||
return NO_HW_CRC;
|
||||
}
|
||||
} else {
|
||||
new_port = NULL;
|
||||
}
|
||||
|
||||
//anounce change
|
||||
triggerEvent(RMAP_SWITCHED_PORT, portNr, getCurrentPortNr());
|
||||
if (portPoolId != 0) {
|
||||
DataSet mySet;
|
||||
PoolVariable<int8_t> channel(portPoolId, &mySet,
|
||||
PoolVariableIF::VAR_WRITE);
|
||||
mySet.read();
|
||||
channel = portNr;
|
||||
mySet.commit(PoolVariableIF::VALID);
|
||||
}
|
||||
|
||||
//reset the old port to clear pending errors etc
|
||||
reset();
|
||||
//assign new port
|
||||
this->port = new_port;
|
||||
|
||||
if (new_port == NULL) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
//stop the new port
|
||||
spw_stop(new_port);
|
||||
//make sure the new port has the max len set
|
||||
new_port->SPWRXL = max_packet_len;
|
||||
//set the addresses
|
||||
this->dest_addr = dest_addr;
|
||||
this->src_addr = src_addr;
|
||||
new_port->SPWNDR = src_addr;
|
||||
//set descriptor table
|
||||
tx_descriptor_table = spw_get_tx_descriptor_table(new_port);
|
||||
rx_descriptor_table = spw_get_rx_descriptor_table(new_port);
|
||||
spw_reset_rxdesc_table(new_port);
|
||||
spw_reset_txdesc_table(new_port);
|
||||
//reset the channel
|
||||
spw_start(new_port);
|
||||
currentTask->sleepFor(10);
|
||||
reset();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::setPort(int8_t port, PeriodicTaskIF* currentTask) {
|
||||
return setPort(port, this->dest_addr, this->src_addr, currentTask);
|
||||
}
|
||||
|
||||
spw_rx_desc* RmapSPWChannel::findReply(RMAPCookie* cookie) {
|
||||
spw_rx_desc *rxdesc;
|
||||
uint8_t i;
|
||||
|
||||
//look downwards
|
||||
for (i = cookie->rxdesc_index; i < 200; i--) {
|
||||
if ((rxdesc = checkRxDesc(cookie, i)) != NULL) {
|
||||
return rxdesc;
|
||||
}
|
||||
}
|
||||
//look upwards
|
||||
for (i = cookie->rxdesc_index + 1; i < max_rx; i++) {
|
||||
if ((rxdesc = checkRxDesc(cookie, i)) != NULL) {
|
||||
return rxdesc;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::sendCommand(RMAPCookie* cookie,
|
||||
uint8_t instruction, uint8_t* data, uint32_t datalen) {
|
||||
|
||||
uint8_t headerlen = RMAP_COMMAND_HEADER_LEN - 1;
|
||||
|
||||
//check if channel has a port
|
||||
if (port == NULL) {
|
||||
return COMMAND_CHANNEL_DEACTIVATED;
|
||||
}
|
||||
|
||||
//max send limit
|
||||
if ((instruction & (1 << RMAP_COMMAND_BIT_WRITE))
|
||||
&& (datalen & ~0xFFFFFF)) {
|
||||
printf("application wants to send to much data with cookie at %p\n",
|
||||
cookie);
|
||||
return TOO_MUCH_DATA;
|
||||
}
|
||||
//max receive limit
|
||||
if ((!(instruction & (1 << RMAP_COMMAND_BIT_WRITE)))
|
||||
&& (datalen + 1 + RMAP_READ_REPLY_HEADER_LEN > max_packet_len)) {
|
||||
printf("application wants to read too much data with cookie at %p\n",
|
||||
cookie);
|
||||
return TOO_MUCH_DATA;
|
||||
}
|
||||
|
||||
//check if enough space is left in the buffer
|
||||
//must be checked against max_packet_len, as you can not tell what hw will do,
|
||||
//except that it will write this number at most
|
||||
if ((buffer_pointer + BYTES2WORDS(max_packet_len))
|
||||
> end_of_buffer) {
|
||||
printf("buffer is full, cookie is %p\n", cookie);
|
||||
return COMMAND_BUFFER_FULL;
|
||||
}
|
||||
|
||||
//we allow tx descriptor wrap at user discretion, but check we have rx descriptors available
|
||||
//as we dont wrap them
|
||||
//note: [tr]x_index will be incremented when done
|
||||
if (rx_index >= max_rx) {
|
||||
triggerEvent(RMAP_NO_RX_DESCRIPTORS, 0);
|
||||
return COMMAND_NO_DESCRIPTORS_AVAILABLE;
|
||||
}
|
||||
if (tx_index >= max_tx) {
|
||||
if (max_tx == 64) {
|
||||
tx_index = 0;
|
||||
} else {
|
||||
triggerEvent(RMAP_NO_TX_DESCRIPTORS, 0);
|
||||
return COMMAND_NO_DESCRIPTORS_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
//check if tx descriptor is activated, which means we wrapped the table
|
||||
//and came to a descriptor not yet sent
|
||||
#ifdef LEON
|
||||
asm("flush");
|
||||
#endif
|
||||
if (tx_descriptor_table[tx_index].word0 & (1 << SPW_DESC_TX_ENABLE)) {
|
||||
return COMMAND_NO_DESCRIPTORS_AVAILABLE;
|
||||
}
|
||||
|
||||
//prepare header
|
||||
//set addresses
|
||||
cookie->header.source_address = src_addr;
|
||||
cookie->header.dest_address = dest_addr;
|
||||
//set instruction
|
||||
cookie->header.instruction = instruction;
|
||||
//set the tid
|
||||
cookie->header.tid_l = tid & 0xff;
|
||||
cookie->header.tid_h = (tid >> 8) & 0xff;
|
||||
tid++;
|
||||
//set datalen
|
||||
cookie->header.datalen_l = datalen & 0xff;
|
||||
cookie->header.datalen_m = (datalen >> 8) & 0xff;
|
||||
cookie->header.datalen_h = (datalen >> 16) & 0xff;
|
||||
|
||||
//configure rx_descriptor
|
||||
rx_descriptor_table[rx_index].word1 = (uint32_t) buffer_pointer;
|
||||
rx_descriptor_table[rx_index].word0 = (1 << SPW_DESC_RX_ENABLE);
|
||||
|
||||
//inc buffer
|
||||
if (instruction & (1 << RMAP_COMMAND_BIT_WRITE)) {
|
||||
buffer_pointer += BYTES2WORDS(RMAP_WRITE_REPLY_HEADER_LEN);
|
||||
} else {
|
||||
buffer_pointer += BYTES2WORDS(RMAP_READ_REPLY_HEADER_LEN + datalen + 1); //+1 for crc
|
||||
}
|
||||
|
||||
//configure tx_descriptor
|
||||
tx_descriptor_table[tx_index].word1 = (uint32_t) &cookie->header;
|
||||
if (instruction & (1 << RMAP_COMMAND_BIT_WRITE)) {
|
||||
tx_descriptor_table[tx_index].word2 = datalen & 0xFFFFFF;
|
||||
} else {
|
||||
tx_descriptor_table[tx_index].word2 = 0;
|
||||
}
|
||||
tx_descriptor_table[tx_index].word3 = (uint32_t) data;
|
||||
|
||||
if (instruction & (1 << RMAP_COMMAND_BIT_WRITE)) {
|
||||
tx_descriptor_table[tx_index].word0 = headerlen
|
||||
| (1 << SPW_DESC_TX_ENABLE) | (1 << SPW_DESC_TX_CRC_DATA)
|
||||
| (1 << SPW_DESC_TX_CRC_HEADER);
|
||||
} else {
|
||||
tx_descriptor_table[tx_index].word0 = headerlen
|
||||
| (1 << SPW_DESC_TX_ENABLE) | (1 << SPW_DESC_TX_CRC_HEADER);
|
||||
}
|
||||
|
||||
//remember descriptors to find them faster when looking for the reply
|
||||
cookie->txdesc = &(tx_descriptor_table[tx_index]);
|
||||
cookie->rxdesc_index = rx_index;
|
||||
|
||||
tx_index++;
|
||||
rx_index++;
|
||||
|
||||
//inform the hw about the new descriptors
|
||||
spw_new_rxdesc(port);
|
||||
spw_new_txdesc(port);
|
||||
|
||||
return RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::getReply(RMAPCookie* cookie, uint8_t** databuffer,
|
||||
uint32_t* len) {
|
||||
spw_rx_desc *rxdesc;
|
||||
ReturnValue_t result;
|
||||
uint32_t packetlen;
|
||||
//was the command sent right
|
||||
result = checkTxDesc(cookie);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
//command was sent
|
||||
//find the rx descriptor
|
||||
if ((rxdesc = findReply(cookie)) == NULL) {
|
||||
return REPLY_NO_REPLY;
|
||||
}
|
||||
//reply_header = (rmap_write_reply_header *) rxdesc->word1;
|
||||
if (databuffer != NULL) {
|
||||
packetlen = (rxdesc->word0 & 0x1FFFFFF);
|
||||
*databuffer = ((uint8_t *) rxdesc->word1) + RMAP_READ_REPLY_HEADER_LEN;
|
||||
*len = packetlen - RMAP_READ_REPLY_HEADER_LEN - 1;
|
||||
}
|
||||
result = ((RMAPStructs::rmap_write_reply_header *) (rxdesc->word1))->status;
|
||||
//result is an RMAP standard return code, not a ReturnValue_t, thus we check against 0
|
||||
//and do MAKE_RETURN_CODE(), or set to RETURN_OK respectively
|
||||
//if RETURN_OK == 0, this is not neccessary, but we should not make assumptions on the
|
||||
//value of ReturnValues
|
||||
if (result != 0) {
|
||||
result = ((RMAP::INTERFACE_ID << 8) + (result));
|
||||
} else {
|
||||
result = RETURN_OK;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::checkTxDesc(RMAPCookie* cookie) {
|
||||
RMAPStructs::rmap_cmd_header *header_desc;
|
||||
uint16_t tid_desc, tid_cookie;
|
||||
uint32_t status;
|
||||
#ifdef LEON
|
||||
asm("flush");
|
||||
#endif
|
||||
if (cookie->txdesc == NULL) {
|
||||
return REPLY_NOT_SENT;
|
||||
}
|
||||
header_desc =
|
||||
(RMAPStructs::rmap_cmd_header *) ((spw_tx_desc *) cookie->txdesc)->word1;
|
||||
status = ((spw_tx_desc *) cookie->txdesc)->word0
|
||||
& ((1 << SPW_DESC_TX_ENABLE) | (1 << SPW_DESC_TX_LINK_ERROR));
|
||||
tid_cookie = (cookie->header.tid_l) | (cookie->header.tid_h << 8);
|
||||
tid_desc = (header_desc->tid_l) | (header_desc->tid_h << 8);
|
||||
if (tid_cookie != tid_desc) {
|
||||
//tx descriptor was reused, we have no info so let's assume the best
|
||||
return RETURN_OK;
|
||||
}
|
||||
//was command sent or an error seen?
|
||||
if (status == (1 << SPW_DESC_TX_ENABLE)) {
|
||||
return REPLY_NOT_YET_SENT;
|
||||
}
|
||||
if (status & (1 << SPW_DESC_TX_LINK_ERROR)) {
|
||||
triggerEvent(SPW_ERROR, SPW_LINK_ERROR, 0);
|
||||
return REPLY_NOT_SENT;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
spw_rx_desc* RmapSPWChannel::checkRxDesc(RMAPCookie* cookie,
|
||||
uint8_t rxdesc_index) {
|
||||
uint16_t *failureEntry, tid_desc, tid_cookie;
|
||||
spw_rx_desc *rxdesc;
|
||||
RMAPStructs::rmap_read_reply_header *reply_header;
|
||||
|
||||
rxdesc = &rx_descriptor_table[rxdesc_index];
|
||||
failureEntry = &failure_table[rxdesc_index];
|
||||
|
||||
if (!(*failureEntry)) {
|
||||
checkRxDescPacket(rxdesc, failureEntry);
|
||||
}
|
||||
if (*failureEntry != 1 << RMAP_RX_FAIL_CHECKED) {
|
||||
return NULL;
|
||||
}
|
||||
//the packet has been checked and is formally correct
|
||||
//only thing left is to check tid and instruction:
|
||||
|
||||
reply_header = (RMAPStructs::rmap_read_reply_header *) rxdesc->word1;
|
||||
|
||||
tid_cookie = cookie->header.tid_l | (cookie->header.tid_h << 8);
|
||||
tid_desc = reply_header->tid_l | (reply_header->tid_h << 8);
|
||||
if (tid_desc != tid_cookie) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cookie->header.instruction & 0x3F) != reply_header->instruction) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_WRONG_REPLY);
|
||||
return NULL;
|
||||
}
|
||||
return rxdesc;
|
||||
|
||||
}
|
||||
|
||||
void RmapSPWChannel::checkRxDescPacket(spw_rx_desc* rxdesc,
|
||||
uint16_t* failureEntry) {
|
||||
uint32_t statusword, len;
|
||||
|
||||
#ifdef LEON
|
||||
asm("flush");
|
||||
#endif
|
||||
|
||||
statusword = rxdesc->word0;
|
||||
|
||||
if ((statusword & (1 << SPW_DESC_RX_ENABLE)) || (statusword == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*failureEntry = 1 << RMAP_RX_FAIL_CHECKED;
|
||||
|
||||
if (statusword & (1 << SPW_DESC_RX_EEP)) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_EEP);
|
||||
return;
|
||||
}
|
||||
|
||||
if (statusword & (1 << SPW_DESC_RX_TRUNCATED)) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_TRUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
len = statusword & 0x1FFFFFF;
|
||||
if (!(len >= 13 || len == 8)) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_LEN);
|
||||
return;
|
||||
}
|
||||
if (checkCrc((uint8_t*) rxdesc->word1, len) != RETURN_OK) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_CRC);
|
||||
return;
|
||||
}
|
||||
|
||||
checkRmapHeader((void *) rxdesc->word1, len, failureEntry);
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::checkCrc(uint8_t* packet, uint32_t len) {
|
||||
if (len == 8) {
|
||||
if (crc_calculate(packet, len) == 0) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
} else {
|
||||
if ((crc_calculate(packet, RMAP_READ_REPLY_HEADER_LEN) == 0)
|
||||
&& (crc_calculate(packet, len) == 0)) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RmapSPWChannel::checkRmapHeader(void* _header, uint32_t len,
|
||||
uint16_t* failureEntry) {
|
||||
RMAPStructs::rmap_read_reply_header *header =
|
||||
(RMAPStructs::rmap_read_reply_header *) _header;
|
||||
uint32_t datalen;
|
||||
|
||||
if (header->dest_address != src_addr) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_DST_ADDR);
|
||||
}
|
||||
|
||||
if (header->protocol != 0x01) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_PROTO);
|
||||
}
|
||||
|
||||
if (header->instruction & 0xC0) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_INSTR_TYPE);
|
||||
} else { //hope that works...
|
||||
if ((!(header->instruction & (1 << RMAP_COMMAND_BIT_REPLY)))
|
||||
|| ((header->instruction & (1 << RMAP_COMMAND_BIT_VERIFY))
|
||||
&& (!(header->instruction
|
||||
& (1 << RMAP_COMMAND_BIT_WRITE))))
|
||||
|| (header->instruction & 3)) {
|
||||
if (header->status == REPLY_UNUSED_PACKET_TYPE_OR_COMMAND_CODE) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_INSTR);
|
||||
} else {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_INSTR_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (header->instruction & (1 << RMAP_COMMAND_BIT_WRITE)) {
|
||||
if (len != 8) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_INSTR_TYPE);
|
||||
}
|
||||
} else {
|
||||
if (len == 8) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_INSTR_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
if (header->source_address != dest_addr) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_SRC_ADDR);
|
||||
}
|
||||
|
||||
if (len != 8) {
|
||||
datalen = header->datalen_l | (header->datalen_m << 8)
|
||||
| (header->datalen_h << 16);
|
||||
if (datalen + RMAP_READ_REPLY_HEADER_LEN + 1 != len) {
|
||||
*failureEntry |= (1 << RMAP_RX_FAIL_LEN_MISSMATCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::sendCommandBlocking(RMAPCookie *cookie,
|
||||
uint8_t *data, uint32_t datalen, uint8_t **databuffer, uint32_t *len,
|
||||
uint32_t timeout_us) {
|
||||
uint32_t time;
|
||||
ReturnValue_t result;
|
||||
if (databuffer != NULL) {
|
||||
result = sendReadCommand(cookie, datalen);
|
||||
} else {
|
||||
result = sendWriteCommand(cookie, data, datalen);
|
||||
}
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
time = hw_timer_get_us();
|
||||
while (time - hw_timer_get_us() < timeout_us) {
|
||||
result = getReply(cookie, databuffer, len);
|
||||
if (!((result == REPLY_NOT_YET_SENT) || (result == REPLY_NO_REPLY))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (result == REPLY_NOT_YET_SENT) {
|
||||
return result;
|
||||
}
|
||||
return REPLY_TIMEOUT;
|
||||
}
|
||||
|
||||
//SHOULDDO find a better way to inject the Extended address
|
||||
#include <config/hardware/IoBoardAddresses.h>
|
||||
ReturnValue_t RmapSPWChannel::open(Cookie **cookie, uint32_t address,
|
||||
uint32_t maxReplyLen) {
|
||||
*cookie = new RMAPCookie(address, IoBoardExtendedAddresses::DEVICE_BUFFER,
|
||||
this, 0, maxReplyLen);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::reOpen(Cookie* cookie, uint32_t address,
|
||||
uint32_t maxReplyLen) {
|
||||
ReturnValue_t result = isActive();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
RMAPCookie *rCookie = dynamic_cast<RMAPCookie *>(cookie);
|
||||
if (rCookie == NULL) {
|
||||
return INVALID_COOKIE_TYPE;
|
||||
}
|
||||
rCookie->setAddress(address);
|
||||
rCookie->setChannel(this);
|
||||
rCookie->setCommandMask(0);
|
||||
rCookie->setExtendedAddress(IoBoardExtendedAddresses::DEVICE_BUFFER);
|
||||
rCookie->setMaxReplyLen(maxReplyLen);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void RmapSPWChannel::close(Cookie* cookie) {
|
||||
delete cookie;
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::sendMessage(Cookie* cookie, uint8_t* data,
|
||||
uint32_t len) {
|
||||
return sendWriteCommand((RMAPCookie *) cookie, data, len);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::getSendSuccess(Cookie* cookie) {
|
||||
return getWriteReply((RMAPCookie *) cookie);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::requestReceiveMessage(Cookie* cookie) {
|
||||
return sendReadCommand((RMAPCookie *) cookie,
|
||||
((RMAPCookie *) cookie)->getMaxReplyLen());
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::readReceivedMessage(Cookie* cookie,
|
||||
uint8_t** buffer, uint32_t* size) {
|
||||
return getReadReply((RMAPCookie *) cookie, buffer, size);
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::setAddress(Cookie* cookie, uint32_t address) {
|
||||
((RMAPCookie *) cookie)->setAddress(address);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t RmapSPWChannel::getAddress(Cookie* cookie) {
|
||||
return ((RMAPCookie *) cookie)->getAddress();
|
||||
}
|
||||
|
||||
ReturnValue_t RmapSPWChannel::setParameter(Cookie* cookie, uint32_t parameter) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint32_t RmapSPWChannel::getParameter(Cookie* cookie) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RmapSPWChannel::reportFailures(uint16_t failureEntry,
|
||||
uint8_t descriptorNr) {
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_CRC)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_INVALID_DATA_CRC, descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_DST_ADDR)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_INVALID_TARGET_LOGICAL_ADDRESS,
|
||||
descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_EEP)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_EEP, descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_INSTR)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR,
|
||||
REPLY_COMMAND_NOT_IMPLEMENTED_OR_NOT_AUTHORISED, descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_INSTR_TYPE)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_RESERVED, descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_LEN)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_TOO_MUCH_DATA, descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_LEN_MISSMATCH)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_INVALID_DATA, descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_PROTO)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_GENERAL_ERROR_CODE,
|
||||
descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_SRC_ADDR)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_GENERAL_ERROR_CODE,
|
||||
descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_TRUNC)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_TRANSMISSION_ERROR,
|
||||
descriptorNr);
|
||||
}
|
||||
if (failureEntry & (1 << RMAP_RX_FAIL_WRONG_REPLY)) {
|
||||
triggerEvent(RMAP_PROTOCOL_ERROR, REPLY_INVALID_KEY, descriptorNr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RmapSPWChannel::reportSpwstr(uint32_t spwstr) {
|
||||
if (spwstr & (1 << SPW_SPWSTR_CE)) {
|
||||
triggerEvent(SPW_ERROR, SPW_CREDIT);
|
||||
}
|
||||
if (spwstr & (1 << SPW_SPWSTR_ER)) {
|
||||
triggerEvent(SPW_ERROR, SPW_ESCAPE);
|
||||
}
|
||||
if (spwstr & (1 << SPW_SPWSTR_DE)) {
|
||||
triggerEvent(SPW_ERROR, SPW_DISCONNECT);
|
||||
}
|
||||
if (spwstr & (1 << SPW_SPWSTR_PE)) {
|
||||
triggerEvent(SPW_ERROR, SPW_PARITY);
|
||||
}
|
||||
if (spwstr & (1 << SPW_SPWSTR_WE)) {
|
||||
triggerEvent(SPW_ERROR, SPW_WRITE_SYNC);
|
||||
}
|
||||
if (spwstr & (1 << SPW_SPWSTR_IA)) {
|
||||
triggerEvent(SPW_ERROR, SPW_INVALID_ADDRESS);
|
||||
}
|
||||
if (spwstr & (1 << SPW_SPWSTR_EE)) {
|
||||
triggerEvent(SPW_ERROR, SPW_EARLY_EOP);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RmapSPWChannel::null_crc = 0;
|
||||
|
||||
int8_t RmapSPWChannel::getCurrentPortNr() {
|
||||
uint8_t i;
|
||||
int8_t oldport = -1;
|
||||
for (i = 0; i < SPW_devices.len; ++i) {
|
||||
if (SPW_devices.devices[i] == this->port) {
|
||||
oldport = i;
|
||||
}
|
||||
}
|
||||
return oldport;
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
#ifndef RMAPCHANNEL_H_
|
||||
#define RMAPCHANNEL_H_
|
||||
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/rmap/RMAPChannelIF.h>
|
||||
extern "C" {
|
||||
#include <bsp_flp/spw/spw.h>
|
||||
}
|
||||
#include <config/datapool/dataPoolInit.h>
|
||||
#include <framework/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <framework/events/Event.h>
|
||||
#include <framework/tasks/PeriodicTaskIF.h>
|
||||
|
||||
class RmapSPWChannel: public SystemObject,
|
||||
public RMAPChannelIF,
|
||||
public DeviceCommunicationIF {
|
||||
public:
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH_1;
|
||||
static const Event SPW_ERROR = MAKE_EVENT(0, SEVERITY::LOW);
|
||||
static const Event SPW_LINK_DOWN = MAKE_EVENT(1, SEVERITY::LOW);
|
||||
// static const Event SPW_CREDIT = MAKE_EVENT(1, SEVERITY::LOW);
|
||||
// static const Event SPW_ESCAPE = MAKE_EVENT(2, SEVERITY::LOW);
|
||||
// static const Event SPW_DISCONNECT = MAKE_EVENT(3, SEVERITY::LOW);
|
||||
// static const Event SPW_PARITY = MAKE_EVENT(4, SEVERITY::LOW);
|
||||
// static const Event SPW_WRITE_SYNC = MAKE_EVENT(5, SEVERITY::LOW);
|
||||
// static const Event SPW_INVALID_ADDRESS = MAKE_EVENT(6, SEVERITY::LOW);
|
||||
// static const Event SPW_EARLY_EOP = MAKE_EVENT(7, SEVERITY::LOW);
|
||||
// static const Event SPW_DMA = MAKE_EVENT(8, SEVERITY::LOW);
|
||||
// static const Event SPW_LINK_ERROR = MAKE_EVENT(9, SEVERITY::LOW);
|
||||
static const Event RMAP_PROTOCOL_ERROR = MAKE_EVENT(10, SEVERITY::LOW);
|
||||
// static const Event RMAP_CRC = MAKE_EVENT(10, SEVERITY::LOW);
|
||||
// static const Event RMAP_DST_ADDR = MAKE_EVENT(11, SEVERITY::LOW);
|
||||
// static const Event RMAP_EEP = MAKE_EVENT(12, SEVERITY::LOW);
|
||||
// static const Event RMAP_INSTR = MAKE_EVENT(13, SEVERITY::LOW);
|
||||
// static const Event RMAP_INSTR_TYPE = MAKE_EVENT(14, SEVERITY::LOW);
|
||||
// static const Event RMAP_LEN = MAKE_EVENT(15, SEVERITY::LOW);
|
||||
// static const Event RMAP_LEN_MISSMATCH = MAKE_EVENT(16, SEVERITY::LOW);
|
||||
// static const Event RMAP_PROTO = MAKE_EVENT(17, SEVERITY::LOW);
|
||||
// static const Event RMAP_SRC_ADDR = MAKE_EVENT(18, SEVERITY::LOW);
|
||||
// static const Event RMAP_TRUNC = MAKE_EVENT(19, SEVERITY::LOW);
|
||||
// static const Event RMAP_WRONG_REPLY = MAKE_EVENT(20, SEVERITY::LOW);
|
||||
static const Event RMAP_MISSED_REPLIES = MAKE_EVENT(21, SEVERITY::LOW);
|
||||
static const Event RMAP_NO_RX_DESCRIPTORS = MAKE_EVENT(22, SEVERITY::LOW);
|
||||
static const Event RMAP_NO_TX_DESCRIPTORS = MAKE_EVENT(23, SEVERITY::LOW);
|
||||
static const Event RMAP_SWITCHED_PORT = MAKE_EVENT(24, SEVERITY::INFO);
|
||||
|
||||
RmapSPWChannel(object_id_t setObjectId, uint16_t buffersize_words,
|
||||
uint32_t maxPacketSize, int8_t portNr, uint8_t dest_addr,
|
||||
uint8_t src_addr, PeriodicTaskIF* currentTask, datapool::opus_variable_id portVariable =
|
||||
datapool::NO_PARAMETER);
|
||||
|
||||
virtual ~RmapSPWChannel();
|
||||
|
||||
virtual ReturnValue_t reset();
|
||||
|
||||
virtual ReturnValue_t isActive();
|
||||
|
||||
virtual ReturnValue_t setPort(int8_t port, uint8_t dest_addr,
|
||||
uint8_t src_addr, PeriodicTaskIF* currentTask);
|
||||
|
||||
virtual ReturnValue_t setPort(int8_t port, PeriodicTaskIF* currentTask);
|
||||
|
||||
virtual ReturnValue_t sendCommand(RMAPCookie *cookie, uint8_t instruction,
|
||||
uint8_t *data, uint32_t datalen);
|
||||
virtual ReturnValue_t getReply(RMAPCookie *cookie, uint8_t **databuffer,
|
||||
uint32_t *len);
|
||||
virtual ReturnValue_t sendCommandBlocking(RMAPCookie *cookie, uint8_t *data,
|
||||
uint32_t datalen, uint8_t **databuffer, uint32_t *len,
|
||||
uint32_t timeout_us);
|
||||
|
||||
virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
|
||||
uint32_t maxReplyLen);
|
||||
|
||||
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
|
||||
uint32_t maxReplyLen);
|
||||
|
||||
virtual void close(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
virtual ReturnValue_t getSendSuccess(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
|
||||
uint32_t *size);
|
||||
|
||||
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address);
|
||||
|
||||
virtual uint32_t getAddress(Cookie *cookie);
|
||||
|
||||
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter);
|
||||
|
||||
virtual uint32_t getParameter(Cookie *cookie);
|
||||
|
||||
private:
|
||||
|
||||
SPW_dev *port;
|
||||
uint32_t *buffer;
|
||||
uint32_t *buffer_pointer; //points to the next free space in the buffer
|
||||
uint32_t *end_of_buffer; //points to the word AFTER the buffer
|
||||
spw_tx_desc *tx_descriptor_table;
|
||||
spw_rx_desc *rx_descriptor_table;
|
||||
uint16_t *failure_table;
|
||||
uint32_t max_packet_len;
|
||||
uint16_t tid;
|
||||
// uint8_t port_has_crc;
|
||||
uint8_t rx_index; //index of the next unused rx descriptor
|
||||
uint8_t max_rx;
|
||||
uint8_t tx_index; //index of the next unused tx descriptor
|
||||
uint8_t max_tx;
|
||||
uint8_t src_addr;
|
||||
uint8_t dest_addr;
|
||||
|
||||
datapool::opus_variable_id portPoolId;
|
||||
|
||||
static uint8_t null_crc;
|
||||
|
||||
spw_rx_desc *findReply(RMAPCookie *cookie);
|
||||
ReturnValue_t checkTxDesc(RMAPCookie *cookie);
|
||||
spw_rx_desc *checkRxDesc(RMAPCookie *cookie, uint8_t rxdesc_index);
|
||||
void checkRxDescPacket(spw_rx_desc *rxdesc, uint16_t *failureEntry);
|
||||
|
||||
ReturnValue_t checkCrc(uint8_t *packet, uint32_t len);
|
||||
|
||||
void checkRmapHeader(void *_header, uint32_t len, uint16_t *failureEntry);
|
||||
|
||||
void reportFailures(uint16_t failureEntry, uint8_t descriptorNr);
|
||||
void reportSpwstr(uint32_t spwstr);
|
||||
int8_t getCurrentPortNr();
|
||||
|
||||
};
|
||||
|
||||
#endif /* RMAPCHANNEL_H_ */
|
@ -7,28 +7,45 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
//#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
|
||||
|
||||
#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||
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_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 ((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))
|
||||
//#define RMAP_REPLY_READ ((1<<RMAP_COMMAND_BIT_REPLY))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// useful info
|
||||
#define RMAP_COMMAND_HEADER_LEN 16
|
||||
#define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||
#define RMAP_READ_REPLY_HEADER_LEN 12
|
||||
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 {
|
||||
|
Reference in New Issue
Block a user