OpenCores
URL https://opencores.org/ocsvn/rio/rio/trunk

Subversion Repositories rio

[/] [rio/] [trunk/] [sw/] [stack/] [riostack.c] - Diff between revs 20 and 49

Show entire file | Details | Blame | View Log

Rev 20 Rev 49
Line 13... Line 13...
 * Symbols are in four flavors, idle, control, data and error. They are abstract
 * Symbols are in four flavors, idle, control, data and error. They are abstract
 * and should be serialized by any implementation to be sent on a transmission
 * and should be serialized by any implementation to be sent on a transmission
 * channel. Error symbols are never generated by the stack and are used if the
 * channel. Error symbols are never generated by the stack and are used if the
 * symbol decoder encounters an error that the stack should be notified of.
 * symbol decoder encounters an error that the stack should be notified of.
 *
 *
 * Symbols are inserted into the stack by calling RIO_portAddSymbol() and symbols to
 * Symbols are inserted into the stack from the lower-half by calling
 * transmit are fetched from the stack using RIO_portGetSymbol(). These two
 * RIOSTACK_portAddSymbol() and symbols to transmit are fetched from the stack
 * functions are the low-level interface towards a physical transmission channel.
 * using RIOSTACK_portGetSymbol(). These two functions are the low-level interface
 * The function RIO_portSetStatus() is used to indicate to the stack that initial
 * towards a physical transmission channel.
 
 * The function RIOSTACK_portSetStatus() is used to indicate to the stack that initial
 * training of the symbol codec has been completed and that the transmission port
 * training of the symbol codec has been completed and that the transmission port
 * is ready to accept other symbols than idle. The procedure is to set the port
 * is ready to accept other symbols than idle. The procedure is to set the port
 * status to initialized once idle symbols are successfully received.
 * status to initialized once idle symbols are successfully received.
 *
 *
 * On the high-level interface are rio_sendXXX() functions used to create and
 * On the upper-half interface are the RIOSTACK_setOutboundPacket() function used to
 * insert packets into the outbound transmission queue. The RIO_eventPoll()
 * insert packets into the outbound transmission queue and RIOSTACK_getInboundPacket()
 * function is used to check if any packet is available for reading in the
 * is used to get packet from the inbound reception queue. The
 * inbound reception queue. These packets are then accessed using
 * RIOSTACK_getInboundQueueLength() function is used to check if any packet is available
 * rio_receiveXXX() functions.
 * for reading in the inbound reception queue.
 *
 *
 * -----------------
 * -----------------
 * |  OS dependent |
 * |  OS dependent |
 * |  (your code)  |
 * |  (your code)  |
 * -----------------
 * -----------------
Line 53... Line 54...
 *
 *
 * The symbol codec maps a RapidIO symbol to the physical transmission media.
 * The symbol codec maps a RapidIO symbol to the physical transmission media.
 *
 *
 * Some typical patterns to handle this stack are:
 * Some typical patterns to handle this stack are:
 * Initialization:
 * Initialization:
 *   RIO_open(...);
 *   RIOSTACK_open(...);
 *   RIO_portSetTimeout(...);
 *   RIOSTACK_portSetTimeout(...);
 *   ...
 *   ...
 *   <Symbol transcoder is successfully decoding symbols from the link>
 *   <Symbol transcoder is successfully decoding symbols from the link>
 *   RIO_portSetStatus(1);
 *   RIOSTACK_portSetStatus(1);
 *
 *
 * Bottom-half traffic handling:
 * Bottom-half traffic handling:
 *   RIO_portSetTime(...);
 *   RIOSTACK_portSetTime(...);
 *   <get symbol from decoder>
 *   <get symbol from decoder>
 *   RIO_portAddSymbol(...);
 *   RIOSTACK_portAddSymbol(...);
 *   s = RIO_portGetSymbol(...);
 *   s = RIOSTACK_portGetSymbol(...);
 *   <send symbol to encoder>
 *   <send symbol to encoder>
 *
 *
 * Receiving packets:
 * Receiving packets:
 *   switch(RIO_eventPoll(...))
 *   if(RIOSTACK_getInboundQueueLength(...) > 0)
 *   {
 *   {
 *     case RIO_EVENT_DOORBELL:
 *     RIOSTACK_getInboundPacket(...);
 *       RIO_receiveDoorbell(...);
 *     <process the new packet>
 *       ...
 
 *   }
 *   }
 *   RIO_packetRemove();
 
 *
 *
 * Transmitting packets:
 * Transmitting packets:
 *   if(RIO_sendAvailable(...))
 *   <create a new packet>
 
 *   if(RIOSTACK_getOutboundQueueAvailable(...) > 0)
 *   {
 *   {
 *     RIO_sendDoorbell(...);
 *     RIOSTACK_setOutboundPacket(...);
 *   }
 *   }
 *   ...
 
 *
 *
 * More details about the usage can be found in the module tests in the end of
 * More details about the usage can be found in the module tests in test_riostack.c.
 * this file.
 
 *
 *
 * To Do:
 * To Do:
 * -
 * - Optimize the packing of stype0 and stype1 into control symbols.
 *
 *
 * Author(s):
 * Author(s):
 * - Magnus Rosenius, magro732@opencores.org
 * - Magnus Rosenius, magro732@opencores.org
 *
 *
 *******************************************************************************
 *******************************************************************************
 *
 *
 * Copyright (C) 2013 Authors and OPENCORES.ORG
 * Copyright (C) 2015 Authors and OPENCORES.ORG
 *
 *
 * This source file may be used and distributed without
 * This source file may be used and distributed without
 * restriction provided that this copyright statement is not
 * restriction provided that this copyright statement is not
 * removed from the file and that any derivative work contains
 * removed from the file and that any derivative work contains
 * the original copyright notice and the associated disclaimer.
 * the original copyright notice and the associated disclaimer.
Line 118... Line 116...
 * Public License along with this source; if not, download it
 * Public License along with this source; if not, download it
 * from http://www.opencores.org/lgpl.shtml
 * from http://www.opencores.org/lgpl.shtml
 *
 *
 *******************************************************************************/
 *******************************************************************************/
 
 
 
 
/**
/**
 * \file riostack.c
 * \file riostack.c
 */
 */
 
 
/*******************************************************************************
/*******************************************************************************
Line 137... Line 136...
 
 
 
 
/* lint --estring(960,17.4) It is not possible to implement a rio stack without some
/* lint --estring(960,17.4) It is not possible to implement a rio stack without some
 * pointer arithmetic */
 * pointer arithmetic */
 
 
 
 
/*******************************************************************************
/*******************************************************************************
 * Local macro definitions
 * Local macro definitions
 *******************************************************************************/
 *******************************************************************************/
 
 
/* Macro to update 5-bit ackId counters. */
/* Macro to update 5-bit ackId counters. */
Line 244... Line 244...
#define LINK_RESPONSE_PORT_STATUS_ERROR 2u
#define LINK_RESPONSE_PORT_STATUS_ERROR 2u
#define LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED 4u
#define LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED 4u
#define LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED 5u
#define LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED 5u
#define LINK_RESPONSE_PORT_STATUS_OK 16u
#define LINK_RESPONSE_PORT_STATUS_OK 16u
 
 
 
 
 
 
/*******************************************************************************
/*******************************************************************************
 * Local typedefs
 * Local typedefs
 *******************************************************************************/
 *******************************************************************************/
 
 
 
 
 
 
/*******************************************************************************
/*******************************************************************************
 * Global declarations
 * Global declarations
 *******************************************************************************/
 *******************************************************************************/
 
 
 
 
 
 
/*******************************************************************************
/*******************************************************************************
 * Local declarations
 * Local declarations
 *******************************************************************************/
 *******************************************************************************/
 
 
 
 
 
 
/*******************************************************************************
/*******************************************************************************
 * Local function prototypes
 * Local function prototypes
 *******************************************************************************/
 *******************************************************************************/
 
 
/* Helper functions for protocol events. */
/* Helper functions for protocol events. */
Line 272... Line 280...
static void handleEndOfPacket(RioStack_t *stack);
static void handleEndOfPacket(RioStack_t *stack);
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd);
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd);
static void handleNewPacketStart(RioStack_t *stack);
static void handleNewPacketStart(RioStack_t *stack);
static void handleNewPacketEnd(RioStack_t *stack);
static void handleNewPacketEnd(RioStack_t *stack);
 
 
/* I/O logical layer maintenance packet functions. */
 
static void sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                        const uint8_t hopCount, const uint32_t offset);
 
static void receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                           uint8_t *hopCount, uint32_t *offset);
 
static void sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                         const uint8_t hopCount, const uint32_t data);
 
static void receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                            uint8_t *hopCount, uint32_t *data);
 
static void sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                         const uint8_t hopCount, const uint32_t offset, const uint32_t data );
 
static void receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                            uint8_t *hopCount, uint32_t *offset, uint32_t *data );
 
static void sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                          const uint8_t hopCount);
 
static void receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                             uint8_t *hopCount);
 
 
 
/* I/O logical layer packet functions. */
 
static void sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                        const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer,
 
                        const uint8_t ack);
 
static uint16_t receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                               uint32_t *address, const uint16_t dataLength, uint8_t *data );
 
static void sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                       const uint32_t address, const uint16_t dataLength);
 
static void receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                          uint32_t *address, uint16_t *dataLength);
 
static void sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                     const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer);
 
static uint16_t receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                            const uint32_t address, const uint16_t dataLength, uint8_t *data );
 
static void sendResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                          const uint8_t status);
 
static void receiveResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid);
 
 
 
/* Message passing logical layer packet functions. */
 
static void sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                          const uint16_t info );
 
static void receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                             uint16_t *info);
 
static void sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
 
                         const uint16_t bufferSize, const uint8_t* bufferData);
 
static uint16_t receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
 
                                const uint16_t dataLength, uint8_t *data );
 
static void sendMessageResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
 
                                 const uint8_t status);
 
static void receiveMessageResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox);
 
 
 
/* Functions to help transfer data bytes to and from a packet payload. */
 
static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
 
                                 const uint16_t dataSize, uint8_t *data);
 
static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
 
                                 const uint16_t dataSize, const uint8_t *data);
 
 
 
/* Functions to help in conversions between rdsize/wrsize and size/offset. */
 
static uint16_t rdsizeGet(const uint32_t address, const uint16_t size);
 
static uint16_t wrsizeGet(const uint32_t address, const uint16_t size);
 
static void rdsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size);
 
static void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size);
 
 
 
/**
/**
 * \brief Create a control symbol.
 * \brief Create a control symbol.
 *
 *
 * \param[in] stype0 The stype0 value.
 * \param[in] stype0 The stype0 value.
 * \param[in] parameter0 The parameter0 value.
 * \param[in] parameter0 The parameter0 value.
 * \param[in] parameter1 The parameter1 value.
 * \param[in] parameter1 The parameter1 value.
 * \param[in] stype1 The stype1 value.
 * \param[in] stype1 The stype1 value.
 * \param[in] cmd The cmd value.
 * \param[in] cmd The cmd value.
 * \param[out] None
 
 * \return The control symbol that were created from the input parameters.
 * \return The control symbol that were created from the input parameters.
 *
 *
 * This function creates a control symbol with the specified arguments and
 * This function creates a control symbol with the specified arguments and
 * calculates a CRC-5 checksum according to the standard specification.
 * calculates a CRC-5 checksum according to the standard specification.
 */
 */
static RioSymbol CreateControlSymbol( const uint8_t stype0,
static RioSymbol_t CreateControlSymbol(const uint8_t stype0,
                                      const uint8_t parameter0, const uint8_t parameter1,
                                      const uint8_t parameter0, const uint8_t parameter1,
                                      const uint8_t stype1, const uint8_t cmd);
                                      const uint8_t stype1, const uint8_t cmd);
 
 
/**
/**
 * \brief Function to calculate ITU-CRC5, polynom=0x15.
 * \brief Function to calculate ITU-CRC5, polynom=0x15.
Line 361... Line 307...
 * \return A new CRC-5 value.
 * \return A new CRC-5 value.
 */
 */
static uint8_t Crc5( const uint32_t data, const uint8_t crc);
static uint8_t Crc5( const uint32_t data, const uint8_t crc);
 
 
/**
/**
 * \brief Function to calculate CITT-CRC16, polynom=0x1021.
 
 *
 
 * \param[in] data The data to calculate CRC-16 on.
 
 * \param[in] crc The crc to initiate the result with.
 
 * \param[out] None
 
 * \return A new CRC-16 value.
 
 *
 
 * This function calculates and returns a new CRC-16 value based on
 
 * new data and a previous CRC-16 value.
 
 */
 
static uint16_t Crc16( const uint16_t data, const uint16_t crc);
 
 
 
/**
 
 * \brief Function to calculate CITT-CRC16, polynom=0x1021.
 
 *
 
 * \param[in] data The data to calculate CRC-16 on.
 
 * \param[in] crc The crc to initiate the result with.
 
 * \param[out] None
 
 * \return A new CRC-16 value.
 
 *
 
 * This function calculates and returns a new CRC-16 value based on
 
 * new data and a previous CRC-16 value.
 
 */
 
static uint16_t Crc32( const uint32_t data, uint16_t crc);
 
 
 
/**
 
 * \brief Create a queue with a specified size and a buffer attached to it.
 * \brief Create a queue with a specified size and a buffer attached to it.
 *
 *
 * \param[in] The number of entries in the queue.
 * \param[in] size The number of entries in the queue.
 * \param[in] A pointer to the buffer to store the content in.
 * \param[in] buffer A pointer to the buffer to store the content in.
 * \return A queue with the specified size and where new data will be stored
 * \return A queue with the specified size and where new data will be stored
 * to the specified buffer.
 * to the specified buffer.
 */
 */
static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer);
static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer);
 
 
Line 410... Line 330...
 * \brief Get if the queue is empty or not.
 * \brief Get if the queue is empty or not.
 *
 *
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
 * \return Non-zero if the queue is empty.
 * \return Non-zero if the queue is empty.
 */
 */
static bool_t QueueEmpty( const Queue_t q);
static int QueueEmpty(const Queue_t q);
 
 
/**
/**
 * \brief Get the length of a queue.
 * \brief Get the length of a queue.
 *
 *
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
Line 442... Line 362...
 * \brief Check if the readout window is empty.
 * \brief Check if the readout window is empty.
 *
 *
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
 * \return If the readout window is empty.
 * \return If the readout window is empty.
 */
 */
static bool_t QueueWindowEmpty( const Queue_t q);
static int QueueWindowEmpty(const Queue_t q);
 
 
/**
/**
 * \brief Reset the window to none.
 * \brief Reset the window to none.
 *
 *
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
Line 478... Line 398...
 * \param[in] content The content to set at the specified index in the newest queue element.
 * \param[in] content The content to set at the specified index in the newest queue element.
 */
 */
static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content);
static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content);
 
 
/**
/**
 * \brief Get the size of the newest element.
 
 *
 
 * \param[in] q The queue to operate on.
 
 * \return The size of the currently pending element.
 
 */
 
static uint32_t QueueGetBackSize( Queue_t q);
 
 
 
/**
 
 * \brief Get a pointer to the buffer of the newest element.
 * \brief Get a pointer to the buffer of the newest element.
 *
 *
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
 * \return A pointer to the content.
 * \return A pointer to the content.
 */
 */
Line 498... Line 410...
/**
/**
 * \brief Get the size of the oldest element.
 * \brief Get the size of the oldest element.
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
 * \return The size of the element.
 * \return The size of the element.
 */
 */
static uint32_t QueueGetFrontSize( Queue_t q );
static uint32_t QueueGetSize(Queue_t q );
 
 
/**
/**
 * \brief Get the content of the oldest element at specified index.
 * \brief Get the content of the oldest element at specified index.
 * \param[in] q The queue to operate on.
 * \param[in] q The queue to operate on.
 * \param[in] index The index into the element to get the content from.
 * \param[in] index The index into the element to get the content from.
Line 522... Line 434...
 
 
/*******************************************************************************
/*******************************************************************************
 * Global functions
 * Global functions
 *******************************************************************************/
 *******************************************************************************/
 
 
 
void RIOSTACK_open(RioStack_t *stack, void *private,
void RIO_open( RioStack_t *stack, const RioStackObserver_t *observer, const void *private,
 
               const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer,
               const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer,
               const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer,
                   const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer)
               const uint16_t configDeviceVendorId, const uint16_t configDeviceId, const uint32_t configDeviceRevisionId,
 
               const uint16_t configAssyVendorId, const uint16_t configAssyId, const uint16_t configAssyRevisionId,
 
               const uint16_t configBaseDeviceId )
 
{
{
  /* Port time and timeout limit. */
  /* Port time and timeout limit. */
  stack->portTime = 0u;
  stack->portTime = 0u;
  stack->portTimeout = 1000u;
  stack->portTimeout = 1000u;
 
 
Line 542... Line 450...
  stack->rxCrc = 0xffffu;
  stack->rxCrc = 0xffffu;
  stack->rxStatusReceived = 0u;
  stack->rxStatusReceived = 0u;
  stack->rxAckId = 0u;
  stack->rxAckId = 0u;
  stack->rxAckIdAcked = 0u;
  stack->rxAckIdAcked = 0u;
  stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
  stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
  stack->rxQueue = QueueCreate((uint8_t) (rxPacketBufferSize/RIO_BUFFER_SIZE), rxPacketBuffer);
  stack->rxQueue = QueueCreate((uint8_t) (rxPacketBufferSize/RIOSTACK_BUFFER_SIZE), rxPacketBuffer);
 
 
  /* Setup the transmitter. */
  /* Setup the transmitter. */
  stack->txState = TX_STATE_UNINITIALIZED;
  stack->txState = TX_STATE_UNINITIALIZED;
  stack->txCounter = 0u;
  stack->txCounter = 0u;
  stack->txStatusCounter = 0u;
  stack->txStatusCounter = 0u;
  stack->txFrameState = TX_FRAME_START;
  stack->txFrameState = TX_FRAME_START;
  stack->txAckId = 0u;
  stack->txAckId = 0u;
  stack->txAckIdWindow = 0u;
  stack->txAckIdWindow = 0u;
  stack->txQueue = QueueCreate((uint8_t) (txPacketBufferSize/RIO_BUFFER_SIZE), txPacketBuffer);
  stack->txQueue = QueueCreate((uint8_t) (txPacketBufferSize/RIOSTACK_BUFFER_SIZE), txPacketBuffer);
 
 
  /* Set our own device address to use in the packets. */
 
  stack->deviceIdentity = configDeviceId;
 
  stack->deviceVendorIdentity = configDeviceVendorId;
 
  stack->deviceRev = configDeviceRevisionId;
 
  stack->assyIdentity = configAssyId;
 
  stack->assyVendorIdentity = configAssyVendorId;
 
  stack->assyRev = configAssyRevisionId;
 
  stack->baseDeviceId = configBaseDeviceId;
 
 
 
  /* Initialize the host base lock CSR. */
 
  stack->hostBaseDeviceIdLock = 0xfffffffful;
 
  stack->componentTag = 0ul;
 
 
 
  /* Bits that are updated by the configuration procedure. */
 
  stack->host = 0u;
 
  stack->masterEnable = 0u;
 
  stack->discovered = 0u;
 
 
 
  /* Setup status counters for inbound direction. */
  /* Setup status counters for inbound direction. */
  stack->statusInboundPacketComplete = 0ul;
  stack->statusInboundPacketComplete = 0ul;
  stack->statusInboundPacketRetry = 0ul;
  stack->statusInboundPacketRetry = 0ul;
  stack->statusInboundErrorControlCrc = 0ul;
  stack->statusInboundErrorControlCrc = 0ul;
Line 583... Line 473...
  stack->statusInboundErrorGeneral = 0ul;
  stack->statusInboundErrorGeneral = 0ul;
  stack->statusInboundErrorPacketUnsupported = 0ul;
  stack->statusInboundErrorPacketUnsupported = 0ul;
 
 
  /* Setup status counters for outbound direction. */
  /* Setup status counters for outbound direction. */
  stack->statusOutboundPacketComplete = 0ul;
  stack->statusOutboundPacketComplete = 0ul;
 
  stack->statusOutboundLinkLatencyMax = 0ul;
  stack->statusOutboundPacketRetry = 0ul;
  stack->statusOutboundPacketRetry = 0ul;
  stack->statusOutboundErrorTimeout = 0ul;
  stack->statusOutboundErrorTimeout = 0ul;
  stack->statusOutboundErrorPacketAccepted = 0ul;
  stack->statusOutboundErrorPacketAccepted = 0ul;
  stack->statusOutboundErrorPacketRetry = 0ul;
  stack->statusOutboundErrorPacketRetry = 0ul;
 
 
Line 596... Line 487...
  stack->statusPartnerErrorPacketAckId = 0ul;
  stack->statusPartnerErrorPacketAckId = 0ul;
  stack->statusPartnerErrorPacketCrc = 0ul;
  stack->statusPartnerErrorPacketCrc = 0ul;
  stack->statusPartnerErrorIllegalCharacter = 0ul;
  stack->statusPartnerErrorIllegalCharacter = 0ul;
  stack->statusPartnerErrorGeneral = 0ul;
  stack->statusPartnerErrorGeneral = 0ul;
 
 
  /* Set callback structure. */
 
  stack->observer = observer;
 
 
 
  /* Set pointer to user private data. */
  /* Set pointer to user private data. */
  stack->private = private;
  stack->private = private;
}
}
 
 
 
 
 
 
/*******************************************************************************************
/*******************************************************************************************
 * Stack status functions.
 * Stack status and queue access functions.
 * Note that status counters are access directly in the stack-structure.
 * Note that status counters are accessed directly in the stack-structure.
 *******************************************************************************************/
 *******************************************************************************************/
 
 
RioStatusType RIO_getStatus( RioStack_t *stack )
int RIOSTACK_getStatus(RioStack_t *stack)
{
{
  RioStatusType status;
  return !(((stack->rxState == RX_STATE_UNINITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED)) &&
 
           ((stack->txState == TX_STATE_UNINITIALIZED) || (stack->txState == TX_STATE_PORT_INITIALIZED)));
 
}
 
 
 
 
  /* Check if both receiver and transmitter is up and running. */
 
  if((stack->rxState == RX_STATE_LINK_INITIALIZED) &&
 
     (stack->txState == TX_STATE_LINK_INITIALIZED))
 
  {
 
    /* Both receiver and transmitter is up. */
 
 
 
    /* Check if it is allowed to act as a master on the bus. */
void RIOSTACK_clearOutboundQueue(RioStack_t *stack)
    if(stack->masterEnable)
 
    {
    {
      /* Allowed to act as master. */
  while(!QueueEmpty(stack->txQueue))
      status = RIO_STATUS_OPERATIONAL;
 
    }
 
    else
 
    {
    {
      /* Not allowed to act as master. */
    stack->txQueue = QueueDequeue(stack->txQueue);
      /* The enumeration process has not been completed yet. */
 
      status = RIO_STATUS_ENUMERATION;
 
    }
 
  }
  }
  else
 
  {
 
    /* The link is not up yet. */
 
    status = RIO_STATUS_UNINITIALIZED;
 
  }
  }
 
 
  return status;
 
}
 
 
 
 
 
uint8_t RIO_outboundQueueLength( RioStack_t *stack )
uint8_t RIOSTACK_getOutboundQueueLength(RioStack_t *stack)
{
{
  return QueueLength(stack->txQueue);
  return QueueLength(stack->txQueue);
}
}
 
 
 
 
uint8_t RIO_inboundQueueLength( RioStack_t *stack )
 
 
uint8_t RIOSTACK_getOutboundQueueAvailable(RioStack_t *stack)
{
{
  return QueueLength(stack->rxQueue);
  return QueueAvailable(stack->txQueue);
}
}
 
 
 
 
/*******************************************************************************************
 
 * Packet reception functions.
 
 *******************************************************************************************/
 
 
 
RioEventType RIO_eventPoll( RioStack_t *stack )
 
{
 
  RioEventType event;
 
  uint32_t *packet;
 
  uint32_t ftype;
 
  uint32_t transaction;
 
 
 
 
 
  /* Check if there are any new packets in the inbound queue. */
void RIOSTACK_setOutboundPacket(RioStack_t *stack, RioPacket_t *packet)
  if(!QueueEmpty(stack->rxQueue))
 
  {
  {
    /* There are new pending packets. */
  uint32_t *src, *dst;
 
  uint32_t size;
 
  uint32_t i;
 
 
    /* Get the packet and its ftype. */
 
    packet = QueueGetFrontBuffer(stack->rxQueue);
 
    ftype = FTYPE_GET(packet);
 
    transaction = TRANSACTION_GET(packet);
 
 
 
    /* Check the type of packets, i.e. read the ftype. */
  ASSERT((QueueAvailable(stack->txQueue) > 0u),
    switch(ftype)
         "Transmission queue packet overflow.");
    {
 
      case FTYPE_REQUEST:
 
        /* Request class. */
 
 
 
        /* Check transaction type. */
  src = &packet->payload[0];
        switch(transaction)
  dst = QueueGetBackBuffer(stack->txQueue);
 
  size = packet->size;
 
  for(i = 0; i < size; i++)
        {
        {
          case TRANSACTION_REQUEST_NREAD:
    dst[i] = src[i];
            /* Supported NREAD request. */
  }
            event = RIO_EVENT_NREAD;
 
            break;
 
 
 
          default:
  QueueSetSize(stack->txQueue, size);
            /* Unsupported request transaction. */
  stack->txQueue = QueueEnqueue(stack->txQueue);
            /* REMARK: Throw these away for now. */
 
            stack->statusInboundErrorPacketUnsupported++;
 
            stack->rxQueue = QueueDequeue(stack->rxQueue);
 
            event = RIO_EVENT_NONE;
 
            break;
 
        }
        }
        break;
 
 
 
      case FTYPE_WRITE:
 
        /* Write class. */
 
 
 
        /* Check transaction type. */
 
        switch(transaction)
 
        {
 
          case TRANSACTION_WRITE_NWRITE:
 
            /* NWRITE transaction. */
 
            if(QueueGetFrontSize(stack->rxQueue) >= 6ul)
 
            {
 
              /* Supported NWRITE request. */
 
              event = RIO_EVENT_NWRITE;
 
            }
 
            else
 
            {
 
              /* Unsupported size. */
 
              /* REMARK: Throw these away for now. */
 
              stack->statusInboundErrorPacketUnsupported++;
 
              stack->rxQueue = QueueDequeue(stack->rxQueue);
 
              event = RIO_EVENT_NONE;
 
            }
 
            break;
 
 
 
          case TRANSACTION_WRITE_NWRITER:
void RIOSTACK_clearInboundQueue(RioStack_t *stack)
            /* NWRITE_R transaction. */
 
            if(QueueGetFrontSize(stack->rxQueue) >= 6ul)
 
            {
            {
              /* Supported NWRITE_R request. */
  while(!QueueEmpty(stack->rxQueue))
              event = RIO_EVENT_NWRITE_R;
 
            }
 
            else
 
            {
            {
              /* Unsupported size. */
 
              /* REMARK: Throw these away for now. */
 
              stack->statusInboundErrorPacketUnsupported++;
 
              stack->rxQueue = QueueDequeue(stack->rxQueue);
              stack->rxQueue = QueueDequeue(stack->rxQueue);
              event = RIO_EVENT_NONE;
 
            }
            }
            break;
 
 
 
          default:
 
            /* Unsupported write transaction. */
 
            /* REMARK: Throw these away for now. */
 
            stack->statusInboundErrorPacketUnsupported++;
 
            stack->rxQueue = QueueDequeue(stack->rxQueue);
 
            event = RIO_EVENT_NONE;
 
            break;
 
        }
        }
        break;
 
 
 
      case FTYPE_MAINTENANCE:
 
        /* Maintenance class. */
 
 
 
        /* Check transaction type. */
 
        /* Normally, only responses could be received here unless the stack is compiled as transparent.
 
           Maintenance requests are answered by the portAddSymbol() function. */
 
        switch(transaction)
 
        {
 
          case TRANSACTION_MAINT_READ_REQUEST:
 
            /* Maintenance read request transaction. */
 
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE)
 
            {
 
              /* Supported maintenance read response. */
 
              event = RIO_EVENT_MAINT_READ_REQUEST;
 
            }
 
            else
 
            {
 
              /* Unsupported maintenance read request. */
 
              /* REMARK: Throw these away for now. */
 
              stack->statusInboundErrorPacketUnsupported++;
 
              stack->rxQueue = QueueDequeue(stack->rxQueue);
 
              event = RIO_EVENT_NONE;
 
            }
 
            break;
 
 
 
          case TRANSACTION_MAINT_WRITE_REQUEST:
uint8_t RIOSTACK_getInboundQueueLength(RioStack_t *stack)
            /* Maintenance write request transaction. */
 
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE)
 
            {
 
              /* Supported maintenance write request. */
 
              event = RIO_EVENT_MAINT_WRITE_REQUEST;
 
            }
 
            else
 
            {
            {
              /* Unsupported maintenance write response. */
  return QueueLength(stack->rxQueue);
              /* REMARK: Throw these away for now. */
 
              stack->statusInboundErrorPacketUnsupported++;
 
              stack->rxQueue = QueueDequeue(stack->rxQueue);
 
              event = RIO_EVENT_NONE;
 
            }
            }
            break;
 
 
 
          case TRANSACTION_MAINT_READ_RESPONSE:
 
            /* Maintenance read response transaction. */
 
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_RESPONSE_SIZE)
 
            {
 
              /* Supported maintenance read response. */
 
              event = RIO_EVENT_MAINT_READ_RESPONSE;
 
            }
 
            else
 
            {
 
              /* Unsupported maintenance read response. */
 
              /* REMARK: Throw these away for now. */
 
              stack->statusInboundErrorPacketUnsupported++;
 
              stack->rxQueue = QueueDequeue(stack->rxQueue);
 
              event = RIO_EVENT_NONE;
 
            }
 
            break;
 
 
 
          case TRANSACTION_MAINT_WRITE_RESPONSE:
 
            /* Maintenance write response transaction. */
uint8_t RIOSTACK_getInboundQueueAvailable(RioStack_t *stack)
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_RESPONSE_SIZE)
 
            {
 
              /* Supported maintenance write response. */
 
              event = RIO_EVENT_MAINT_WRITE_RESPONSE;
 
            }
 
            else
 
            {
            {
              /* Unsupported maintenance write response. */
  return QueueAvailable(stack->rxQueue);
              /* REMARK: Throw these away for now. */
 
              stack->statusInboundErrorPacketUnsupported++;
 
              stack->rxQueue = QueueDequeue(stack->rxQueue);
 
              event = RIO_EVENT_NONE;
 
            }
            }
            break;
 
 
 
          default:
 
            /* Unsupported maintenance transaction. */
 
            /* REMARK: Throw these away for now. */
 
            stack->statusInboundErrorPacketUnsupported++;
 
            stack->rxQueue = QueueDequeue(stack->rxQueue);
 
            event = RIO_EVENT_NONE;
 
            break;
 
        }
 
        break;
 
 
 
      case FTYPE_DOORBELL:
 
        /* Doorbell class. */
 
 
 
        /* Check size of message. */
void RIOSTACK_getInboundPacket(RioStack_t *stack, RioPacket_t *packet)
        if(QueueGetFrontSize(stack->rxQueue) == 3ul)
 
        {
 
          /* Supported doorbell. */
 
          event = RIO_EVENT_DOORBELL;
 
        }
 
        else
 
        {
        {
          /* Unsupported doorbell request. */
  uint32_t *src, *dst;
          /* REMARK: Throw these away for now. */
  uint32_t size;
          stack->statusInboundErrorPacketUnsupported++;
  uint32_t i;
          stack->rxQueue = QueueDequeue(stack->rxQueue);
 
          event = RIO_EVENT_NONE;
 
        }
 
        break;
 
 
 
      case FTYPE_MESSAGE:
 
        /* Message class. */
 
 
 
        /* Check msglen to see if this packet continues. */
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
        if(MSGLEN_GET(packet) == 0ul)
 
 
  src = QueueGetFrontBuffer(stack->rxQueue);
 
  dst = &packet->payload[0];
 
  size = QueueGetSize(stack->rxQueue);
 
  for(i = 0; i < size; i++)
        {
        {
          /* Single-packet message. */
    dst[i] = src[i];
          event = RIO_EVENT_MESSAGE;
 
        }
        }
        else
 
        {
  packet->size = size;
          /* Unsupported message type. */
 
          /* REMARK: Throw these away for now. */
 
          stack->statusInboundErrorPacketUnsupported++;
 
          stack->rxQueue = QueueDequeue(stack->rxQueue);
          stack->rxQueue = QueueDequeue(stack->rxQueue);
          event = RIO_EVENT_NONE;
 
        }
        }
        break;
 
 
 
      case FTYPE_RESPONSE:
 
        /* Response class. */
 
 
 
        /* Check transaction field. */
 
        switch(transaction)
 
        {
 
          case TRANSACTION_RESPONSE_NO_PAYLOAD:
 
            /* Response transaction without payload. */
 
 
 
            /* Check status field. */
/*******************************************************************************************
            switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
 * Packet port functions.
 
 *******************************************************************************************/
 
 
 
void RIOSTACK_portSetTime(RioStack_t *stack, const uint32_t time)
            {
            {
              case 0x00000000:
  stack->portTime = time;
                event = RIO_EVENT_RESPONSE_DONE;
 
                break;
 
              case 0x00000300:
 
                event = RIO_EVENT_RESPONSE_RETRY;
 
                break;
 
              case 0x00000700:
 
                event = RIO_EVENT_RESPONSE_ERROR;
 
                break;
 
              default:
 
                /* Unsupported response status. */
 
                /* REMARK: Throw these away for now. */
 
                stack->statusInboundErrorPacketUnsupported++;
 
                stack->rxQueue = QueueDequeue(stack->rxQueue);
 
                event = RIO_EVENT_NONE;
 
                break;
 
            }
            }
            break;
 
 
 
          case TRANSACTION_RESPONSE_MESSAGE_RESPONSE:
 
            /* Message response transaction. */
 
 
 
            /* Check status field. */
 
            switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
void RIOSTACK_portSetTimeout(RioStack_t *stack, const uint32_t time)
            {
            {
              case 0x00000000:
  stack->portTimeout = time;
                event = RIO_EVENT_MESSAGE_RESPONSE_DONE;
 
                break;
 
              case 0x00000300:
 
                event = RIO_EVENT_MESSAGE_RESPONSE_RETRY;
 
                break;
 
              case 0x00000700:
 
                event = RIO_EVENT_MESSAGE_RESPONSE_ERROR;
 
                break;
 
              default:
 
                /* Unsupported message response status. */
 
                /* REMARK: Throw these away for now. */
 
                stack->statusInboundErrorPacketUnsupported++;
 
                stack->rxQueue = QueueDequeue(stack->rxQueue);
 
                event = RIO_EVENT_NONE;
 
                break;
 
            }
            }
            break;
 
 
 
          case TRANSACTION_RESPONSE_WITH_PAYLOAD:
 
            /* Response with payload transaction. */
 
 
 
            /* Check status field. */
 
            switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
 
            {
 
              case 0x00000000:
 
                event = RIO_EVENT_RESPONSE_DONE_PAYLOAD;
 
                break;
 
              case 0x00000300:
 
                event = RIO_EVENT_RESPONSE_RETRY;
 
                break;
 
              case 0x00000700:
 
                event = RIO_EVENT_RESPONSE_ERROR;
 
                break;
 
              default:
 
                /* Unsupported response with payload status. */
 
                /* REMARK: Throw these away for now. */
 
                stack->statusInboundErrorPacketUnsupported++;
 
                stack->rxQueue = QueueDequeue(stack->rxQueue);
 
                event = RIO_EVENT_NONE;
 
                break;
 
            }
 
            break;
 
 
 
          default:
void RIOSTACK_portSetStatus(RioStack_t *stack, const uint8_t initialized)
            /* Unsupported response transaction. */
{
            /* REMARK: Throw these away for now. */
  /* REMARK: Clean the queues here as well??? */
            stack->statusInboundErrorPacketUnsupported++;
  if (initialized)
            stack->rxQueue = QueueDequeue(stack->rxQueue);
  {
            event = RIO_EVENT_NONE;
    stack->rxState = RX_STATE_PORT_INITIALIZED;
            break;
    stack->rxCounter = 0u;
        }
    stack->rxCrc = 0xffffu;
        break;
    stack->rxStatusReceived = 0;
 
    stack->rxAckId = 0u;
 
    stack->rxAckIdAcked = 0u;
 
    stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
 
 
      default:
    stack->txState = TX_STATE_PORT_INITIALIZED;
        /* Unsupported class. */
    stack->txCounter = 0u;
        /* REMARK: Throw these away for now. */
    stack->txStatusCounter = 0u;
        stack->statusInboundErrorPacketUnsupported++;
    stack->txFrameState = TX_FRAME_START;
        stack->rxQueue = QueueDequeue(stack->rxQueue);
    stack->txAckId = 0u;
        event = RIO_EVENT_NONE;
    stack->txAckIdWindow = 0u;
        break;
 
    }
 
  }
  }
  else
  else
  {
  {
    /* No pending events available. */
    stack->rxState = RX_STATE_UNINITIALIZED;
    event = RIO_EVENT_NONE;
    stack->txState = TX_STATE_UNINITIALIZED;
  }
  }
 
 
  return event;
 
}
}
 
 
 
 
void RIO_packetRemove( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  stack->rxQueue = QueueDequeue(stack->rxQueue);
 
}
 
 
 
 
 
bool_t RIO_sendAvailable( RioStack_t *stack, const uint16_t size )
void RIOSTACK_portAddSymbol(RioStack_t *stack, const RioSymbol_t s)
{
{
  /* Return if there are buffers available and if the requested size is less
  uint8_t stype0;
     than or equal to the maximum payload that fits into one packet. */
  uint8_t parameter0;
  return (bool_t) (stack->masterEnable && (size <= 256u) && (QueueAvailable(stack->txQueue) > 0u));
  uint8_t parameter1;
}
  uint8_t stype1;
 
 
 
 
uint32_t RIO_packetGet( RioStack_t *stack, uint32_t length, uint32_t *dest)
  switch(stack->rxState)
{
{
  uint32_t i;
    case RX_STATE_PORT_INITIALIZED:
  uint32_t size;
      /******************************************************************************
  uint32_t *src;
       * PORT_INITIALIZED
 
       * This state is entered to initialize the link. Only status-control-symbols
 
       * are accepted in this state. When 7 error-free, i.e. with CRC5 correct, status
 
       * control symbols has been received, change state to linkInitialized.
 
       ******************************************************************************/
 
 
 
      /* Check the type of symbol. */
 
      if(s.type == RIOSTACK_SYMBOL_TYPE_CONTROL)
 
      {
 
        /* This is a control symbol. */
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
        /* Check that the control symbol contains no errors. */
 
        if(Crc5(s.data, 0x1fu) == (s.data & 0x1ful))
 
        {
 
          /* Error-free control symbol. */
 
 
  /* Get the size and a pointer to the raw packet. */
          /* Check if the symbol is a status symbol. */
  size = QueueGetFrontSize(stack->rxQueue);
          stype0 = STYPE0_GET(s.data);
  src = QueueGetFrontBuffer(stack->rxQueue);
          if(stype0 == STYPE0_STATUS)
 
          {
 
            /* Status symbol received. */
 
 
  ASSERT((length >= size), "Too short destination packet.");
            /* Indicate an error-free status has been received. */
 
            stack->rxStatusReceived = 1;
 
 
  /* Copy the packet to the destination packet pointer. */
            /* Check if enough status control symbols has been received. */
  for(i = 0; i < size; i++)
            if(stack->rxCounter == 7u)
  {
  {
    dest[i] = src[i];
              /* Enough correct status control symbols has been received without
  }
                 errors in between. */
 
 
  /* Remove the packet from the queue. */
              /* Setup the transmitter with the content of the symbol. */
  stack->rxQueue = QueueDequeue(stack->rxQueue);
              stack->txAckId = PARAMETER0_GET(s.data);
 
              stack->txAckIdWindow = stack->txAckId;
 
              stack->txBufferStatus = PARAMETER1_GET(s.data);
 
 
  /* Return the size of the copied packet. */
              /* Set the transmitter in its normal operational mode. */
  return size;
              stack->rxState = RX_STATE_LINK_INITIALIZED;
 
              stack->rxCounter = 0u;
}
}
 
            else
 
 
void RIO_packetSet( RioStack_t *stack, uint32_t length, uint32_t *src)
 
{
{
  uint32_t i;
              /* Count the number of consequitive error-free status control symbols
  uint32_t *dest;
                 that has been received. */
 
              stack->rxCounter++;
 
            }
  ASSERT((QueueAvailable(stack->txQueue) > 0), "Writing to full transmission queue.");
          }
  ASSERT((length < RIO_PACKET_SIZE), "Writing a too large packet.");
          else
 
 
  /* Set the size of the new packet. */
 
  QueueSetSize(stack->txQueue, length);
 
 
 
  /* Get a pointer to the destination packet in the transmission queue. */
 
  dest = QueueGetBackBuffer(stack->txQueue);
 
 
 
  /* Copy the packet into the transmission queue. */
 
  for(i = 0; i < length; i++)
 
  {
  {
    dest[i] = src[i];
            /* The received symbol is not a status symbol. */
 
            /* Discard it. */
  }
  }
 
        }
  /* Make sure the ackId field of the copied packet is reset. */
        else
  /* Unless this is done, the ackId field of the transmitted packet may be corrupted. */
        {
  dest[0] &= 0x03ffffff;
          /* CRC error in control symbol. */
 
          /* Restart counting error-free status-control-symbols. */
  /* Enqueue the new packet. */
          stack->rxCounter = 0u;
  stack->txQueue = QueueEnqueue(stack->txQueue);
        }
 
      }
 
      else
 
      {
 
        /* Not a control symbol. */
 
        /* Discard the symbol. */
}
}
 
 
/*******************************************************************************************
      break;
 * Configuration-space access methods.
 
 *******************************************************************************************/
    case RX_STATE_LINK_INITIALIZED:
 
      /******************************************************************************
 
       * LINK_INITIALIZED
 
       * The normal state. Accept packets and forward them.
 
       ******************************************************************************/
 
 
uint32_t RIO_readConfig( RioStack_t *stack, const uint32_t offset )
      /* Check the type of symbol. */
 
      switch(s.type)
{
{
  uint32_t data;
        case RIOSTACK_SYMBOL_TYPE_CONTROL:
 
          /**************************************************************************
 
           * This is a control symbol.
 
           **************************************************************************/
 
 
  /* Check the area of the access. */
          /* Check if the CRC is correct. */
  if(offset < 0x10000ul)
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
  {
  {
    /* Access is in not in implementation-defined space. */
            /* The CRC is correct. */
 
 
 
            /* Get the content of the control symbol. */
 
            stype0 = STYPE0_GET(s.data);
 
            parameter0 = PARAMETER0_GET(s.data);
 
            parameter1 = PARAMETER1_GET(s.data);
 
            stype1 = STYPE1_GET(s.data);
 
 
    /* Check offset and return. */
            /**********************************************************************************
    switch(offset)
             * Check the stype0 part of the symbol.
 
             * Note that errors in this should trigger OUTPUT_ERROR_STOPPED.
 
             **********************************************************************************/
 
            switch(stype0)
    {
    {
      case DEVICE_IDENTITY_CAR:
              case STYPE0_STATUS:
        data = (uint32_t)stack->deviceIdentity << 16;
                /* A status containing the current ackId and the buffer status has been
        data |= stack->deviceVendorIdentity;
                   received. */
        break;
                handleStatus(stack, parameter0, parameter1);
      case DEVICE_INFORMATION_CAR:
 
        data = stack->deviceRev;
 
        break;
 
      case ASSEMBLY_IDENTITY_CAR:
 
        data = (uint32_t)stack->assyIdentity << 16;
 
        data |= stack->assyVendorIdentity;
 
        break;
 
      case ASSEMBLY_INFORMATION_CAR:
 
        data = (uint32_t)stack->assyRev << 16;
 
        data |= EXTENDED_FEATURES_OFFSET;
 
        break;
 
      case PROCESSING_ELEMENT_FEATURES_CAR:
 
        /* Indicate processor with extended features
 
           and 34-bit address support. */
 
        /* Supports common transport large systems. */
 
        data = 0x20000019ul;
 
        break;
 
      case SOURCE_OPERATIONS_CAR:
 
        /* Supporting doorbells and data messages. */
 
        data = 0x00000c00ul;
 
        break;
        break;
      case DESTINATION_OPERATIONS_CAR:
 
        /* Supporting doorbells and data messages. */
              case STYPE0_PACKET_ACCEPTED:
        data = 0x00000c00ul;
                /* A packet has been accepted by the link partner. */
 
                handlePacketAccepted(stack, parameter0, parameter1);
        break;
        break;
      case PROCESSING_ELEMENT_LOGICAL_LAYER_CONTROL_CSR:
 
        /* Supports 34-bit addresses. */
              case STYPE0_PACKET_RETRY:
        data = 0x00000001ul;
                /* The link partner wants us to initiate a restart of the received ackId. */
 
                handlePacketRetry(stack, parameter0, parameter1);
        break;
        break;
      case BASE_DEVICE_ID_CSR:
 
        data = stack->baseDeviceId;
              case STYPE0_PACKET_NOT_ACCEPTED:
 
                /* The link partner indicates that a packet has been rejected. */
 
                handlePacketNotAccepted(stack, parameter0, parameter1);
        break;
        break;
      case HOST_BASE_DEVICE_ID_LOCK_CSR:
 
        data = stack->hostBaseDeviceIdLock & (uint32_t)0x0000fffful;
              case STYPE0_LINK_RESPONSE:
 
                /* The link partner has sent a response to a link-request. */
 
                handleLinkResponse(stack, parameter0, parameter1);
        break;
        break;
      case COMPONENT_TAG_CSR:
 
        data = stack->componentTag;
              case STYPE0_VC_STATUS:
 
              case STYPE0_RESERVED:
 
              case STYPE0_IMPLEMENTATION_DEFINED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
        break;
        break;
      case LP_SERIAL_REGISTER_BLOCK_HEADER(EXTENDED_FEATURES_OFFSET):
            }
        /* Indicate Generic end point device and no more extended features. */
 
        data = 0x00000001ul;
            /**********************************************************************************
 
             * Check the stype1 part of the symbol.
 
             * Note that errors in this should trigger INPUT_ERROR_STOPPED.
 
             **********************************************************************************/
 
            switch(stype1)
 
            {
 
              case STYPE1_START_OF_PACKET:
 
                /* Start of a new packet. */
 
                handleStartOfPacket(stack);
        break;
        break;
      case PORT_LINK_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
 
        /* REMARK: Implement this... */
              case STYPE1_END_OF_PACKET:
        data = 0x00000000ul;
                /* Ending a packet. */
 
                handleEndOfPacket(stack);
        break;
        break;
      case PORT_RESPONSE_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
 
        /* REMARK: Implement this... */
              case STYPE1_STOMP:
        data = 0x00000000ul;
                /* Cancel the currently received frame. */
 
                stack->rxCounter = 0;
        break;
        break;
      case PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
 
        /* Return the host, master enable bit and the discovered bit. */
              case STYPE1_RESTART_FROM_RETRY:
        data = ((uint32_t) stack->host) << 31;
                /* Cancel the currently received frame when in this state. */
        data |= ((uint32_t) stack->masterEnable) << 30;
                stack->rxCounter = 0;
        data |= ((uint32_t) stack->discovered) << 29;
 
        break;
        break;
      case PORT_N_LOCAL_ACKID_CSR(EXTENDED_FEATURES_OFFSET, 0u):
 
        data = ((uint32_t) stack->rxAckId) << 24;
              case STYPE1_LINK_REQUEST:
        data |= ((uint32_t) stack->txAckId) << 8;
                /* A link-request has been received. */
        data |= ((uint32_t) stack->txAckIdWindow);
                handleLinkRequest(stack, CMD_GET(s.data));
        break;
        break;
      case PORT_N_ERROR_AND_STATUS_CSR(EXTENDED_FEATURES_OFFSET, 0u):
 
        /* Indicate the port status here. */
              case STYPE1_NOP:
        if((stack->txState == TX_STATE_LINK_INITIALIZED) &&
                /* No operation symbol. */
           (stack->rxState == RX_STATE_LINK_INITIALIZED))
                /* Discard these. */
        {
 
          /* Port ok. */
 
          data = 0x00000002ul;
 
        }
 
        else
 
        {
 
          /* Port not ok. */
 
          data = 0x00000001ul;
 
        }
 
        break;
        break;
 
 
 
              case STYPE1_MULTICAST_EVENT:
 
              case STYPE1_RESERVED:
      default:
      default:
        data = 0x00000000ul;
                /* Unsupported symbol received. */
 
                /* Discard them. */
        break;
        break;
    }
    }
  }
  }
  else
  else
  {
  {
    /* Access is in implementation-defined space. */
            /* The control symbol CRC is incorrect. */
 
            /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
    /* Check if there are any registered callback. */
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
    if((stack->observer != NULL) &&
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
       (stack->observer->configRead != NULL))
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
    {
            stack->statusInboundErrorControlCrc++;
      /* Call the observer callback to handle the access. */
 
      data = stack->observer->configRead(stack, offset - 0x00010000ul);
 
    }
 
    else
 
    {
 
      data = 0x00000000ul;
 
    }
 
  }
 
 
 
  return data;
 
}
}
 
          break;
 
 
 
        case RIOSTACK_SYMBOL_TYPE_DATA:
 
          /**************************************************************************
 
           * This is a data symbol.
 
           **************************************************************************/
 
 
void RIO_writeConfig( RioStack_t *stack, const uint32_t offset, const uint32_t data)
          /* Check if a packet has been started and that it is not too long. */
{
          if ((stack->rxCounter >= 1u) && (stack->rxCounter <= RIOPACKET_SIZE_MAX))
  /* Check the area of the access. */
 
  if(offset < 0x00010000ul)
 
  {
  {
    /* Access is not in implementation-defined space. */
            /* A packet has been started. */
 
 
    /* Check offset and execute request. */
            /* Check if the ackId is correct on the first part of the packet. */
    switch(offset)
            if ((stack->rxCounter > 1u) ||
 
                ((stack->rxCounter == 1u) && (((uint8_t)(s.data >> 27)) == stack->rxAckId)))
    {
    {
      case BASE_DEVICE_ID_CSR:
              /* The ackId is the expected one. */
        stack->baseDeviceId = (uint16_t) data;
 
        break;
              /* Check if this is the first symbol of a packet. */
      case HOST_BASE_DEVICE_ID_LOCK_CSR:
              if (stack->rxCounter == 1u)
        if (stack->hostBaseDeviceIdLock == 0xfffffffful)
 
        {
        {
          stack->hostBaseDeviceIdLock = (uint16_t)data;
                /* This is the first symbol of the packet. */
 
                /* Start to calculate the CRC of the packet. */
 
                /* Note that the ackId should not be included in the CRC calculation. */
 
                stack->rxCrc = RIOPACKET_Crc32(s.data & (uint32_t)0x03fffffful, 0xffffu);
        }
        }
        else
        else
        {
        {
          if ((stack->hostBaseDeviceIdLock & (uint32_t)0x0000fffful) ==
                /* This is not the first symbol. */
              (data & (uint32_t)0x0000fffful))
                /* Continue to calculate the CRC of the packet. */
          {
                stack->rxCrc = RIOPACKET_Crc32(s.data, stack->rxCrc);
            stack->hostBaseDeviceIdLock = 0xfffffffful;
              }
 
 
 
              /* Save the new data in the packet queue and update the reception counter. */
 
              QueueSetContent(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul, s.data);
 
              stack->rxCounter++;
          }
          }
          else
          else
          {
          {
            /* Ignore the write. */
              /* The ackId is not correct. */
 
              /* Packet error. Enter input-error-stopped state. */
 
              stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
              stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
              stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
 
              stack->statusInboundErrorPacketAckId++;
          }
          }
        }
        }
        break;
          else
      case COMPONENT_TAG_CSR:
 
        stack->componentTag = data;
 
        break;
 
      case PORT_LINK_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
 
        /* REMARK: Implement this... */
 
        break;
 
      case PORT_RESPONSE_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
 
        /* REMARK: Implement this... */
 
        break;
 
      case PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
 
        /* Return host, master enable bit and discovered bit. */
 
        stack->host = (uint8_t)(data >> 31) & 1u;
 
        stack->masterEnable = (uint8_t)(data >> 30) & 1u;
 
        stack->discovered = (uint8_t)(data >> 29) & 1u;
 
        break;
 
      case PORT_N_LOCAL_ACKID_CSR(EXTENDED_FEATURES_OFFSET, 0u):
 
        if(data & 0x80000000)
 
        {
 
          while(!QueueEmpty(stack->txQueue))
 
          {
          {
            stack->txQueue = QueueDequeue(stack->txQueue);
            /* No packet has been started or the packet is too long. */
          }
            /* Packet error. Enter input-error-stopped state. */
 
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
 
            stack->statusInboundErrorGeneral++;
        }
        }
        stack->rxAckId = (uint8_t) ((data >> 24) & 0x1f);
 
        stack->txAckId = (uint8_t) ((data >> 8) & 0x1f);
 
        stack->txAckIdWindow = (uint8_t) (data & 0x1f);
 
        break;
 
      default:
 
        break;
        break;
    }
 
  }
 
  else
 
  {
 
    /* Access is in implementation-defined space. */
 
 
 
    /* Check if there are any registered callback. */
        case RIOSTACK_SYMBOL_TYPE_ERROR:
    if((stack->observer != NULL) &&
          /**************************************************************************
       (stack->observer->configWrite != NULL))
           * The decoder has received a erronous symbol.
    {
           **************************************************************************/
      /* Call the observer callback to handle the access. */
 
      stack->observer->configWrite(stack, offset - 0x00010000ul, data);
 
    }
 
    else
 
    {
 
      /* Dont do anything. */
 
    }
 
  }
 
}
 
 
 
 
          /* Idle symbol error. Place the receiver in input-error-stopped state. */
 
          stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
          stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
          stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
 
          stack->statusInboundErrorIllegalCharacter++;
 
          break;
 
 
/*******************************************************************************************
        case RIOSTACK_SYMBOL_TYPE_IDLE:
 * Logical I/O MAINTENANCE-READ functions.
        default:
 *******************************************************************************************/
          /**************************************************************************
 
           * Idle symbol or unsupported symbol.
 
           **************************************************************************/
 
 
#ifdef RIO_TRANSPARENT
          /* Discard these for now. */
void RIO_sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
          break;
                                     const uint8_t hopCount, const uint32_t offset)
 
{
 
  sendMaintenanceReadRequest(stack, destid, srcid, tid, hopCount, offset);
 
}
 
#else
 
void RIO_sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                                     const uint8_t hopCount, const uint32_t offset)
 
{
 
  sendMaintenanceReadRequest(stack, destid, stack->baseDeviceId, tid, hopCount, offset);
 
}
}
#endif
      break;
 
 
#ifdef RIO_TRANSPARENT
    case RX_STATE_INPUT_RETRY_STOPPED:
void RIO_receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
      /******************************************************************************
                                        uint8_t *hopCount, uint32_t *offset)
       * INPUT_RETRY_STOPPED
{
       * This state is entered when no more buffers was available and a packet was
  receiveMaintenanceReadRequest( stack, destid, srcid, tid, hopCount, offset);
       * received. When in this state, all packets should be discarded until a
}
       * RESTART-FROM-RETRY symbol is received. See section 5.9.1.4 of the standard.
#else
       * Note that it is only the input side of the port that are affected, not the
void RIO_receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
       * output side. Packets may still be transmitted and acknowledges should be
                                        uint8_t *hopCount, uint32_t *offset)
       * accepted.
{
       ******************************************************************************/
  receiveMaintenanceReadRequest( stack, srcid, srcid, tid, hopCount, offset);
 
}
 
#endif
 
 
 
#ifdef RIO_TRANSPARENT
      /* Check the type of symbol. */
void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
      switch(s.type)
                                      const uint8_t hopCount, const uint32_t data)
 
{
 
  sendMaintenanceReadResponse(stack, destid, srcid, tid, hopCount, data);
 
}
 
#else
 
void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                                      const uint8_t hopCount, const uint32_t data)
 
{
{
  sendMaintenanceReadResponse(stack, destid, stack->baseDeviceId, tid, hopCount, data);
        case RIOSTACK_SYMBOL_TYPE_CONTROL:
}
          /* This is a control symbol. */
#endif
 
 
 
#ifdef RIO_TRANSPARENT
          /* Check if the CRC is correct. */
void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
                                         uint8_t *hopCount, uint32_t *data)
 
{
 
  receiveMaintenanceReadResponse(stack, destid, srcid, tid, hopCount, data);
 
}
 
#else
 
void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                                         uint8_t *hopCount, uint32_t *data)
 
{
{
  receiveMaintenanceReadResponse(stack, srcid, srcid, tid, hopCount, data);
            /* The CRC is correct. */
}
 
#endif
 
 
 
/*******************************************************************************************
            /* Get the content of the control symbol. */
 * Logical I/O MAINTENANCE-WRITE functions.
            stype0 = STYPE0_GET(s.data);
 *******************************************************************************************/
            parameter0 = PARAMETER0_GET(s.data);
 
            parameter1 = PARAMETER1_GET(s.data);
 
            stype1 = STYPE1_GET(s.data);
 
 
#ifdef RIO_TRANSPARENT
            /* Check the stype0 part of the symbol. */
void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
            switch(stype0)
                                      const uint8_t hopCount, const uint32_t offset, const uint32_t data )
 
{
 
  sendMaintenanceWriteRequest(stack, destid, srcid, tid, hopCount, offset, data);
 
}
 
#else
 
void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                                      const uint8_t hopCount, const uint32_t offset, const uint32_t data )
 
{
{
  sendMaintenanceWriteRequest(stack, destid, stack->baseDeviceId, tid, hopCount, offset, data);
              case STYPE0_STATUS:
}
                /* A status containing the current ackId and the buffer status has been
#endif
                   received. */
 
                handleStatus(stack, parameter0, parameter1);
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE0_PACKET_ACCEPTED:
void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
                /* A packet has been accepted by the link partner. */
                                         uint8_t *hopCount, uint32_t *offset, uint32_t *data )
                handlePacketAccepted(stack, parameter0, parameter1);
{
                break;
  receiveMaintenanceWriteRequest(stack, destid, srcid, tid, hopCount, offset, data);
 
}
 
#else
 
void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                                         uint8_t *hopCount, uint32_t *offset, uint32_t *data )
 
{
 
  receiveMaintenanceWriteRequest(stack, srcid, srcid, tid, hopCount, offset, data);
 
}
 
#endif
 
 
 
#ifdef RIO_TRANSPARENT
 
void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                       const uint8_t hopCount)
 
{
 
  sendMaintenanceWriteResponse(stack, destid, srcid, tid, hopCount);
 
}
 
#else
 
void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                                       const uint8_t hopCount)
 
{
 
  sendMaintenanceWriteResponse(stack, destid, stack->baseDeviceId, tid, hopCount);
 
}
 
#endif
 
 
 
#ifdef RIO_TRANSPARENT
              case STYPE0_PACKET_RETRY:
void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
                /* The link partner wants us to initiate a restart of the received ackId. */
                                      uint8_t *hopCount)
                handlePacketRetry(stack, parameter0, parameter1);
{
                break;
  receiveMaintenanceWriteResponse(stack, destid, srcid, tid, hopCount);
 
}
 
#else
 
void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                                      uint8_t *hopCount)
 
{
 
  receiveMaintenanceWriteResponse(stack, srcid, srcid, tid, hopCount);
 
}
 
#endif
 
 
 
/*******************************************************************************************
              case STYPE0_PACKET_NOT_ACCEPTED:
 * Logical I/O NWRITE/NWRITER functions.
                /* The link partner indicates that a packet has been rejected. */
 *******************************************************************************************/
                handlePacketNotAccepted(stack, parameter0, parameter1);
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE0_LINK_RESPONSE:
void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid,
                /* The link partner has sent a response to a link-request. */
                     const uint32_t address, const uint16_t size, const uint8_t *data)
                handleLinkResponse(stack, parameter0, parameter1);
{
                break;
  sendNwrite(stack, destid, srcid, 0, address, size, data, 0u);
 
}
 
#else
 
void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid,
 
                     const uint32_t address, const uint16_t size, const uint8_t *data)
 
{
 
  sendNwrite(stack, destid, stack->baseDeviceId, 0, address, size, data, 0u);
 
}
 
#endif
 
 
 
#ifdef RIO_TRANSPARENT
              case STYPE0_VC_STATUS:
void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
              case STYPE0_RESERVED:
                      const uint32_t address, const uint16_t size, const uint8_t *data)
              case STYPE0_IMPLEMENTATION_DEFINED:
{
              default:
  sendNwrite(stack, destid, srcid, tid, address, size, data, 1u);
                /* Unsupported symbol received. */
}
                /* Discard them. */
#else
                break;
void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                      const uint32_t address, const uint16_t size, const uint8_t *data)
 
{
 
  sendNwrite(stack, destid, stack->baseDeviceId, tid, address, size, data, 1u);
 
}
}
#endif
 
 
 
#ifdef RIO_TRANSPARENT
            /* Check the stype1 part of the symbol. */
uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
            switch(stype1)
                        uint32_t *address, const uint16_t dataLength, uint8_t *data )
 
{
 
  return receiveNwrite(stack, destid, srcid, tid, address, dataLength, data);
 
}
 
#else
 
uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                        uint32_t *address, const uint16_t dataLength, uint8_t *data )
 
{
{
  return receiveNwrite(stack, srcid, srcid, tid, address, dataLength, data);
              case STYPE1_START_OF_PACKET:
}
                /* Starting new frames are ignored in this state. */
#endif
                break;
 
 
/*******************************************************************************************
              case STYPE1_END_OF_PACKET:
 * Logical I/O NREAD functions.
                /* Ending new frames are ignored in this state. */
 *******************************************************************************************/
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE1_STOMP:
void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
                /* Restarting frames are ignored in this state. */
                    const uint32_t address, const uint16_t dataLength)
                break;
{
 
  sendNread(stack, destid, srcid, tid, address, dataLength);
 
}
 
#else
 
void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                    const uint32_t address, const uint16_t dataLength)
 
{
 
  sendNread(stack, destid, stack->baseDeviceId, tid, address, dataLength);
 
}
 
#endif
 
 
 
#ifdef RIO_TRANSPARENT
              case STYPE1_RESTART_FROM_RETRY:
void RIO_receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
                /* The link partner has confirmed our packet-retry-symbol. */
                       uint32_t *address, uint16_t *dataLength)
                /* Go back to the normal state and reset the frame reception. */
{
                stack->rxState = RX_STATE_LINK_INITIALIZED;
  receiveNread( stack, destid, srcid, tid, address, dataLength);
                stack->rxCounter = 0u;
}
                break;
#else
 
void RIO_receiveNread( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                       uint32_t *address, uint16_t *dataLength)
 
{
 
  receiveNread( stack, srcid, srcid, tid, address, dataLength);
 
}
 
#endif
 
 
 
/*******************************************************************************************
              case STYPE1_LINK_REQUEST:
 * Logical I/O RESPONSE-DONE-PAYLOAD, RESPONSE-DONE, RESPONSE-RETRY and RESPONSE-ERROR
                /* A link-request has been received. */
 * functions.
                handleLinkRequest(stack, CMD_GET(s.data));
 *******************************************************************************************/
                stack->rxState = RX_STATE_LINK_INITIALIZED;
 
                break;
 
 
 
              case STYPE1_NOP:
 
                /* No operation symbol. */
 
                /* Discard these. */
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE1_MULTICAST_EVENT:
void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
              case STYPE1_RESERVED:
                                  const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
              default:
{
                /* Unsupported symbol received. */
  sendResponseDonePayload(stack, destid, srcid, tid, address, bufferSize, buffer);
                /* Discard them. */
}
                break;
#else
 
void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                                  const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
 
{
 
  sendResponseDonePayload(stack, destid, stack->baseDeviceId, tid, address, bufferSize, buffer);
 
}
}
#endif
 
 
 
#ifdef RIO_TRANSPARENT
 
uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                         const uint32_t address, const uint16_t dataLength, uint8_t *data )
 
{
 
  return receiveResponseDonePayload(stack, destid, srcid, tid, address, dataLength, data);
 
}
}
#else
          else
uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                                         const uint32_t address, const uint16_t dataLength, uint8_t *data )
 
{
{
  return receiveResponseDonePayload(stack, srcid, srcid, tid, address, dataLength, data);
            /* The control symbol CRC is incorrect. */
 
            /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
 
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
 
            stack->statusInboundErrorControlCrc++;
}
}
#endif
          break;
 
 
#ifdef RIO_TRANSPARENT
        case RIOSTACK_SYMBOL_TYPE_ERROR:
void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid)
          /* Idle symbol error. Place the receiver in input-error-stopped state. */
{
          stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
  sendResponse(stack, destid, srcid, tid, 0x0u);
          stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
}
          stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
#else
          stack->statusInboundErrorIllegalCharacter++;
void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t tid)
          break;
{
 
  sendResponse(stack, destid, stack->baseDeviceId, tid, 0x0u);
        case RIOSTACK_SYMBOL_TYPE_DATA:
 
        case RIOSTACK_SYMBOL_TYPE_IDLE:
 
        default:
 
          /* Data or idle symbol. */
 
          /* Discard these in this state. */
 
          break;
}
}
#endif
      break;
 
 
 
    case RX_STATE_INPUT_ERROR_STOPPED:
 
      /******************************************************************************
 
       * INPUT_ERROR_STOPPED
 
       * This state is entered when an error situation has occurred. When in this
 
       * state, all symbols should be discarded until a link-request-symbols has
 
       * been received. See section 5.13.2.6 in part 6 of the standard.
 
       * Note that it is only the input side of the port that are affected, not the
 
       * output side. Packets may still be transmitted and acknowledges should be
 
       * accepted.
 
       ******************************************************************************/
 
 
#ifdef RIO_TRANSPARENT
      /* Check the type of symbol. */
void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
      switch(s.type)
{
{
  receiveResponse(stack, destid, srcid, tid);
        case RIOSTACK_SYMBOL_TYPE_CONTROL:
}
          /* This is a control symbol. */
#else
 
void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
          /* Check if the CRC is correct. */
 
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
{
{
  receiveResponse(stack, srcid, srcid, tid);
            /* The CRC is correct. */
}
 
#endif
 
 
 
 
            /* Get the content of the control symbol. */
 
            stype0 = STYPE0_GET(s.data);
 
            parameter0 = PARAMETER0_GET(s.data);
 
            parameter1 = PARAMETER1_GET(s.data);
 
            stype1 = STYPE1_GET(s.data);
 
 
#ifdef RIO_TRANSPARENT
            /* Check the stype0 part of the symbol. */
void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid )
            switch(stype0)
{
 
  sendResponse(stack, destid, srcid, tid, 0x3u);
 
}
 
#else
 
void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t tid )
 
{
{
  sendResponse(stack, destid, stack->baseDeviceId, tid, 0x3u);
              case STYPE0_STATUS:
}
                /* A status containing the current ackId and the buffer status has been
#endif
                   received. */
 
                handleStatus(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_ACCEPTED:
 
                /* A packet has been accepted by the link partner. */
 
                handlePacketAccepted(stack, parameter0, parameter1);
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE0_PACKET_RETRY:
void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
                /* The link partner wants us to initiate a restart of the received ackId. */
{
                handlePacketRetry(stack, parameter0, parameter1);
  receiveResponse(stack, destid, srcid, tid);
                break;
}
 
#else
 
void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
 
{
 
  receiveResponse(stack, srcid, srcid, tid);
 
}
 
#endif
 
 
 
 
              case STYPE0_PACKET_NOT_ACCEPTED:
 
                /* The link partner indicates that a packet has been rejected. */
 
                handlePacketNotAccepted(stack, parameter0, parameter1);
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE0_LINK_RESPONSE:
void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid)
                /* The link partner has sent a response to a link-request. */
{
                handleLinkResponse(stack, parameter0, parameter1);
  sendResponse(stack, destid, srcid, tid, 0x7u);
                break;
 
 
 
              case STYPE0_VC_STATUS:
 
              case STYPE0_RESERVED:
 
              case STYPE0_IMPLEMENTATION_DEFINED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
 
                break;
}
}
#else
 
void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t tid)
            /* Check the stype1 part of the symbol. */
 
            switch(stype1)
{
{
  sendResponse(stack, destid, stack->baseDeviceId, tid, 0x7u);
              case STYPE1_START_OF_PACKET:
}
                /* Starting new frames are ignored in this state. */
#endif
                break;
 
 
 
              case STYPE1_END_OF_PACKET:
 
                /* Ending new frames are ignored in this state. */
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE1_STOMP:
void RIO_receiveResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
                /* Restarting frames are ignored in this state. */
{
                break;
  receiveResponse(stack, destid, srcid, tid);
 
}
 
#else
 
void RIO_receiveResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
 
{
 
  receiveResponse(stack, srcid, srcid, tid);
 
}
 
#endif
 
 
 
 
              case STYPE1_RESTART_FROM_RETRY:
 
                /* Restart-from-retry are ignored in this state.  */
 
                break;
 
 
 
              case STYPE1_LINK_REQUEST:
 
                /* This is the symbol we have been waiting for. */
 
                /* Force the transmitter to send a link-response and go back into the normal
 
                   operational state. */
 
                /* The transmitter will always send a status as the first symbol after this. */
 
                handleLinkRequest(stack, CMD_GET(s.data));
 
                stack->rxState = RX_STATE_LINK_INITIALIZED;
 
                break;
 
 
/*******************************************************************************************
              case STYPE1_NOP:
 * Logical message passing DOORBELL and MESSAGE functions.
                /* No operation symbol. */
 *******************************************************************************************/
                /* Discard these. */
 
                break;
 
 
#ifdef RIO_TRANSPARENT
              case STYPE1_MULTICAST_EVENT:
void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
              case STYPE1_RESERVED:
                       const uint16_t info )
              default:
{
                /* Unsupported symbol received. */
  sendDoorbell(stack, destid, srcid, tid, info);
                /* Discard them. */
}
                break;
#else
 
void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
 
                       const uint16_t info )
 
{
 
  sendDoorbell(stack, destid, stack->baseDeviceId, tid, info);
 
}
}
#endif
 
 
 
#ifdef RIO_TRANSPARENT
 
void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                          uint16_t *info)
 
{
 
  receiveDoorbell(stack, destid, srcid, tid, info);
 
}
}
#else
          else
void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
 
                          uint16_t *info)
 
{
{
  receiveDoorbell(stack, srcid, srcid, tid, info);
            /* The CRC is incorrect. */
 
            /* Discard these in this state. */
}
}
#endif
          break;
 
 
#ifdef RIO_TRANSPARENT
        case RIOSTACK_SYMBOL_TYPE_DATA:
void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
        case RIOSTACK_SYMBOL_TYPE_IDLE:
                      const uint16_t bufferSize, const uint8_t* bufferData)
        case RIOSTACK_SYMBOL_TYPE_ERROR:
{
        default:
  sendMessage(stack, destid, srcid, mailbox, bufferSize, bufferData);
          /* Data, idle or error symbol. */
}
          /* Discard these in this state. */
#else
          break;
void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox,
 
                      const uint16_t bufferSize, const uint8_t* bufferData)
 
{
 
  sendMessage(stack, destid, stack->baseDeviceId, mailbox, bufferSize, bufferData);
 
}
}
#endif
      break;
 
 
#ifdef RIO_TRANSPARENT
    case RX_STATE_UNINITIALIZED:
uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
    default:
                             const uint16_t dataLength, uint8_t *data )
      /******************************************************************************
{
       * Wait for the port to be initialized.
  return receiveMessage(stack, destid, srcid, mailbox, dataLength, data);
       ******************************************************************************/
 
 
 
      /* Discard all incoming symbols. */
 
      break;
}
}
#else
 
uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox,
 
                             const uint16_t dataLength, uint8_t *data )
 
{
 
  return receiveMessage(stack, srcid, srcid, mailbox, dataLength, data);
 
}
}
#endif
 
 
 
/*******************************************************************************************
 
 * Logical message passing MESSAGE-RESPONSE functions.
 
 *******************************************************************************************/
 
 
 
#ifdef RIO_TRANSPARENT
 
void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
RioSymbol_t RIOSTACK_portGetSymbol(RioStack_t *stack )
{
 
  sendMessageResponse(stack, destid, srcid, mailbox, 0x0u);
 
}
 
#else
 
void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
 
{
{
  sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x0u);
  RioSymbol_t s;
}
 
#endif
 
 
 
 
 
#ifdef RIO_TRANSPARENT
  switch(stack->txState)
void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
 
{
 
  receiveMessageResponse(stack, destid, srcid, mailbox);
 
}
 
#else
 
void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
 
{
{
  receiveMessageResponse(stack, srcid, srcid, mailbox);
    case TX_STATE_PORT_INITIALIZED:
}
      /******************************************************************************
#endif
       * PORT_INITIALIZED
 
       * This state is entered to initialize the link. Send status-control-symbols
 
       * once in a while until the receiver has received enough error-free status-
 
       * control-symbols and we have transmitted enough status-control-symbols. Once
 
       * an error-free status-control-symbol has been received, the statuses are
 
       * transmitted more frequently to decrease the time for the link to be
 
       * initialized.
 
       ******************************************************************************/
 
 
#ifdef RIO_TRANSPARENT
      /* Check if an idle symbol or a status control symbol should be sent. */
void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
      if(((stack->rxStatusReceived == 0) && (stack->txCounter == 255u)) ||
{
         ((stack->rxStatusReceived == 1) && (stack->txCounter >= 15u)))
  sendMessageResponse(stack, destid, srcid, mailbox, 0x3u);
 
}
 
#else
 
void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
 
{
{
  sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x3u);
        /* A control symbol should be sent. */
}
 
#endif
 
 
 
 
        /* Create a new status symbol and reset the transmission counter. */
 
        stack->txCounter = 0u;
 
        s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                STYPE1_NOP, 0u);
 
 
#ifdef RIO_TRANSPARENT
        /* Check if the receiver has received any error-free status and that we
void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
           have sent at least 15 status control symbols. */
 
        if((stack->rxStatusReceived == 1) && (stack->txStatusCounter < 15u))
{
{
  receiveMessageResponse(stack, destid, srcid, mailbox);
          /* Has not sent enough status control symbols. */
 
          stack->txStatusCounter++;
}
}
#else
        else
void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
 
{
{
  receiveMessageResponse(stack, srcid, srcid, mailbox);
          /* Has sent enough status control symbols. */
 
          /* Dont do anything. */
}
}
#endif
 
 
 
 
 
#ifdef RIO_TRANSPARENT
 
void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
 
{
 
  sendMessageResponse(stack, destid, srcid, mailbox, 0x7u);
 
}
}
#else
      else
void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
 
{
{
  sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x7u);
        /* Idle symbol should be sent. */
 
        s.type = RIOSTACK_SYMBOL_TYPE_IDLE;
 
        stack->txCounter++;
}
}
#endif
 
 
 
 
 
#ifdef RIO_TRANSPARENT
      /* Check if we are ready to set the transmitter in a link initialized state. */
void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
      if ((stack->rxState == RX_STATE_LINK_INITIALIZED) && (stack->txStatusCounter == 15u))
{
{
  receiveMessageResponse(stack, destid, srcid, mailbox);
        /* Ready to go to link initialized. */
 
        stack->txState = TX_STATE_LINK_INITIALIZED;
 
        stack->txFrameState = TX_FRAME_START;
 
        stack->txStatusCounter = 0u;
}
}
#else
      else
void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
 
{
{
  receiveMessageResponse(stack, srcid, srcid, mailbox);
        /* Not ready to go to link initialized. */
 
        /* Dont do anything. */
}
}
#endif
 
 
 
 
      break;
 
 
 
    case TX_STATE_LINK_INITIALIZED:
 
      /******************************************************************************
 
       * LINK_INITIALIZED
 
       * The normal state. Accept packets and forward them. Send acknowledges when
 
       * the receiver has received complete packets.
 
       ******************************************************************************/
 
 
void RIO_portSetStatus( RioStack_t *stack, const uint8_t initialized)
      /* Check if the receiver wants to acknowledge a packet. */
{
      if(stack->rxAckId == stack->rxAckIdAcked)
  /* REMARK: Clean the queues here as well??? */
 
  if (initialized)
 
  {
  {
    stack->rxState = RX_STATE_PORT_INITIALIZED;
        /* The receiver does not want to acknowledge a packet. */
    stack->rxCounter = 0u;
 
    stack->rxCrc = 0xffffu;
 
    stack->rxStatusReceived = 0;
 
    stack->rxAckId = 0u;
 
    stack->rxAckIdAcked = 0u;
 
    stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
 
 
 
    stack->txState = TX_STATE_PORT_INITIALIZED;
        /* Check if there are any outstanding packets and if it has timed out. */
    stack->txCounter = 0u;
        if((stack->txAckId == stack->txAckIdWindow) ||
    stack->txStatusCounter = 0u;
           ((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout))
    stack->txFrameState = TX_FRAME_START;
 
    stack->txAckId = 0u;
 
    stack->txAckIdWindow = 0u;
 
  }
 
  else
 
  {
  {
    stack->rxState = RX_STATE_UNINITIALIZED;
          /* There are no outstanding packets or there has been no timeout. */
    stack->txState = TX_STATE_UNINITIALIZED;
 
  }
 
}
 
 
 
 
          /* Check if a packet is ongoing. */
 
          if(stack->txFrameState == TX_FRAME_BODY)
 
          {
 
            /* A packet transmission is ongoing. */
 
 
void RIO_portSetTime( RioStack_t *stack, const uint32_t time)
            /* Check if the packet has been completly sent. */
 
            if(stack->txCounter != QueueGetSize(stack->txQueue))
{
{
  stack->portTime = time;
              /* The packet has not been completly sent. */
}
 
 
 
 
              /* Create a new data symbol to transmit. */
 
              s.type = RIOSTACK_SYMBOL_TYPE_DATA;
 
              s.data = QueueGetFrontContent(stack->txQueue, (uint32_t)stack->txCounter);
 
 
void RIO_portSetTimeout( RioStack_t *stack, const uint32_t time)
              /* Check if this is the first symbol in a packet. */
 
              if (stack->txCounter == 0u)
{
{
  stack->portTimeout = time;
                /* Place the correct ackId in the right place. */
 
                s.data |= (uint32_t)stack->txAckIdWindow << 27;
 
              }
 
              else
 
              {
 
                /* Dont do anything. */
}
}
 
 
 
              /* Update the transmission counter. */
 
              stack->txCounter++;
 
 
void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s)
              /* A status control symbol was not sent. Update the status counter. */
 
              stack->txStatusCounter++;
 
            }
 
            else
{
{
  uint8_t stype0;
              /* The packet has been sent. */
  uint8_t parameter0;
 
  uint8_t parameter1;
 
  uint8_t stype1;
 
 
 
 
              /* Save the timeout time and update to the next ackId. */
 
              stack->txFrameTimeout[stack->txAckIdWindow] = stack->portTime;
 
              stack->txAckIdWindow = ACKID_INC(stack->txAckIdWindow);
 
              stack->txQueue = QueueWindowNext(stack->txQueue);
 
 
  switch(stack->rxState)
              /* Check if there are more packets pending to be sent. */
 
              /* Also check that there are buffer available at the receiver and that not too many
 
                 packets are outstanding. */
 
              if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
 
                 (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
  {
  {
    case RX_STATE_PORT_INITIALIZED:
                /* More pending packets. */
      /******************************************************************************
                /* Create a control symbol to signal that the new packet has started. */
       * PORT_INITIALIZED
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
       * This state is entered to initialize the link. Only status-control-symbols
                                        STYPE1_START_OF_PACKET, 0u);
       * are accepted in this state. When 7 error-free, i.e. with CRC5 correct, status
 
       * control symbols has been received, change state to linkInitialized.
 
       ******************************************************************************/
 
 
 
      /* Check the type of symbol. */
                /* Restart transmission counter. */
      if(s.type == RIO_SYMBOL_TYPE_CONTROL)
                stack->txCounter = 0;
 
              }
 
              else
      {
      {
        /* This is a control symbol. */
                /* No more pending packets. */
 
                /* Create a control symbol to signal that the packet has ended. */
 
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                        STYPE1_END_OF_PACKET, 0u);
 
 
        /* Check that the control symbol contains no errors. */
                /* Go back to wait for a new frame. */
        if(Crc5(s.data, 0x1fu) == (s.data & 0x1ful))
                stack->txFrameState = TX_FRAME_START;
        {
              }
          /* Error-free control symbol. */
 
 
 
          /* Check if the symbol is a status symbol. */
              /* A status control symbol has been sent. Reset the status counter. */
          stype0 = STYPE0_GET(s.data);
              stack->txStatusCounter = 0u;
          if(stype0 == STYPE0_STATUS)
            }
 
          }
 
          else
          {
          {
            /* Status symbol received. */
            /* No packet is being sent. */
 
 
            /* Indicate an error-free status has been received. */
            /* Check if there are any pending packets to start sending. */
            stack->rxStatusReceived = 1;
            /* Also check that there are buffer available at the receiver and that not too many
 
               packets are outstanding. */
 
            if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
 
               (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
 
            {
 
              /* There is a pending packet to send. */
 
              /* Send a start-of-packet control symbol to start to send the packet. */
 
              s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                      STYPE1_START_OF_PACKET, 0u);
 
              stack->txFrameState = TX_FRAME_BODY;
 
              stack->txCounter = 0u;
 
 
            /* Check if enough status control symbols has been received. */
              /* A status control symbol has been sent. Reset the status counter. */
            if(stack->rxCounter == 7u)
              stack->txStatusCounter = 0u;
 
            }
 
            else
            {
            {
              /* Enough correct status control symbols has been received without
              /* There are no pending packets to send. */
                 errors in between. */
 
 
 
              /* Setup the transmitter with the content of the symbol. */
              /* Check if a status control symbol must be transmitted. */
              stack->txAckId = PARAMETER0_GET(s.data);
              if(stack->txStatusCounter < 255u)
              stack->txAckIdWindow = stack->txAckId;
              {
              stack->txBufferStatus = PARAMETER1_GET(s.data);
                /* Not required to send a status control symbol. */
 
 
              /* Set the transmitter in its normal operational mode. */
                /* Send an idle-symbol. */
              stack->rxState = RX_STATE_LINK_INITIALIZED;
                s.type = RIOSTACK_SYMBOL_TYPE_IDLE;
              stack->rxCounter = 0u;
                stack->txStatusCounter++;
              DEBUG_STATE("rx:normal");
 
            }
            }
            else
            else
            {
            {
              /* Count the number of consequitive error-free status control symbols
                /* Must send a status control symbol. */
                 that has been received. */
 
              stack->rxCounter++;
                /* Create a status control symbol. */
 
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                        STYPE1_NOP, 0u);
 
 
 
                /* A status control symbol has been sent. Reset the status counter. */
 
                stack->txStatusCounter = 0u;
            }
            }
          }
          }
          else
 
          {
 
            /* The received symbol is not a status symbol. */
 
            /* Discard it. */
 
          }
          }
        }
        }
        else
        else
        {
        {
          /* CRC error in control symbol. */
          /* There has been a timeout. */
          /* Restart counting error-free status-control-symbols. */
          /* A packet has been sent but no packet-accepted has been received. */
          stack->rxCounter = 0u;
          /* Send link-request-symbol (input-status). */
 
          s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                  STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
 
 
          /* Save the time when this was transmitted. */
 
          stack->txFrameTimeout[stack->txAckId] = stack->portTime;
 
 
 
          /* Remember that this symbol has been transmitted. */
 
          stack->txCounter = 1;
 
 
 
          /* Go into the output error stopped state. */
 
          stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
 
          stack->statusOutboundErrorTimeout++;
        }
        }
      }
      }
      else
      else
      {
      {
        /* Not a control symbol. */
        /* The receiver wants us to send an acknowledgement. */
        /* Discard the symbol. */
        s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
      }
                                STYPE1_NOP, 0u);
 
        stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
 
 
 
        /* A status control symbol was not sent. Update the status counter. */
 
        stack->txStatusCounter++;
 
      }
      break;
      break;
 
 
    case RX_STATE_LINK_INITIALIZED:
    case TX_STATE_SEND_PACKET_RETRY:
      /******************************************************************************
      /******************************************************************************
       * LINK_INITIALIZED
       * SEND_PACKET_RETRY
       * The normal state. Accept packets and forward them.
       * This state is set by the receiver to force a packet-retry-symbol to be
 
       * transmitted.
       ******************************************************************************/
       ******************************************************************************/
 
 
      /* Check the type of symbol. */
      /* Check if the receiver wants to acknowledge a packet. */
      switch(s.type)
      /* This must be done first or we will get an error for a missmatching
 
         ackId in the link-partner. */
 
      if(stack->rxAckId == stack->rxAckIdAcked)
      {
      {
        case RIO_SYMBOL_TYPE_CONTROL:
        /* No pending acknowledge. */
          /**************************************************************************
 
           * This is a control symbol.
 
           **************************************************************************/
 
 
 
          /* Check if the CRC is correct. */
        /* Send a packet-retry symbol to tell the link partner to retry the last frame. */
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
        s = CreateControlSymbol(STYPE0_PACKET_RETRY, stack->rxAckId, QueueAvailable(stack->rxQueue),
          {
                                STYPE1_NOP, 0u);
            /* The CRC is correct. */
 
 
 
            /* Get the content of the control symbol. */
        /* Proceed with normal transmission. */
            stype0 = STYPE0_GET(s.data);
        stack->txState = TX_STATE_LINK_INITIALIZED;
            parameter0 = PARAMETER0_GET(s.data);
 
            parameter1 = PARAMETER1_GET(s.data);
 
            stype1 = STYPE1_GET(s.data);
 
 
 
            /**********************************************************************************
        /* A status control symbol was not sent. Update the status counter. */
             * Check the stype0 part of the symbol.
        stack->txStatusCounter++;
             * Note that errors in this should trigger OUTPUT_ERROR_STOPPED.
      }
             **********************************************************************************/
      else
            switch(stype0)
 
            {
            {
              case STYPE0_STATUS:
 
                /* A status containing the current ackId and the buffer status has been
 
                   received. */
 
                handleStatus(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_ACCEPTED:
 
                /* A packet has been accepted by the link partner. */
 
                handlePacketAccepted(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_RETRY:
 
                /* The link partner wants us to initiate a restart of the received ackId. */
 
                handlePacketRetry(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_NOT_ACCEPTED:
        /* The receiver wants us to send an acknowledgement. */
                /* The link partner indicates that a packet has been rejected. */
        s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
                handlePacketNotAccepted(stack, parameter0, parameter1);
                                STYPE1_NOP, 0u);
                break;
        stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
 
 
              case STYPE0_LINK_RESPONSE:
 
                /* The link partner has sent a response to a link-request. */
 
                handleLinkResponse(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_VC_STATUS:
        /* A status control symbol was not sent. Update the status counter. */
              case STYPE0_RESERVED:
        stack->txStatusCounter++;
              case STYPE0_IMPLEMENTATION_DEFINED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
 
                break;
 
            }
            }
 
 
            /**********************************************************************************
 
             * Check the stype1 part of the symbol.
 
             * Note that errors in this should trigger INPUT_ERROR_STOPPED.
 
             **********************************************************************************/
 
            switch(stype1)
 
            {
 
              case STYPE1_START_OF_PACKET:
 
                /* Start of a new packet. */
 
                handleStartOfPacket(stack);
 
                break;
                break;
 
 
              case STYPE1_END_OF_PACKET:
    case TX_STATE_SEND_PACKET_NOT_ACCEPTED:
                /* Ending a packet. */
      /******************************************************************************
                handleEndOfPacket(stack);
       * SEND_PACKET_NOT_ACCEPTED
                break;
       * This state is set by the receiver to force a packet-not-accepted-symbol to be
 
       * transmitted.
 
       ******************************************************************************/
 
 
              case STYPE1_STOMP:
      /* Send a packet-not-accepted symbol to indicate an error on the link. */
                /* Cancel the currently received frame. */
      s = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, stack->rxErrorCause,
                stack->rxCounter = 0;
                              STYPE1_NOP, 0u);
                break;
 
 
 
              case STYPE1_RESTART_FROM_RETRY:
      /* Proceed with normal transmission. */
                /* Cancel the currently received frame when in this state. */
      stack->txState = TX_STATE_LINK_INITIALIZED;
                stack->rxCounter = 0;
 
                break;
 
 
 
              case STYPE1_LINK_REQUEST:
      /* A status control symbol was not sent. Update the status counter. */
                /* A link-request has been received. */
      stack->txStatusCounter++;
                handleLinkRequest(stack, CMD_GET(s.data));
 
                break;
                break;
 
 
              case STYPE1_NOP:
    case TX_STATE_SEND_LINK_RESPONSE:
                /* No operation symbol. */
      /******************************************************************************
                /* Discard these. */
       * SEND_LINK_RESPONSE
                break;
       * This state is set by the receiver to force a link-response-symbol to be
 
       * transmitted.
 
       ******************************************************************************/
 
 
              case STYPE1_MULTICAST_EVENT:
      /* Check the state of the receiver. */
              case STYPE1_RESERVED:
      /* REMARK: If a link-request gives this response and a link-request also makes the receiver
              default:
         enter the normal operational state, none of these states except the normal state will ever
                /* Unsupported symbol received. */
         be used... */
                /* Discard them. */
      if((stack->rxState == RX_STATE_LINK_INITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED))
                break;
 
            }
 
          }
 
          else
 
          {
          {
            /* The control symbol CRC is incorrect. */
        /* Normal state. */
            /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_OK,
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
                                STYPE1_NOP, 0u);
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
 
            stack->statusInboundErrorControlCrc++;
 
            DEBUG_STATE("rx:error-stopped");
 
          }
          }
          break;
      else if(stack->rxState == RX_STATE_INPUT_RETRY_STOPPED)
 
 
        case RIO_SYMBOL_TYPE_DATA:
 
          /**************************************************************************
 
           * This is a data symbol.
 
           **************************************************************************/
 
 
 
          /* Check if a packet has been started and that it is not too long. */
 
          if ((stack->rxCounter >= 1u) && (stack->rxCounter <= RIO_PACKET_SIZE))
 
          {
 
            /* A packet has been started. */
 
 
 
            /* Check if the ackId is correct on the first part of the packet. */
 
            if ((stack->rxCounter > 1u) ||
 
                ((stack->rxCounter == 1u) && (((uint8_t)(s.data >> 27)) == stack->rxAckId)))
 
            {
            {
              /* The ackId is the expected one. */
        /* Input-retry-stopped state. */
 
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED,
              /* Check if this is the first symbol of a packet. */
                                STYPE1_NOP, 0u);
              if (stack->rxCounter == 1u)
      }
 
      else if(stack->rxState == RX_STATE_INPUT_ERROR_STOPPED)
              {
              {
                /* This is the first symbol of the packet. */
        /* Input-error-stopped state. */
                /* Start to calculate the CRC of the packet. */
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED,
                /* Note that the ackId should not be included in the CRC calculation. */
                                STYPE1_NOP, 0u);
                stack->rxCrc = Crc32(s.data & (uint32_t)0x03fffffful, 0xffffu);
 
              }
              }
              else
              else
              {
              {
                /* This is not the first symbol. */
        /* Not in the defined states. */
                /* Continue to calculate the CRC of the packet. */
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR,
                stack->rxCrc = Crc32(s.data, stack->rxCrc);
                                STYPE1_NOP, 0u);
              }
              }
 
 
              /* Save the new data in the packet queue and update the reception counter. */
      /* Proceed with normal transmission. */
              QueueSetContent(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul, s.data);
      stack->txState = TX_STATE_LINK_INITIALIZED;
              stack->rxCounter++;
 
            }
 
            else
 
            {
 
              DEBUG_FRAMING_RX("error=%u %u", stack->rxAckId, s.data>>27);
 
 
 
              /* The ackId is not correct. */
      /* Force a status to be transmitted the next time to comply to the input-error-stopped
              /* Packet error. Enter input-error-stopped state. */
         state rules. */
              stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
      stack->txStatusCounter = 255;
              stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
              stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
 
              stack->statusInboundErrorPacketAckId++;
 
              DEBUG_STATE("rx:error-stopped");
 
            }
 
          }
 
          else
 
          {
 
            /* No packet has been started or the packet is too long. */
 
            /* Packet error. Enter input-error-stopped state. */
 
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
 
            stack->statusInboundErrorGeneral++;
 
            DEBUG_STATE("rx:error-stopped");
 
          }
 
          break;
          break;
 
 
        case RIO_SYMBOL_TYPE_ERROR:
    case TX_STATE_OUTPUT_RETRY_STOPPED:
          /**************************************************************************
      /******************************************************************************
           * The decoder has received a erronous symbol.
       * OUTPUT_RETRY_STOPPED
           **************************************************************************/
       * This state is entered when the link-partner has transmitted a
 
       * packet-retry-symbol. The packet-retry-symbol is acknowledged by sending a
 
       * restart-from-retry-symbol.
 
       * This state follows 5.9.1.5 in part 6.
 
       ******************************************************************************/
 
 
          /* Idle symbol error. Place the receiver in input-error-stopped state. */
      /* Send a restart-from-retry symbol to acknowledge. */
          stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
      s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
          stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
                              STYPE1_RESTART_FROM_RETRY, 0u);
          stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
 
          stack->statusInboundErrorIllegalCharacter++;
 
          DEBUG_STATE("rx:error-stopped");
 
          break;
 
 
 
        case RIO_SYMBOL_TYPE_IDLE:
      /* Restart the current frame and proceed with normal operation. */
        default:
      stack->txFrameState = TX_FRAME_START;
          /**************************************************************************
      stack->txState = TX_STATE_LINK_INITIALIZED;
           * Idle symbol or unsupported symbol.
      stack->txCounter = 0;
           **************************************************************************/
 
 
 
          /* Discard these for now. */
      /* Discard all packets that has not received a matching packet-accepted. */
          break;
      stack->txAckIdWindow = stack->txAckId;
      }
      stack->txQueue = QueueWindowReset(stack->txQueue);
 
 
 
      /* A status control symbol was sent. Reset the status counter. */
 
      stack->txStatusCounter = 0;
      break;
      break;
 
 
    case RX_STATE_INPUT_RETRY_STOPPED:
    case TX_STATE_OUTPUT_ERROR_STOPPED:
      /******************************************************************************
      /******************************************************************************
       * INPUT_RETRY_STOPPED
       * OUTPUT_ERROR_STOPPED
       * This state is entered when no more buffers was available and a packet was
       * This state is entered when the link partner has encountered any problem
       * received. When in this state, all packets should be discarded until a
       * which is indicated by sending a packet-not-accepted symbol or if a packet
       * RESTART-FROM-RETRY symbol is received. See section 5.9.1.4 of the standard.
       * timeout has expired. The error condition is acknowledged by sending a
       * Note that it is only the input side of the port that are affected, not the
       * link-request-symbol and then wait for a link-response reply.
       * output side. Packets may still be transmitted and acknowledges should be
       * This state follows 5.13.2.7 in part 6.
       * accepted.
 
       ******************************************************************************/
       ******************************************************************************/
 
 
      /* Check the type of symbol. */
      /* Check if a link-request-symbol has been transmitted. */
      switch(s.type)
      if(stack->txCounter == 0)
      {
      {
        case RIO_SYMBOL_TYPE_CONTROL:
        /* A link-request-symbol has not been transmitted. */
          /* This is a control symbol. */
 
 
 
          /* Check if the CRC is correct. */
        /* Send link-request-symbol (input-status). */
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
        s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
          {
                                STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
            /* The CRC is correct. */
 
 
 
            /* Get the content of the control symbol. */
 
            stype0 = STYPE0_GET(s.data);
 
            parameter0 = PARAMETER0_GET(s.data);
 
            parameter1 = PARAMETER1_GET(s.data);
 
            stype1 = STYPE1_GET(s.data);
 
 
 
            /* Check the stype0 part of the symbol. */
 
            switch(stype0)
 
            {
 
              case STYPE0_STATUS:
 
                /* A status containing the current ackId and the buffer status has been
 
                   received. */
 
                handleStatus(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_ACCEPTED:
 
                /* A packet has been accepted by the link partner. */
 
                handlePacketAccepted(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_RETRY:
 
                /* The link partner wants us to initiate a restart of the received ackId. */
 
                handlePacketRetry(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_NOT_ACCEPTED:
 
                /* The link partner indicates that a packet has been rejected. */
 
                handlePacketNotAccepted(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_LINK_RESPONSE:
 
                /* The link partner has sent a response to a link-request. */
 
                handleLinkResponse(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_VC_STATUS:
 
              case STYPE0_RESERVED:
 
              case STYPE0_IMPLEMENTATION_DEFINED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
 
                break;
 
            }
 
 
 
            /* Check the stype1 part of the symbol. */
 
            switch(stype1)
 
            {
 
              case STYPE1_START_OF_PACKET:
 
                /* Starting new frames are ignored in this state. */
 
                break;
 
 
 
              case STYPE1_END_OF_PACKET:
 
                /* Ending new frames are ignored in this state. */
 
                break;
 
 
 
              case STYPE1_STOMP:
 
                /* Restarting frames are ignored in this state. */
 
                break;
 
 
 
              case STYPE1_RESTART_FROM_RETRY:
 
                /* The link partner has confirmed our packet-retry-symbol. */
 
                /* Go back to the normal state and reset the frame reception. */
 
                stack->rxState = RX_STATE_LINK_INITIALIZED;
 
                stack->rxCounter = 0u;
 
                DEBUG_STATE("rx:normal(restart)");
 
                break;
 
 
 
              case STYPE1_LINK_REQUEST:
 
                /* A link-request has been received. */
 
                handleLinkRequest(stack, CMD_GET(s.data));
 
                stack->rxState = RX_STATE_LINK_INITIALIZED;
 
                DEBUG_STATE("rx:normal(link-req)");
 
                break;
 
 
 
              case STYPE1_NOP:
 
                /* No operation symbol. */
 
                /* Discard these. */
 
                break;
 
 
 
              case STYPE1_MULTICAST_EVENT:
 
              case STYPE1_RESERVED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
 
                break;
 
            }
 
          }
 
          else
 
          {
 
            /* The control symbol CRC is incorrect. */
 
            /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
 
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
 
            stack->statusInboundErrorControlCrc++;
 
            DEBUG_STATE("rx:error-stopped");
 
          }
 
          break;
 
 
 
        case RIO_SYMBOL_TYPE_ERROR:
 
          /* Idle symbol error. Place the receiver in input-error-stopped state. */
 
          stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
          stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
          stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
 
          stack->statusInboundErrorIllegalCharacter++;
 
          DEBUG_STATE("rx:error-stopped");
 
          break;
 
 
 
        case RIO_SYMBOL_TYPE_DATA:
 
        case RIO_SYMBOL_TYPE_IDLE:
 
        default:
 
          /* Data or idle symbol. */
 
          /* Discard these in this state. */
 
          break;
 
      }
 
      break;
 
 
 
    case RX_STATE_INPUT_ERROR_STOPPED:
 
      /******************************************************************************
 
       * INPUT_ERROR_STOPPED
 
       * This state is entered when an error situation has occurred. When in this
 
       * state, all symbols should be discarded until a link-request-symbols has
 
       * been received. See section 5.13.2.6 in part 6 of the standard.
 
       * Note that it is only the input side of the port that are affected, not the
 
       * output side. Packets may still be transmitted and acknowledges should be
 
       * accepted.
 
       ******************************************************************************/
 
 
 
      /* Check the type of symbol. */
 
      switch(s.type)
 
      {
 
        case RIO_SYMBOL_TYPE_CONTROL:
 
          /* This is a control symbol. */
 
 
 
          /* Check if the CRC is correct. */
 
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
 
          {
 
            /* The CRC is correct. */
 
 
 
            /* Get the content of the control symbol. */
 
            stype0 = STYPE0_GET(s.data);
 
            parameter0 = PARAMETER0_GET(s.data);
 
            parameter1 = PARAMETER1_GET(s.data);
 
            stype1 = STYPE1_GET(s.data);
 
 
 
            /* Check the stype0 part of the symbol. */
 
            switch(stype0)
 
            {
 
              case STYPE0_STATUS:
 
                /* A status containing the current ackId and the buffer status has been
 
                   received. */
 
                handleStatus(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_ACCEPTED:
 
                /* A packet has been accepted by the link partner. */
 
                handlePacketAccepted(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_RETRY:
 
                /* The link partner wants us to initiate a restart of the received ackId. */
 
                handlePacketRetry(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_PACKET_NOT_ACCEPTED:
 
                /* The link partner indicates that a packet has been rejected. */
 
                handlePacketNotAccepted(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_LINK_RESPONSE:
 
                /* The link partner has sent a response to a link-request. */
 
                handleLinkResponse(stack, parameter0, parameter1);
 
                break;
 
 
 
              case STYPE0_VC_STATUS:
 
              case STYPE0_RESERVED:
 
              case STYPE0_IMPLEMENTATION_DEFINED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
 
                break;
 
            }
 
 
 
            /* Check the stype1 part of the symbol. */
 
            switch(stype1)
 
            {
 
              case STYPE1_START_OF_PACKET:
 
                /* Starting new frames are ignored in this state. */
 
                break;
 
 
 
              case STYPE1_END_OF_PACKET:
 
                /* Ending new frames are ignored in this state. */
 
                break;
 
 
 
              case STYPE1_STOMP:
 
                /* Restarting frames are ignored in this state. */
 
                break;
 
 
 
              case STYPE1_RESTART_FROM_RETRY:
 
                /* Restart-from-retry are ignored in this state.  */
 
                break;
 
 
 
              case STYPE1_LINK_REQUEST:
 
                /* This is the symbol we have been waiting for. */
 
                /* Force the transmitter to send a link-response and go back into the normal
 
                   operational state. */
 
                /* The transmitter will always send a status as the first symbol after this. */
 
                handleLinkRequest(stack, CMD_GET(s.data));
 
                stack->rxState = RX_STATE_LINK_INITIALIZED;
 
                DEBUG_STATE("rx:normal(link-req)");
 
                break;
 
 
 
              case STYPE1_NOP:
 
                /* No operation symbol. */
 
                /* Discard these. */
 
                break;
 
 
 
              case STYPE1_MULTICAST_EVENT:
 
              case STYPE1_RESERVED:
 
              default:
 
                /* Unsupported symbol received. */
 
                /* Discard them. */
 
                break;
 
            }
 
          }
 
          else
 
          {
 
            /* The CRC is incorrect. */
 
            /* Discard these in this state. */
 
          }
 
          break;
 
 
 
        case RIO_SYMBOL_TYPE_DATA:
 
        case RIO_SYMBOL_TYPE_IDLE:
 
        case RIO_SYMBOL_TYPE_ERROR:
 
        default:
 
          /* Data, idle or error symbol. */
 
          /* Discard these in this state. */
 
          break;
 
      }
 
      break;
 
 
 
    case RX_STATE_UNINITIALIZED:
 
    default:
 
      /******************************************************************************
 
       * Wait for the port to be initialized.
 
       ******************************************************************************/
 
 
 
      /* Discard all incoming symbols. */
 
      break;
 
  }
 
}
 
 
 
 
 
 
 
RioSymbol RIO_portGetSymbol( RioStack_t *stack )
 
{
 
  RioSymbol s;
 
 
 
 
 
  switch(stack->txState)
 
  {
 
    case TX_STATE_PORT_INITIALIZED:
 
      /******************************************************************************
 
       * PORT_INITIALIZED
 
       * This state is entered to initialize the link. Send status-control-symbols
 
       * once in a while until the receiver has received enough error-free status-
 
       * control-symbols and we have transmitted enough status-control-symbols. Once
 
       * an error-free status-control-symbol has been received, the statuses are
 
       * transmitted more frequently to decrease the time for the link to be
 
       * initialized.
 
       ******************************************************************************/
 
 
 
      /* Check if an idle symbol or a status control symbol should be sent. */
 
      if(((stack->rxStatusReceived == 0) && (stack->txCounter == 255u)) ||
 
         ((stack->rxStatusReceived == 1) && (stack->txCounter >= 15u)))
 
      {
 
        /* A control symbol should be sent. */
 
 
 
        /* Create a new status symbol and reset the transmission counter. */
 
        stack->txCounter = 0u;
 
        s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                STYPE1_NOP, 0u);
 
 
 
        /* Check if the receiver has received any error-free status and that we
 
           have sent at least 15 status control symbols. */
 
        if((stack->rxStatusReceived == 1) && (stack->txStatusCounter < 15u))
 
        {
 
          /* Has not sent enough status control symbols. */
 
          stack->txStatusCounter++;
 
        }
 
        else
 
        {
 
          /* Has sent enough status control symbols. */
 
          /* Dont do anything. */
 
        }
 
      }
 
      else
 
      {
 
        /* Idle symbol should be sent. */
 
        s.type = RIO_SYMBOL_TYPE_IDLE;
 
        stack->txCounter++;
 
      }
 
 
 
      /* Check if we are ready to set the transmitter in a link initialized state. */
 
      if ((stack->rxState == RX_STATE_LINK_INITIALIZED) && (stack->txStatusCounter == 15u))
 
      {
 
        /* Ready to go to link initialized. */
 
        stack->txState = TX_STATE_LINK_INITIALIZED;
 
        stack->txFrameState = TX_FRAME_START;
 
        stack->txStatusCounter = 0u;
 
        DEBUG_STATE("tx:normal");
 
      }
 
      else
 
      {
 
        /* Not ready to go to link initialized. */
 
        /* Dont do anything. */
 
      }
 
 
 
      break;
 
 
 
    case TX_STATE_LINK_INITIALIZED:
 
      /******************************************************************************
 
       * LINK_INITIALIZED
 
       * The normal state. Accept packets and forward them. Send acknowledges when
 
       * the receiver has received complete packets.
 
       ******************************************************************************/
 
 
 
      /* Check if the receiver wants to acknowledge a packet. */
 
      if(stack->rxAckId == stack->rxAckIdAcked)
 
      {
 
        /* The receiver does not want to acknowledge a packet. */
 
 
 
        /* Check if there are any outstanding packets and if it has timed out. */
 
        if((stack->txAckId == stack->txAckIdWindow) ||
 
           ((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout))
 
        {
 
          /* There are no outstanding packets or there has been no timeout. */
 
 
 
          /* Check if a packet is ongoing. */
 
          if(stack->txFrameState == TX_FRAME_BODY)
 
          {
 
            /* A packet transmission is ongoing. */
 
 
 
            /* Check if the packet has been completly sent. */
 
            if(stack->txCounter != QueueGetFrontSize(stack->txQueue))
 
            {
 
              /* The packet has not been completly sent. */
 
 
 
              /* Create a new data symbol to transmit. */
 
              s.type = RIO_SYMBOL_TYPE_DATA;
 
              s.data = QueueGetFrontContent(stack->txQueue, (uint32_t)stack->txCounter);
 
 
 
              /* Check if this is the first symbol in a packet. */
 
              if (stack->txCounter == 0u)
 
              {
 
                /* Place the correct ackId in the right place. */
 
                s.data |= (uint32_t)stack->txAckIdWindow << 27;
 
              }
 
              else
 
              {
 
                /* Dont do anything. */
 
              }
 
 
 
              /* Update the transmission counter. */
 
              stack->txCounter++;
 
 
 
              /* A status control symbol was not sent. Update the status counter. */
 
              stack->txStatusCounter++;
 
            }
 
            else
 
            {
 
              /* The packet has been sent. */
 
 
 
              /* Save the timeout time and update to the next ackId. */
 
              stack->txFrameTimeout[stack->txAckIdWindow] = stack->portTime;
 
              stack->txAckIdWindow = ACKID_INC(stack->txAckIdWindow);
 
              stack->txQueue = QueueWindowNext(stack->txQueue);
 
 
 
              /* Check if there are more packets pending to be sent. */
 
              /* Also check that there are buffer available at the receiver and that not too many
 
                 packets are outstanding. */
 
              if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
 
                 (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
 
              {
 
                /* More pending packets. */
 
                DEBUG_FRAMING_TX("cont=%i", stack->txAckIdWindow);
 
                /* Create a control symbol to signal that the new packet has started. */
 
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                        STYPE1_START_OF_PACKET, 0u);
 
 
 
                /* Restart transmission counter. */
 
                stack->txCounter = 0;
 
              }
 
              else
 
              {
 
                /* No more pending packets. */
 
                DEBUG_FRAMING_TX("end=%i", stack->txAckIdWindow);
 
                /* Create a control symbol to signal that the packet has ended. */
 
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                        STYPE1_END_OF_PACKET, 0u);
 
 
 
                /* Go back to wait for a new frame. */
 
                stack->txFrameState = TX_FRAME_START;
 
              }
 
 
 
              /* A status control symbol has been sent. Reset the status counter. */
 
              stack->txStatusCounter = 0u;
 
            }
 
          }
 
          else
 
          {
 
            /* No packet is being sent. */
 
 
 
            /* Check if there are any pending packets to start sending. */
 
            /* Also check that there are buffer available at the receiver and that not too many
 
               packets are outstanding. */
 
            if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
 
               (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
 
            {
 
              /* There is a pending packet to send. */
 
              DEBUG_FRAMING_TX("start=%i", stack->txAckIdWindow);
 
              /* Send a start-of-packet control symbol to start to send the packet. */
 
              s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                      STYPE1_START_OF_PACKET, 0u);
 
              stack->txFrameState = TX_FRAME_BODY;
 
              stack->txCounter = 0u;
 
 
 
              /* A status control symbol has been sent. Reset the status counter. */
 
              stack->txStatusCounter = 0u;
 
            }
 
            else
 
            {
 
              /* There are no pending packets to send. */
 
 
 
              /* Check if a status control symbol must be transmitted. */
 
              if(stack->txStatusCounter < 255u)
 
              {
 
                /* Not required to send a status control symbol. */
 
 
 
                /* Send an idle-symbol. */
 
                s.type = RIO_SYMBOL_TYPE_IDLE;
 
                stack->txStatusCounter++;
 
              }
 
              else
 
              {
 
                /* Must send a status control symbol. */
 
 
 
                /* Create a status control symbol. */
 
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                        STYPE1_NOP, 0u);
 
 
 
                /* A status control symbol has been sent. Reset the status counter. */
 
                stack->txStatusCounter = 0u;
 
              }
 
            }
 
          }
 
        }
 
        else
 
        {
 
          /* There has been a timeout. */
 
          /* A packet has been sent but no packet-accepted has been received. */
 
          DEBUG_FRAMING_TX("timeout=%i", stack->txAckId);
 
          /* Send link-request-symbol (input-status). */
 
          s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                  STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
 
 
          /* Save the time when this was transmitted. */
 
          stack->txFrameTimeout[stack->txAckId] = stack->portTime;
 
 
 
          /* Remember that this symbol has been transmitted. */
 
          stack->txCounter = 1;
 
 
 
          /* Go into the output error stopped state. */
 
          stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
 
          stack->statusOutboundErrorTimeout++;
 
          DEBUG_STATE("tx:error-stopped");
 
        }
 
      }
 
      else
 
      {
 
        /* The receiver wants us to send an acknowledgement. */
 
        s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
 
                                STYPE1_NOP, 0u);
 
        stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
 
 
 
        /* A status control symbol was not sent. Update the status counter. */
 
        stack->txStatusCounter++;
 
      }
 
      break;
 
 
 
    case TX_STATE_SEND_PACKET_RETRY:
 
      /******************************************************************************
 
       * SEND_PACKET_RETRY
 
       * This state is set by the receiver to force a packet-retry-symbol to be
 
       * transmitted.
 
       ******************************************************************************/
 
 
 
      /* Check if the receiver wants to acknowledge a packet. */
 
      /* This must be done first or we will get an error for a missmatching
 
         ackId in the link-partner. */
 
      if(stack->rxAckId == stack->rxAckIdAcked)
 
      {
 
        /* No pending acknowledge. */
 
 
 
        /* Send a packet-retry symbol to tell the link partner to retry the last frame. */
 
        s = CreateControlSymbol(STYPE0_PACKET_RETRY, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                STYPE1_NOP, 0u);
 
 
 
        /* Proceed with normal transmission. */
 
        stack->txState = TX_STATE_LINK_INITIALIZED;
 
 
 
        /* A status control symbol was not sent. Update the status counter. */
 
        stack->txStatusCounter++;
 
      }
 
      else
 
      {
 
 
 
        /* The receiver wants us to send an acknowledgement. */
 
        s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
 
                                STYPE1_NOP, 0u);
 
        stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
 
 
 
        /* A status control symbol was not sent. Update the status counter. */
 
        stack->txStatusCounter++;
 
      }
 
      break;
 
 
 
    case TX_STATE_SEND_PACKET_NOT_ACCEPTED:
 
      /******************************************************************************
 
       * SEND_PACKET_NOT_ACCEPTED
 
       * This state is set by the receiver to force a packet-not-accepted-symbol to be
 
       * transmitted.
 
       ******************************************************************************/
 
 
 
      /* Send a packet-not-accepted symbol to indicate an error on the link. */
 
      s = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, stack->rxErrorCause,
 
                              STYPE1_NOP, 0u);
 
 
 
      /* Proceed with normal transmission. */
 
      stack->txState = TX_STATE_LINK_INITIALIZED;
 
 
 
      /* A status control symbol was not sent. Update the status counter. */
 
      stack->txStatusCounter++;
 
      break;
 
 
 
    case TX_STATE_SEND_LINK_RESPONSE:
 
      /******************************************************************************
 
       * SEND_LINK_RESPONSE
 
       * This state is set by the receiver to force a link-response-symbol to be
 
       * transmitted.
 
       ******************************************************************************/
 
 
 
      DEBUG_FRAMING_RX("link-res:%u", stack->rxAckId);
 
 
 
      /* Check the state of the receiver. */
 
      /* REMARK: If a link-request gives this response and a link-request also makes the receiver
 
         enter the normal operational state, none of these states except the normal state will ever
 
         be used... */
 
      if((stack->rxState == RX_STATE_LINK_INITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED))
 
      {
 
        /* Normal state. */
 
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_OK,
 
                                STYPE1_NOP, 0u);
 
      }
 
      else if(stack->rxState == RX_STATE_INPUT_RETRY_STOPPED)
 
      {
 
        /* Input-retry-stopped state. */
 
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED,
 
                                STYPE1_NOP, 0u);
 
      }
 
      else if(stack->rxState == RX_STATE_INPUT_ERROR_STOPPED)
 
      {
 
        /* Input-error-stopped state. */
 
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED,
 
                                STYPE1_NOP, 0u);
 
      }
 
      else
 
      {
 
        /* Not in the defined states. */
 
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR,
 
                                STYPE1_NOP, 0u);
 
      }
 
 
 
      /* Proceed with normal transmission. */
 
      stack->txState = TX_STATE_LINK_INITIALIZED;
 
 
 
      /* Force a status to be transmitted the next time to comply to the input-error-stopped
 
         state rules. */
 
      stack->txStatusCounter = 255;
 
      break;
 
 
 
    case TX_STATE_OUTPUT_RETRY_STOPPED:
 
      /******************************************************************************
 
       * OUTPUT_RETRY_STOPPED
 
       * This state is entered when the link-partner has transmitted a
 
       * packet-retry-symbol. The packet-retry-symbol is acknowledged by sending a
 
       * restart-from-retry-symbol.
 
       * This state follows 5.9.1.5 in part 6.
 
       ******************************************************************************/
 
 
 
      /* Send a restart-from-retry symbol to acknowledge. */
 
      s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                              STYPE1_RESTART_FROM_RETRY, 0u);
 
 
 
      /* Restart the current frame and proceed with normal operation. */
 
      stack->txFrameState = TX_FRAME_START;
 
      stack->txState = TX_STATE_LINK_INITIALIZED;
 
      stack->txCounter = 0;
 
      DEBUG_STATE("tx:normal");
 
 
 
      /* Discard all packets that has not received a matching packet-accepted. */
 
      stack->txAckIdWindow = stack->txAckId;
 
      stack->txQueue = QueueWindowReset(stack->txQueue);
 
 
 
      /* A status control symbol was sent. Reset the status counter. */
 
      stack->txStatusCounter = 0;
 
      break;
 
 
 
    case TX_STATE_OUTPUT_ERROR_STOPPED:
 
      /******************************************************************************
 
       * OUTPUT_ERROR_STOPPED
 
       * This state is entered when the link partner has encountered any problem
 
       * which is indicated by sending a packet-not-accepted symbol or if a packet
 
       * timeout has expired. The error condition is acknowledged by sending a
 
       * link-request-symbol and then wait for a link-response reply.
 
       * This state follows 5.13.2.7 in part 6.
 
       ******************************************************************************/
 
 
 
      /* Check if a link-request-symbol has been transmitted. */
 
      if(stack->txCounter == 0)
 
      {
 
        /* A link-request-symbol has not been transmitted. */
 
 
 
        /* Send link-request-symbol (input-status). */
 
        s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
 
 
        /* Save the time when this was transmitted. */
 
        stack->txFrameTimeout[stack->txAckId] = stack->portTime;
 
 
 
        /* Remember that this symbol has been transmitted. */
 
        stack->txCounter = 1;
 
      }
 
      else
 
      {
 
        /* A link-request-symbol has been transmitted. */
 
 
 
        /* Check if the link partner reply has timed out. */
 
        if((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout)
 
        {
 
          /* No timeout. */
 
 
 
          /* A link-request-symbol has been transmitted. */
 
          /* Send only idle-symbols until the link-response is received. */
 
          s.type = RIO_SYMBOL_TYPE_IDLE;
 
        }
 
        else
 
        {
 
          /* Link response timeout. */
 
 
 
          /* Check if the link-partner has not responded for too many times. */
 
          if(stack->txCounter < 5)
 
          {
 
            /* Not too many timeouts. */
 
            /* Retry and send a new link-request. */
 
 
 
            /* Send link-request-symbol (input-status). */
 
            s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
 
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
 
 
            /* Save the time when this was transmitted. */
 
            stack->txFrameTimeout[stack->txAckId] = stack->portTime;
 
 
 
            /* Increment the number of times we have retransmitted the link-request. */
 
            stack->txCounter++;
 
          }
 
          else
 
          {
 
            /* The link partner has not answered for too many times. */
 
            /* Give up and set the state to uninitialized. */
 
            stack->txState = TX_STATE_UNINITIALIZED;
 
            s.type = RIO_SYMBOL_TYPE_IDLE;
 
            ASSERT0("No link-response received, giving up.");
 
          }
 
        }
 
      }
 
      break;
 
 
 
    case TX_STATE_UNINITIALIZED:
 
    default:
 
      /******************************************************************************
 
       * Wait for the port to be initialized.
 
       ******************************************************************************/
 
 
 
      /* Send only idle symbols. */
 
      s.type = RIO_SYMBOL_TYPE_IDLE;
 
      break;
 
  }
 
 
 
  /* Return the created symbol. */
 
  return s;
 
}
 
 
 
/*******************************************************************************
 
 * Deprecated functions
 
 *******************************************************************************/
 
 
 
uint8_t RIO_packetTid( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue) , "Reading from empty reception queue.");
 
 
 
  return (uint8_t) (QueueGetFrontContent(stack->rxQueue, 1ul) & 0xfful);
 
}
 
 
 
 
 
uint16_t RIO_packetDestination( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 0ul));
 
}
 
 
 
 
 
uint16_t RIO_packetSource( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 1ul) >> 16);
 
}
 
 
 
 
 
uint8_t RIO_readMaintenanceReadRequestHop( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
 
}
 
 
 
uint32_t RIO_readMaintenanceReadRequestOffset( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (QueueGetFrontContent(stack->rxQueue, 2ul) & 0x00fffffcul);
 
}
 
 
 
uint8_t RIO_readMaintenanceReadResponseHop( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
 
}
 
 
 
uint32_t RIO_readMaintenanceReadResponse( RioStack_t *stack )
 
{
 
  uint32_t readData;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* There is no way of knowing where the data is positioned. */
 
  /* Bit-or the two words together since one of the words are zero. */
 
  readData = QueueGetFrontContent(stack->rxQueue, 3ul);
 
  readData |= QueueGetFrontContent(stack->rxQueue, 4ul);
 
  return readData;
 
}
 
 
 
uint8_t RIO_readMaintenanceWriteRequestHop( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
 
}
 
 
 
uint32_t RIO_readMaintenanceWriteRequestOffset( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (QueueGetFrontContent(stack->rxQueue, 2ul) & 0x00fffffcul);
 
}
 
 
 
uint32_t RIO_readMaintenanceWriteRequestData( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (QueueGetFrontContent(stack->rxQueue, 3ul) | QueueGetFrontContent(stack->rxQueue, 4ul));
 
}
 
 
 
uint8_t RIO_readMaintenanceWriteResponseHop( RioStack_t *stack )
 
{
 
  return (uint8_t) (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
 
}
 
 
 
 
 
 
 
void RIO_sendNwrite8( RioStack_t *stack, const uint16_t destid, const uint32_t address,
 
                      const uint8_t data)
 
{
 
  sendNwrite(stack, destid, stack->baseDeviceId, 0, address, 1, &data, 0u);
 
}
 
 
 
 
 
void RIO_sendNwriteR8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address,
 
                       const uint8_t data)
 
{
 
  sendNwrite(stack, destid, stack->baseDeviceId, tid, address, 1, &data, 1u);
 
}
 
 
 
 
 
uint32_t RIO_readNwriteAddress8( RioStack_t *stack )
 
{
 
  uint32_t address;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Assemble the address from the wrsize field and the address itself to get a byte address. */
 
  address = (QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0x00000003ul;
 
  address |= QueueGetFrontContent(stack->rxQueue, 2ul) & (uint32_t)0xfffffffcul;
 
 
 
  return address;
 
}
 
 
 
 
 
uint8_t RIO_readNwriteSize8( RioStack_t *stack )
 
{
 
  uint8_t wrsize;
 
  uint8_t n;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Get the wrsize field from the packet and check its value. */
 
  wrsize = (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0xful);
 
  switch(wrsize)
 
  {
 
    case 0:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    case 1:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    case 2:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    case 3:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    default:
 
      /* Unsupported. */
 
      n = 0u;
 
      break;
 
  }
 
 
 
  return n;
 
}
 
 
 
 
 
uint8_t RIO_readNwritePayload8( RioStack_t *stack )
 
{
 
  uint8_t returnValue;
 
  uint32_t readData;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Since there is no way of knowing where the byte will be placed,
 
     OR all bytes in the payload and return it. */
 
  readData = QueueGetFrontContent(stack->rxQueue, 3ul);
 
  returnValue = (uint8_t) (readData >> 24);
 
  returnValue |= (uint8_t) (readData >> 16);
 
  returnValue |= (uint8_t) (readData >> 8);
 
  returnValue |= (uint8_t) (readData);
 
  readData = QueueGetFrontContent(stack->rxQueue, 4ul);
 
  returnValue |= (uint8_t) (readData >> 24);
 
  returnValue |= (uint8_t) (readData >> 16);
 
  returnValue |= (uint8_t) (readData >> 8);
 
  returnValue |= (uint8_t) (readData);
 
 
 
  return returnValue;
 
}
 
 
 
void RIO_sendNread8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = ((uint32_t) 0x0012ul) << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
 
  content = ((uint32_t) stack->baseDeviceId) << 16;
 
  content |= ((uint32_t) 0x4ul) << 12;
 
  content |= (address & (uint32_t)0x00000003ul) << 8;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* address(28:0)|wdptr|xamsbs(1:0) */
 
  /* xamsbs cannot be used if the address is a word. */
 
  content = address & (uint32_t)0xfffffffcul;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = ((uint32_t) crc) << 16;
 
  QueueSetContent(stack->txQueue, 3ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 4ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
 
 
uint32_t RIO_readNreadAddress8( RioStack_t *stack )
 
{
 
  uint32_t address;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Assemble the address from the rdsize field and the address itself to get a byte address. */
 
  address = (QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0x00000003ul;
 
  address |= QueueGetFrontContent(stack->rxQueue, 2ul) & (uint32_t)0xfffffffcul;
 
 
 
  return address;
 
}
 
 
 
 
 
uint8_t RIO_readNreadSize8( RioStack_t *stack )
 
{
 
  uint8_t rdsize;
 
  uint8_t n;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Get the rdsize field from the packet and check its value. */
 
  rdsize = (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0xful);
 
  switch(rdsize)
 
  {
 
    case 0:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    case 1:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    case 2:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    case 3:
 
      /* Reading one byte. */
 
      n = 1u;
 
      break;
 
    default:
 
      /* Unsupported. */
 
      n = 0u;
 
      break;
 
  }
 
 
 
  return n;
 
}
 
 
 
 
 
void RIO_sendMessage8( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox, const uint16_t size, const uint8_t* data)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
  uint32_t packetIndex;
 
  uint32_t dataIndex;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
  ASSERT((size <= 256), "Packet sizes over 256 are currently unsupported.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = ((uint32_t) 0x001bul) << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0|mbox(1:0)|xmbox(3:0) */
 
  content = ((uint32_t) stack->baseDeviceId) << 16;
 
  if(size <= 8u)
 
  {
 
    content |= ((uint32_t) 0x09ul) << 8;
 
  }
 
  else if(size <= 16u)
 
  {
 
    content |= ((uint32_t) 0x0aul) << 8;
 
  }
 
  else if(size <= 32u)
 
  {
 
    content |= ((uint32_t) 0x0bul) << 8;
 
  }
 
  else if(size <= 64u)
 
  {
 
    content |= ((uint32_t) 0x0cul) << 8;
 
  }
 
  else if(size <= 128u)
 
  {
 
    content |= ((uint32_t) 0x0dul) << 8;
 
  }
 
  else
 
  {
 
    content |= ((uint32_t) 0x0eul) << 8;
 
  }
 
  content |= ((uint32_t)mailbox & (uint32_t)0xfu) << 4;
 
  content |= ((uint32_t)mailbox) >> 4;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* double-word0...double-wordN */
 
  dataIndex = 0;
 
  packetIndex = 8;
 
  while(dataIndex < size)
 
  {
 
    content <<= 8;
 
    if(packetIndex == 80)
 
    {
 
      content |= crc >> 8;
 
    }
 
    else if(packetIndex == 81)
 
    {
 
      content |= crc & 0xff;
 
    }
 
    else
 
    {
 
      content |= data[dataIndex++];
 
    }
 
 
 
    if((packetIndex & 0x3) == 3)
 
    {
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, packetIndex>>2, content);
 
    }
 
 
 
    packetIndex++;
 
  }
 
 
 
  /* Pad the data to an even double word. */
 
  while((dataIndex & 0x7) != 0)
 
  {
 
    content <<= 8;
 
    dataIndex++;
 
 
 
    if((packetIndex & 0x3) == 3)
 
    {
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, packetIndex>>2, content);
 
    }
 
 
 
    packetIndex++;
 
  }
 
 
 
  /* Check where the CRC should be placed. */
 
  if((packetIndex & 0x3) == 0)
 
  {
 
    /* crc(15:0)|pad(15:0) */
 
    content = ((uint32_t) crc) << 16;
 
  }
 
  else
 
  {
 
    /* double-wordN-LSB|crc(15:0) */
 
    content &= 0x0000ffff;
 
    crc = Crc16(content, crc);
 
    content <<= 16;
 
    content |= crc;
 
  }
 
 
 
  /* Set the crc. */
 
  QueueSetContent(stack->txQueue, packetIndex>>2, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 1+(packetIndex>>2));
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
 
 
uint8_t RIO_readMessageMbox( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue." );
 
 
 
  return (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 4) & (uint32_t)0xful);
 
}
 
 
 
 
 
uint16_t RIO_readMessageSize8( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (uint16_t) (4ul*(QueueGetFrontSize(stack->rxQueue) - 3ul));
 
}
 
 
 
 
 
/*lint -save -e613 */
 
void RIO_readMessagePayload8( RioStack_t *stack, uint8_t* buffer )
 
{
 
  uint32_t size;
 
  uint32_t dataIndex;
 
  uint32_t packetIndex;
 
  uint32_t content = 0;;
 
 
 
 
 
  ASSERT((buffer != NULL), "Buffer is not allocated.");
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Move bytes from inbound packet queue into the user buffer. */
 
  /* Long messages contain a CRC in byte 80-81, this is removed when the buffer
 
     is copied. */
 
  size = QueueGetFrontSize(stack->rxQueue);
 
  dataIndex = 0;
 
  packetIndex = 8;
 
  while((packetIndex>>2) < size)
 
  {
 
    /* Check if a new word should be read from the inbound queue. */
 
    if((packetIndex & 0x3) == 0)
 
    {
 
      /* Get a new word. */
 
      content = QueueGetFrontContent(stack->rxQueue, packetIndex>>2);
 
    }
 
    else
 
    {
 
      /* Update the current word. Remove the MSB, it has already be moved
 
         to the user buffer. */
 
      content <<= 8;
 
    }
 
 
 
    /* Check if the current byte is CRC. */
 
    if((packetIndex != 80) && (packetIndex != 81))
 
    {
 
      /* Not CRC. */
 
      /* Move the byte to the user buffer. */
 
      buffer[dataIndex++] = (content >> 24);
 
    }
 
 
 
    /* Increment to the next position in the packet. */
 
    packetIndex++;
 
  }
 
}
 
/*lint -restore */
 
 
 
uint16_t RIO_readDoorbellInfo( RioStack_t *stack )
 
{
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 2ul) >> 16);
 
}
 
 
 
 
 
void RIO_sendResponseDone8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address, const uint8_t data)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = 0x001dul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
 
  content = ((uint32_t) stack->baseDeviceId) << 16;
 
  content |= (uint32_t)0x80ul << 8;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* double-word 0 */
 
  switch(address & 0x7ul)
 
  {
 
    case 0:
 
      /* MSB byte. */
 
      content = ((uint32_t) data) << 24;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    case 1:
 
      content = ((uint32_t) data) << 16;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    case 2:
 
      content = ((uint32_t) data) << 8;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    case 3:
 
      content = ((uint32_t) data);
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    case 4:
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = ((uint32_t) data) << 24;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    case 5:
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = ((uint32_t) data) << 16;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    case 6:
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = ((uint32_t) data) << 8;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
    default:
 
      /* LSB byte. */
 
      content = 0x00000000ul;
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 2ul, content);
 
      content = ((uint32_t) data);
 
      crc = Crc32(content, crc);
 
      QueueSetContent(stack->txQueue, 3ul, content);
 
      break;
 
  }
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = ((uint32_t) crc) << 16;
 
  QueueSetContent(stack->txQueue, 4ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 5ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
 
 
uint8_t RIO_readResponseDone8( RioStack_t *stack )
 
{
 
  uint8_t returnValue;
 
  uint32_t readData;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Since there is no way of knowing where the byte will be placed,
 
     OR all bytes in the reply and return it. */
 
  readData = QueueGetFrontContent(stack->rxQueue, 2ul);
 
  returnValue = (uint8_t) (readData >> 24);
 
  returnValue |= (uint8_t) (readData >> 16);
 
  returnValue |= (uint8_t) (readData >> 8);
 
  returnValue |= (uint8_t) (readData);
 
  readData = QueueGetFrontContent(stack->rxQueue, 3ul);
 
  returnValue |= (uint8_t) (readData >> 24);
 
  returnValue |= (uint8_t) (readData >> 16);
 
  returnValue |= (uint8_t) (readData >> 8);
 
  returnValue |= (uint8_t) (readData);
 
 
 
  return returnValue;
 
}
 
 
 
 
 
 
 
/*******************************************************************************
 
 * Local functions
 
 *******************************************************************************/
 
 
 
 
 
static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
 
{
 
  /* Update the buffer status of the link partner. */
 
  (void) ackId;
 
  stack->txBufferStatus = bufferStatus;
 
}
 
 
 
 
 
static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
 
{
 
  /* Check if an acknowledge is expected and that it is for a transmitted packet. */
 
  if((stack->txAckId != stack->txAckIdWindow) && (ackId == stack->txAckId))
 
  {
 
    DEBUG_FRAMING_TX("ack=%i", ackId);
 
    /* Acknowledge for a recently transmitted packet received. */
 
    /* Remove the packet from the outbound queue and restart the transmission for
 
       a new packet. */
 
    stack->txQueue = QueueDequeue(stack->txQueue);
 
    stack->txAckId = ACKID_INC(stack->txAckId);
 
    stack->statusOutboundPacketComplete++;
 
  }
 
  else
 
  {
 
    DEBUG_FRAMING_TX("*ack=%i", ackId);
 
    /* Acknowledge for an unexpected ackId or not waiting for an acknowledge. */
 
    /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
 
    stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
 
    stack->txCounter = 0u;
 
    stack->statusOutboundErrorPacketAccepted++;
 
    DEBUG_STATE("tx:error-stopped");
 
  }
 
 
 
  /* Update the buffer status of the link partner. */
 
  stack->txBufferStatus = bufferStatus;
 
}
 
 
 
 
 
static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
 
{
 
  /* Check if the retried packet ackId is acceptable. */
 
  if(ackId == stack->txAckId)
 
  {
 
    DEBUG_FRAMING_TX("retry=%u", ackId);
 
    /* The request for retry is for the current packet. */
 
    /* Force the transmitter to send a RESTART-FROM-RETRY symbol. */
 
    stack->txState = TX_STATE_OUTPUT_RETRY_STOPPED;
 
    stack->statusOutboundPacketRetry++;
 
    DEBUG_STATE("tx:retry-stopped");
 
  }
 
  else
 
  {
 
    DEBUG_FRAMING_TX("*retry=%u %u", ackId, stack->txAckId);
 
    /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
 
    stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
 
    stack->txCounter = 0u;
 
    stack->statusOutboundErrorPacketRetry++;
 
    DEBUG_STATE("tx:error-stopped");
 
  }
 
 
 
  /* Update the buffer status of the link partner. */
 
  stack->txBufferStatus = bufferStatus;
 
}
 
 
 
 
 
static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause)
 
{
 
  (void) arbitrary;
 
 
 
  /* Force the transmitter to enter output-error-stopped state. */
 
  stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
 
  stack->txCounter = 0u;
 
 
 
  /* Record the type of error that caused the packet to not being accepted. */
 
  switch(cause)
 
  {
 
    case PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID:
 
      stack->statusPartnerErrorPacketAckId++;
 
      break;
 
    case PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC:
 
      stack->statusPartnerErrorControlCrc++;
 
      break;
 
    case PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC:
 
      stack->statusPartnerErrorPacketCrc++;
 
      break;
 
    case PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER:
 
      stack->statusPartnerErrorIllegalCharacter++;
 
      break;
 
    default:
 
      stack->statusPartnerErrorGeneral++;
 
      break;
 
  }
 
 
 
  DEBUG_STATE("tx:error-stopped");
 
}
 
 
 
 
 
static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus)
 
{
 
  uint8_t window;
 
  uint8_t windowReceived;
 
 
 
 
 
  (void) portStatus;
 
 
 
  /* Check if this symbols is expected. */
 
  if(stack->txState == TX_STATE_OUTPUT_ERROR_STOPPED)
 
  {
 
    DEBUG_FRAMING_TX("link-res:%u %u %u", stack->txAckIdWindow, stack->txAckId, ackId);
 
 
 
    /* Calculate the number of packets that has not received an acknowledge on our side and
 
       on the link-partner side. */
 
    window = (stack->txAckIdWindow - stack->txAckId) & 0x1f;
 
    windowReceived = (ackId - stack->txAckId) & 0x1f;
 
 
 
    /* Check if the link-partners response is acceptable. */
 
    if(windowReceived <= window)
 
    {
 
      /* A link-response is expected. */
 
      DEBUG_STATE("tx:recover");
 
 
 
      /* Remove entries in the queue that the link-partner has sent acknowledges for that has been lost. */
 
      while(stack->txAckId != ackId)
 
      {
 
        stack->txQueue = QueueDequeue(stack->txQueue);
 
        stack->txAckId = ACKID_INC(stack->txAckId);
 
        stack->statusOutboundPacketComplete++;
 
      }
 
 
 
      /* Set the transmission window to the resend packets that has not been received. */
 
      stack->txQueue = QueueWindowReset(stack->txQueue);
 
      stack->txAckIdWindow = ackId;
 
      stack->txFrameState = TX_FRAME_START;
 
 
 
      /* Set the transmitter back into normal operation. */
 
      stack->txState = TX_STATE_LINK_INITIALIZED;
 
    }
 
    else
 
    {
 
      /* The link-partner response is unacceptable. */
 
      /* Recovery is not possible. */
 
      stack->txState = TX_STATE_UNINITIALIZED;
 
      ASSERT0("Unrecoverable protocol error.");
 
    }
 
  }
 
  else
 
  {
 
    /* Not expecting a link-response. */
 
    /* Just discard this symbol. */
 
    /* REMARK: Add status counter here??? */
 
  }
 
}
 
 
 
 
 
static void handleStartOfPacket(RioStack_t *stack)
 
{
 
  /* Check if a packet is already started. */
 
  if(stack->rxCounter != 0u)
 
  {
 
    /* Packet has already started. */
 
    /* This indicates an implicit end-of-packet symbol and signals the previous packet as ready. */
 
    DEBUG_FRAMING_RX("cont=%u", stack->rxAckId);
 
 
 
    /* Check the packet crc. */
 
    if(stack->rxCrc == 0x0000u)
 
    {
 
      /* The packet has a correct CRC. */
 
 
 
      /* Check if the packet is long enough to contain a complete packet. */
 
      if(stack->rxCounter > 3u)
 
      {
 
        /* Packet long enough to process. */
 
 
 
        /* Process the newly received packet and start a new one. */
 
        handleNewPacketEnd(stack);
 
        handleNewPacketStart(stack);
 
      }
 
      else
 
      {
 
        /* The packet has a valid CRC but is too short. */
 
        /* Packet error. Enter input-error-stopped state. */
 
        stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
        stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
        stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
 
        stack->statusInboundErrorGeneral++;
 
        DEBUG_STATE("rx:error-stopped");
 
      }
 
    }
 
    else
 
    {
 
      /* The packet has an invalid CRC. */
 
      /* Packet error. Enter input-error-stopped state. */
 
      stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
      stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
      stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
 
      stack->statusInboundErrorPacketCrc++;
 
      DEBUG_STATE("rx:error-stopped");
 
    }
 
  }
 
  else
 
  {
 
    /* Packet has not already started. */
 
    DEBUG_FRAMING_RX("start=%u", stack->rxAckId);
 
    handleNewPacketStart(stack);
 
  }
 
}
 
 
 
 
 
static void handleEndOfPacket(RioStack_t *stack)
 
{
 
  DEBUG_FRAMING_RX("end=%u", stack->rxAckId);
 
 
 
  /* Check if the CRC is correct. */
 
  if(stack->rxCrc == 0x0000u)
 
  {
 
    /* The packet has a correct CRC. */
 
 
 
    /* Check if the packet is long enough to contain a complete packet. */
 
    if(stack->rxCounter > 3u)
 
    {
 
      /* Packet long enough to process. */
 
 
 
      /* Process the newly received packet. */
 
      handleNewPacketEnd(stack);
 
    }
 
    else
 
    {
 
      /* The packet has a valid CRC but is too short. */
 
      /* Packet error. Enter input-error-stopped state. */
 
      stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
      stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
      stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
 
      stack->statusInboundErrorGeneral++;
 
      DEBUG_STATE("rx:error-stopped");
 
    }
 
  }
 
  else
 
  {
 
    /* The packet has an invalid CRC. */
 
    /* Packet error. Enter input-error-stopped state. */
 
    stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
    stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
    stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
 
    stack->statusInboundErrorPacketCrc++;
 
    DEBUG_STATE("rx:error-stopped");
 
  }
 
}
 
 
 
 
 
static void handleNewPacketStart(RioStack_t *stack)
 
{
 
  /* Check if there are buffers available to store the new frame. */
 
  if (QueueAvailable(stack->rxQueue) > 0u)
 
  {
 
    /* There are buffers available to accept the new packet. */
 
 
 
    /* Update the reception counter to indicate the frame has started. */
 
    stack->rxCounter = 1;
 
  }
 
  else
 
  {
 
    /* There are no buffers available. */
 
    /* Go to input retry stopped state. */
 
    DEBUG_FRAMING_RX("retry=%u", stack->rxAckId);
 
    stack->statusInboundPacketRetry++;
 
    stack->txState = TX_STATE_SEND_PACKET_RETRY;
 
    stack->rxState = RX_STATE_INPUT_RETRY_STOPPED;
 
    DEBUG_STATE("rx:retry-stopped");
 
  }
 
}
 
 
 
 
 
static void handleNewPacketEnd(RioStack_t *stack)
 
{
 
  uint32_t *packet;
 
  uint32_t ftype;
 
  uint32_t transaction;
 
 
 
 
 
  /* Save the size of the packet. */
 
  QueueSetSize(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul);
 
 
 
  /* Get the packet and information about its type. */
 
  packet = QueueGetBackBuffer(stack->rxQueue);
 
  ftype = FTYPE_GET(packet);
 
  transaction = TRANSACTION_GET(packet);
 
 
 
#ifdef RIO_TRANSPARENT
 
  /* Always forward the packet to the top of the stack. */
 
  stack->rxQueue = QueueEnqueue(stack->rxQueue);
 
#else
 
  /* Check if the packet should be forwarded to the top of the stack. */
 
  if ((QueueGetBackSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE) &&
 
      (ftype == FTYPE_MAINTENANCE) && (transaction == TRANSACTION_MAINT_READ_REQUEST))
 
  {
 
    /* Received maintenance read request. */
 
    /* Send a maintenance read response. This packet is aimed at the stack, it should
 
       not be forwarded. */
 
    /* Note that only single word accesses are supported. */
 
    RIO_sendMaintenanceReadResponse(stack, SRCID_GET(packet),TID_GET(packet), 0xff,
 
                                    RIO_readConfig(stack, CONFIG_OFFSET_GET(packet)));
 
  }
 
  else if ((QueueGetBackSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE) &&
 
           (ftype == FTYPE_MAINTENANCE) && (transaction == TRANSACTION_MAINT_WRITE_REQUEST))
 
  {
 
    /* Received maintenance write request. */
 
    /* Send a maintenance write response. This packet is aimed at the stack, it should
 
       not be forwarded. */
 
    /* Note that only single word accesses are supported. */
 
    RIO_writeConfig(stack, CONFIG_OFFSET_GET(packet),
 
                    DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0));
 
    RIO_sendMaintenanceWriteResponse(stack, SRCID_GET(packet), TID_GET(packet), 0xff);
 
  }
 
  else
 
  {
 
    /* Forward this packet to the top of the stack. */
 
    stack->rxQueue = QueueEnqueue(stack->rxQueue);
 
  }
 
#endif
 
  /* Reset the reception counter. */
 
  stack->rxCounter = 0u;
 
 
 
  /* Update the ackId for the receiver. */
 
  stack->rxAckId = ACKID_INC(stack->rxAckId);
 
 
 
  /* Update status counter. */
 
  stack->statusInboundPacketComplete++;
 
}
 
 
 
 
 
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd)
 
{
 
  /* Check the command of the link-request. */
 
  if(cmd == LINK_REQUEST_INPUT_STATUS)
 
  {
 
    /* Input-status requested. */
 
    /* Return input port status. */
 
 
 
    /* Force the transmitter to send a link-response-symbol. */
 
    stack->txState = TX_STATE_SEND_LINK_RESPONSE;
 
  }
 
  else if(cmd == LINK_REQUEST_RESET_DEVICE)
 
  {
 
    /* Reset-device requested. */
 
    /* REMARK: Support this??? */
 
  }
 
  else
 
  {
 
    /* Unrecognized command. */
 
    /* Dont do anything. */
 
  }
 
 
 
  /* Always cancel an ongoing frame when a link-request has been received. */
 
  stack->rxCounter = 0;
 
 
 
  /* Receiving this indicates the link partner having encountered a potential problem. */
 
  /* Count the number of times this happens. */
 
  stack->statusPartnerLinkRequest++;
 
}
 
 
 
 
 
static void sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                        const uint8_t hopCount, const uint32_t offset)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = 0x0018ul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  content |= (uint32_t) 0x08ul << 8;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
 
  content = ((uint32_t) hopCount) << 24;
 
  content |= offset & (uint32_t) 0x00fffffcul;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = ((uint32_t) crc) << 16;
 
  QueueSetContent(stack->txQueue, 3ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 4ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static void receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                    uint8_t *hopCount, uint32_t *offset)
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *hopCount = HOP_GET(packet);
 
  *offset = CONFIG_OFFSET_GET(packet);
 
}
 
 
 
static void sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                         const uint8_t hopCount, const uint32_t data)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  /* REMARK: What should we do if there are no buffers available to send the packet... */
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = (uint32_t)0x0018ul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
 
  content = (uint32_t) srcid << 16;
 
  content |= (uint32_t) 0x28ul << 8;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* hopcount(7:0)|reserved(23:0) */
 
  content = (uint32_t) (hopCount << 24);
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* double-word 0 */
 
  /* Send the data in both words since this function cannot know the offset the request was sent to. */
 
  content = data;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 3ul, content);
 
  content = data;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 4ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = (uint32_t)crc << 16;
 
  QueueSetContent(stack->txQueue, 5ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 6ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static void receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                            uint8_t *hopCount, uint32_t *data)
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT((data != NULL), "Buffer is not allocated.");
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *hopCount = HOP_GET(packet);
 
  *data = DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0);
 
}
 
 
 
static void sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                         const uint8_t hopCount, const uint32_t offset, const uint32_t data )
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = 0x0018ul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  content |= (uint32_t)0x18ul << 8;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
 
  content = ((uint32_t) hopCount) << 24;
 
  content |= offset & (uint32_t)0x00fffffcul;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* double-word 0 */
 
  /* Note that both words are filled in to avoid looking at the offset. The receiver will not
 
     look at the other part anyway. The standard does not say anything about the value of the padding. */
 
  content = data;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 3ul, content);
 
  content = data;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 4ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = ((uint32_t) crc) << 16;
 
  QueueSetContent(stack->txQueue, 5ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 6ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static void receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                            uint8_t *hopCount, uint32_t *offset, uint32_t *data )
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT((data != NULL), "Buffer is not allocated.");
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *hopCount = HOP_GET(packet);
 
  *offset = CONFIG_OFFSET_GET(packet);
 
  *data = DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0);
 
}
 
 
 
static void sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                          const uint8_t hopCount)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  /* REMARK: What should we do if there are no buffers available to send the packet... */
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = (uint32_t)0x0018ul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
 
  content = (uint32_t) srcid << 16;
 
  content |= (uint32_t)0x38ul << 8;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* hopcount(7:0)|reserved(23:0) */
 
  content = hopCount << 24;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = (uint32_t)crc << 16;
 
  QueueSetContent(stack->txQueue, 3ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 4ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static void receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                      uint8_t *hopCount)
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *hopCount = HOP_GET(packet);
 
}
 
 
 
/* REMARK: Use a packet pointer instead of using the QueueSetContent... */
 
static void sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                        const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer,
 
                        const uint8_t ack)
 
{
 
  uint32_t content;
 
  uint32_t size;
 
  uint16_t wrsize = wrsizeGet(address, bufferSize);
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
  ASSERT((wrsize != 0xffff), "Write access unsupported by protocol.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = ((uint32_t)0x0015ul) << 16;
 
  content |= (uint32_t)destid;
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|wrsize(3:0)|srcTID(7:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  if(ack == 0u)
 
  {
 
    /* Send NWRITE. */
 
    content |= (uint32_t) TRANSACTION_WRITE_NWRITE << 12;
 
  }
 
  else
 
  {
 
    /* Send NWRITE_R. */
 
    content |= (uint32_t) TRANSACTION_WRITE_NWRITER << 12;
 
  }
 
  content |= (uint32_t) (wrsize & 0x0f00);
 
  content |= (uint32_t) tid;
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* address(28:0)|wdptr|xamsbs(1:0) */
 
  /* wrsize also contains wdptr in the lower nibble. */
 
  /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
 
     34-bit address should be used, another mechanism to set it should be used. */
 
  content = (address & 0xfffffff8ul);
 
  content |= ((uint32_t) (wrsize & 0x000f)) << 2;
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* Place data buffer into the payload of the packet. */
 
  size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 12, address & 0x7, bufferSize, buffer);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, size+1);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static uint16_t receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                               uint32_t *address, const uint16_t dataLength, uint8_t *data )
 
{
 
  uint32_t *packet;
 
  uint8_t offset;
 
  uint16_t size;
 
  uint8_t wrsize;
 
  uint8_t wdptr;
 
 
 
 
 
  ASSERT((data != NULL), "Buffer is not allocated.");
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  wrsize = WRSIZE_GET(packet);
 
  wdptr = WDPTR_GET(packet);
 
  wrsizeToOffset(wrsize, wdptr, &offset, &size);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *address = ADDRESS_GET(packet) | offset;
 
 
 
  if(size > 16)
 
  {
 
    /* Remove header and crc from the size count. */
 
    size = ((QueueGetFrontSize(stack->rxQueue)-4) * 4);
 
  }
 
 
 
  /* Check if there is enough room in the receiving buffer. */
 
  if(size <= dataLength)
 
  {
 
    return getPacketPayload(packet, 12, offset, size, data);
 
  }
 
  else
 
  {
 
    return 0;
 
  }
 
}
 
 
 
static void sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                       const uint32_t address, const uint16_t dataLength)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
  uint16_t rdsize = rdsizeGet(address, dataLength);
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
  ASSERT((rdsize != 0xffff), "Read access unsupported by protocol.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = ((uint32_t) 0x0012ul) << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  content |= ((uint32_t) TRANSACTION_REQUEST_NREAD) << 12;
 
  content |= (uint32_t) (rdsize & 0x0f00);
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* address(28:0)|wdptr|xamsbs(1:0) */
 
  /* rdsize also contains wdptr in the lower nibble. */
 
  /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
 
     34-bit address should be used, another mechanism to set it should be used. */
 
  content = address & 0xfffffff8ul;
 
  content |= ((uint32_t) (rdsize & 0x000f)) << 2;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = ((uint32_t) crc) << 16;
 
  QueueSetContent(stack->txQueue, 3ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 4ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static void receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                          uint32_t *address, uint16_t *dataLength)
 
{
 
  uint32_t *packet;
 
  uint8_t offset;
 
  uint16_t size;
 
  uint8_t rdsize;
 
  uint8_t wdptr;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  rdsize = WRSIZE_GET(packet);
 
  wdptr = WDPTR_GET(packet);
 
  rdsizeToOffset(rdsize, wdptr, &offset, &size);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *address = ADDRESS_GET(packet) | offset;
 
  *dataLength = size;
 
}
 
 
 
static void sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                                     const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
 
{
 
  uint32_t content;
 
  uint32_t size;
 
 
 
 
 
  ASSERT((buffer != NULL), "Buffer is not allocated.");
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = 0x001dul << 16;
 
  content |= (uint32_t) destid;
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  content |= ((uint32_t) TRANSACTION_RESPONSE_WITH_PAYLOAD) << 12;
 
  content |= (uint32_t) tid;
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* Place data buffer into the payload of the packet. */
 
  size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 8, address & 0x7, bufferSize, buffer);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, size+1);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
 
 
static uint16_t receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                                            const uint32_t address, const uint16_t dataLength, uint8_t *data )
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT((data != NULL), "Buffer is not allocated.");
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
 
 
  return getPacketPayload(packet, 8, address & 0x7, dataLength, data);
 
}
 
 
 
 
 
static void sendResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                          const uint8_t status)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = (uint32_t)0x001dul << 16;
 
  content |= destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
 
  content = (uint32_t)srcid << 16;
 
  content |= ((uint32_t)status & (uint32_t)0x0ful) << 8;
 
  content |= tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = (uint32_t)crc << 16;
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 3ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
 
 
static void receiveResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
}
 
 
 
 
 
static void sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
 
                          const uint16_t info )
 
{
 
  uint32_t content;
 
  uint16_t crc;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = 0x001aul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, 0xffffu);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
 
  content = ((uint32_t) info) << 16;
 
  crc = Crc16(info, crc);
 
  content |= crc;
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 3ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
 
 
static void receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
 
                             uint16_t *info)
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *tid = TID_GET(packet);
 
  *info = INFO_GET(packet);
 
}
 
 
 
 
 
static void sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
 
                         const uint16_t bufferSize, const uint8_t* bufferData)
 
{
 
  uint32_t content;
 
  uint32_t size;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
  ASSERT((bufferSize <= 256), "Packet sizes larger than 256 are currently unsupported.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = ((uint32_t) 0x001bul) << 16;
 
  content |= (uint32_t) destid;
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0|mbox(1:0)|xmbox(3:0) */
 
  content = ((uint32_t) srcid) << 16;
 
  if(bufferSize <= 8u)
 
  {
 
    content |= ((uint32_t) 0x09ul) << 8;
 
  }
 
  else if(bufferSize <= 16u)
 
  {
 
    content |= ((uint32_t) 0x0aul) << 8;
 
  }
 
  else if(bufferSize <= 32u)
 
  {
 
    content |= ((uint32_t) 0x0bul) << 8;
 
  }
 
  else if(bufferSize <= 64u)
 
  {
 
    content |= ((uint32_t) 0x0cul) << 8;
 
  }
 
  else if(bufferSize <= 128u)
 
  {
 
    content |= ((uint32_t) 0x0dul) << 8;
 
  }
 
  else
 
  {
 
    content |= ((uint32_t) 0x0eul) << 8;
 
  }
 
  content |= ((uint32_t)mailbox & (uint32_t)0xfu) << 4;
 
  content |= ((uint32_t)mailbox) >> 4;
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* Place data buffer into the payload of the packet. */
 
  size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 8, 0, bufferSize, bufferData);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, size+1);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static uint16_t receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
 
                                const uint16_t dataLength, uint8_t *data )
 
{
 
  uint32_t *packet;
 
  uint32_t size;
 
 
 
 
 
  ASSERT((data != NULL), "Buffer is not allocated.");
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  /* Get a pointer to the packet. */
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  /* The higher mailbox numbers are used with messages that cannot be multi-packets. */
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *mailbox = XMBOX_GET(packet);
 
  *mailbox <<= 2;
 
  *mailbox |= LETTER_GET(packet);
 
  *mailbox <<= 2;
 
  *mailbox |= MBOX_GET(packet);
 
 
 
  /* Calculate the number of bytes to transfer. */
 
  /* Remove the header and crc from the size count. */
 
  size = (QueueGetFrontSize(stack->rxQueue)-3) * 4;
 
 
 
  /* Check if there is enough room in the receiving buffer. */
 
  if(size <= dataLength)
 
  {
 
    return getPacketPayload(packet, 8, 0, size, data);
 
  }
 
  else
 
  {
 
    return 0;
 
  }
 
 
 
}
 
 
 
static void sendMessageResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
 
                                 const uint8_t status)
 
{
 
  uint32_t content;
 
  uint16_t crc = 0xffffu;
 
 
 
 
 
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = (uint32_t)0x001dul << 16;
 
  content |= destid;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 0ul, content);
 
 
 
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|letter(1:0|mbox(1:0)|msgseg(3:0) */
 
  content = (uint32_t)srcid << 16;
 
  content |= (uint32_t)0x1ul << 12;
 
  content |= ((uint32_t)status & (uint32_t)0xful) << 8;
 
  content |= ((uint32_t)mailbox & (uint32_t)0xful) << 4;
 
  content |= ((uint32_t)mailbox) >> 4;
 
  crc = Crc32(content, crc);
 
  QueueSetContent(stack->txQueue, 1ul, content);
 
 
 
  /* crc(15:0)|pad(15:0) */
 
  content = (uint32_t)crc << 16;
 
  QueueSetContent(stack->txQueue, 2ul, content);
 
 
 
  /* Set the size of the packet and place it in the queue. */
 
  QueueSetSize(stack->txQueue, 3ul);
 
  stack->txQueue = QueueEnqueue(stack->txQueue);
 
}
 
 
 
static void receiveMessageResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
 
{
 
  uint32_t *packet;
 
 
 
 
 
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
 
 
 
  packet = QueueGetFrontBuffer(stack->rxQueue);
 
 
 
  *destid = DESTID_GET(packet);
 
  *srcid = SRCID_GET(packet);
 
  *mailbox = XMBOX_GET(packet);
 
  *mailbox <<= 2;
 
  *mailbox |= LETTER_GET(packet);
 
  *mailbox <<= 2;
 
  *mailbox |= MBOX_GET(packet);
 
}
 
 
 
 
 
static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
 
                                 const uint16_t dataSize, uint8_t *data)
 
{
 
  uint32_t content = 0;
 
  uint16_t packetIndex;
 
  uint16_t payloadIndex;
 
  uint16_t dataIndex;
 
 
 
 
 
  /* Move bytes from inbound packet queue into the user buffer. */
 
  /* Long packets contain a CRC in byte 80-81, this is removed when the buffer
 
     is copied. */
 
  packetIndex = payloadOffset;
 
  payloadIndex = 0;
 
  dataIndex = 0;
 
  while(dataIndex < dataSize)
 
  {
 
    /* Check if a new word should be read from the inbound queue. */
 
    if((packetIndex & 0x3) == 0)
 
    {
 
      /* Get a new word. */
 
      content = packet[packetIndex>>2];
 
    }
 
    else
 
    {
 
      /* Update the current word. Remove the MSB, it has already be moved
 
         to the user buffer. */
 
      content <<= 8;
 
    }
 
 
 
    /* Check if the current byte is CRC. */
 
    if((packetIndex != 80) && (packetIndex != 81) && (payloadIndex >= dataOffset))
 
    {
 
      /* Not CRC. */
 
      /* Move the byte to the user buffer. */
 
      data[dataIndex++] = (content >> 24);
 
    }
 
 
 
    /* Increment to the next position in the packet. */
 
    packetIndex++;
 
    payloadIndex++;
 
  }
 
 
 
  return dataIndex;
 
}
 
 
 
 
 
static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
 
                                 const uint16_t dataSize, const uint8_t *data)
 
{
 
  uint16_t crc = 0xffffu;
 
  uint32_t content = 0;
 
  uint16_t packetIndex;
 
  uint16_t payloadIndex;
 
  uint16_t dataIndex;
 
 
 
 
 
  /***************************************************
 
   * Calculate the CRC for the packet header.
 
   ***************************************************/
 
  for(packetIndex = 0; packetIndex < payloadOffset; packetIndex+=4)
 
  {
 
    crc = Crc32(packet[packetIndex>>2], crc);
 
  }
 
 
 
  /***************************************************
 
   * Pad the data before the actual data is written.
 
   ***************************************************/
 
  payloadIndex = 0;
 
  while(payloadIndex < dataOffset)
 
  {
 
    content <<= 8;
 
 
 
    if((packetIndex & 0x3) == 3)
 
    {
 
      crc = Crc32(content, crc);
 
      packet[packetIndex>>2] = content;
 
    }
 
 
 
    payloadIndex++;
 
    packetIndex++;
 
  }
 
 
 
  /***************************************************
 
   * Write content and any embedded CRC.
 
   ***************************************************/
 
  dataIndex = 0;
 
  while(dataIndex < dataSize)
 
  {
 
    content <<= 8;
 
 
 
    /* Check if CRC or content should be entered into the packet. */
 
    if(packetIndex == 80)
 
    {
 
      /* CRC MSB. */
 
      content |= crc >> 8;
 
    }
 
    else if(packetIndex == 81)
 
    {
 
      /* CRC LSB. */
 
      content |= crc & 0xff;
 
    }
 
    else
 
    {
 
      /* Data content. */
 
      content |= data[dataIndex++];
 
      payloadIndex++;
 
    }
 
 
 
    if((packetIndex & 0x3) == 3)
 
    {
 
      crc = Crc32(content, crc);
 
      packet[packetIndex>>2] = content;
 
    }
 
 
 
    packetIndex++;
 
  }
 
 
 
  /***************************************************
 
   * Pad the data to an even double word.
 
   ***************************************************/
 
  while((payloadIndex & 0x7) != 0)
 
  {
 
    content <<= 8;
 
 
 
    if((packetIndex & 0x3) == 3)
 
    {
 
      crc = Crc32(content, crc);
 
      packet[packetIndex>>2] = content;
 
    }
 
 
 
    packetIndex++;
 
    payloadIndex++;
 
  }
 
 
 
  /***************************************************
 
   * Write the CRC into the packet.
 
   ***************************************************/
 
  if((packetIndex & 0x3) == 0)
 
  {
 
    /* crc(15:0)|pad(15:0) */
 
    content = ((uint32_t) crc) << 16;
 
  }
 
  else
 
  {
 
    /* double-wordN-LSB|crc(15:0) */
 
    content &= 0x0000ffff;
 
    crc = Crc16(content, crc);
 
    content <<= 16;
 
    content |= crc;
 
  }
 
  packet[packetIndex>>2] = content;
 
 
 
  return (packetIndex>>2);
 
}
 
 
 
 
 
/* \note See the RapidIO standard part1 table 4-4 for details about
 
 * {address, size}->{wdptr, wrsize} mapping.
 
 */
 
static uint16_t rdsizeGet(const uint32_t address, const uint16_t size)
 
{
 
  uint8_t wdptr;
 
  uint8_t rdsize;
 
 
 
 
 
  switch(size/8)
 
  {
 
    case 0:
 
      /**************************************************************
 
       * Sub double-word access.
 
       **************************************************************/
 
      /* REMARK: The same code as in wrsizeGet for sub
 
         double-word... use it instead??? */
 
      switch(size%8)
 
      {
 
        case 0:
 
          /* Not supported by protocol. */
 
          wdptr = 0xff;
 
          rdsize = 0xff;
 
          break;
 
        case 1:
 
          /* Reading one byte. */
 
          /* Any address is allowed. */
 
          wdptr = (address >> 2) & 0x1;
 
          rdsize = address & 0x3;
 
          break;
 
        case 2:
 
          /* Reading two bytes. */
 
          /* Address 0, 2, 4, 6 are valid. */
 
          if((address & 0x1) == 0)
 
          {
 
            wdptr = (address >> 2) & 0x1;
 
            rdsize = (address & 0x7) | 0x4;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            rdsize = 0xff;
 
          }
 
          break;
 
        case 3:
 
          /* Reading 3 bytes. */
 
          /* Address 0 and 5 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 5))
 
          {
 
            wdptr = (address >> 2) & 0x1;
 
            rdsize = 0x5ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            rdsize = 0xff;
 
          }
 
          break;
 
        case 4:
 
          /* Reading 4 bytes. */
 
          /* Address 0 and 4 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 4))
 
          {
 
            wdptr = (address >> 2) & 0x1;
 
            rdsize = 0x8ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            rdsize = 0xff;
 
          }
 
          break;
 
        case 5:
 
          /* Reading 5 bytes. */
 
          /* Address 0 and 3 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 3))
 
          {
 
            wdptr = (address >> 1) & 0x1;
 
            rdsize = 0x7ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            rdsize = 0xff;
 
          }
 
          break;
 
        case 6:
 
          /* Reading 6 bytes. */
 
          /* Addresses 0 and 2 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 2))
 
          {
 
            wdptr = (address >> 1) & 0x1;
 
            rdsize = 0x9ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            rdsize = 0xff;
 
          }
 
          break;
 
        default:
 
          /* Reading 7 bytes. */
 
          /* Addresses 0 and 1 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 1))
 
          {
 
            wdptr = address & 0x1;
 
            rdsize = 0xaul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            rdsize = 0xff;
 
          }
 
          break;
 
      }
 
      break;
 
    case 1:
 
      /* Reading 8 bytes. */
 
      /* Only even double-word address are valid. */
 
      if((address % 8) == 0)
 
      {
 
        wdptr = 0;
 
        rdsize = 0xbul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 2:
 
      /* Reading 16 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address % 8) == 0)
 
      {
 
        wdptr = 1;
 
        rdsize = 0xbul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 3:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 4:
 
      /* Reading 32 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 0;
 
        rdsize = 0xcul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 5:
 
    case 6:
 
    case 7:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 8:
 
      /* Reading 64 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        rdsize = 0xcul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 9:
 
    case 10:
 
    case 11:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 12:
 
      /* Reading 96 bytes. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 0;
 
        rdsize = 0xdul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 13:
 
    case 14:
 
    case 15:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 16:
 
      /* Reading 128 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        rdsize = 0xdul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 17:
 
    case 18:
 
    case 19:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 20:
 
      /* Reading 160 bytes. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 0;
 
        rdsize = 0xeul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 21:
 
    case 22:
 
    case 23:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 24:
 
      /* Reading 192 bytes. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        rdsize = 0xeul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 25:
 
    case 26:
 
    case 27:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 28:
 
      /* Reading 224 bytes. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 0;
 
        rdsize = 0xful;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    case 29:
 
    case 30:
 
    case 31:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
    case 32:
 
      /* Reading 256 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        rdsize = 0xful;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        rdsize = 0xff;
 
      }
 
      break;
 
    default:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      rdsize = 0xff;
 
      break;
 
  }
 
 
 
  return ((((uint16_t) rdsize) << 8) | ((uint16_t) wdptr));
 
}
 
 
 
 
 
void rdsizeToOffset(uint8_t rdsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
 
{
 
  switch(rdsize)
 
  {
 
    case 0:
 
    case 1:
 
    case 2:
 
    case 3:
 
      *offset = wdptr << 2;
 
      *offset |= rdsize;
 
      *size = 1;
 
      break;
 
    case 4:
 
    case 6:
 
      *offset = wdptr << 2;
 
      *offset |= rdsize & 0x02;
 
      *size = 2;
 
      break;
 
    case 5:
 
      *offset = wdptr * 5;
 
      *size = 3;
 
      break;
 
    case 8:
 
      *offset = wdptr * 4;
 
      *size = 4;
 
      break;
 
    case 7:
 
      *offset = wdptr * 3;
 
      *size = 5;
 
      break;
 
    case 9:
 
      *offset = wdptr * 2;
 
      *size = 6;
 
      break;
 
    case 10:
 
      *offset = wdptr * 1;
 
      *size = 7;
 
      break;
 
    case 11:
 
      *offset = 0;
 
      *size = 8 + 8*wdptr;
 
      break;
 
    case 12:
 
      *offset = 0;
 
      *size = 32 + 32*wdptr;
 
      break;
 
    case 13:
 
      *offset = 0;
 
      *size = 96 + 32*wdptr;
 
      break;
 
    case 14:
 
      *offset = 0;
 
      *size = 160 + 32*wdptr;
 
      break;
 
    case 15:
 
      *offset = 0;
 
      *size = 224 + 32*wdptr;
 
      break;
 
  }
 
}
 
 
 
 
 
static uint16_t wrsizeGet(const uint32_t address, const uint16_t size)
 
{
 
  uint8_t wdptr;
 
  uint8_t wrsize;
 
 
 
 
        /* Save the time when this was transmitted. */
 
        stack->txFrameTimeout[stack->txAckId] = stack->portTime;
 
 
  switch(size/8)
        /* Remember that this symbol has been transmitted. */
  {
        stack->txCounter = 1;
    case 0:
 
      /**************************************************************
 
       * Sub double-word access.
 
       **************************************************************/
 
      switch(size%8)
 
      {
 
        case 0:
 
          /* Not supported by protocol. */
 
          wdptr = 0xff;
 
          wrsize = 0xff;
 
          break;
 
        case 1:
 
          /* Writing one byte. */
 
          /* Any address is allowed. */
 
          wdptr = (address >> 2) & 0x1;
 
          wrsize = address & 0x3;
 
          break;
 
        case 2:
 
          /* Writing two bytes. */
 
          /* Address 0, 2, 4, 6 are valid. */
 
          if((address & 0x1) == 0)
 
          {
 
            wdptr = (address >> 2) & 0x1;
 
            wrsize = (address & 0x7) | 0x4;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            wrsize = 0xff;
 
          }
 
          break;
 
        case 3:
 
          /* Writing 3 bytes. */
 
          /* Address 0 and 5 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 5))
 
          {
 
            wdptr = (address >> 2) & 0x1;
 
            wrsize = 0x5ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            wrsize = 0xff;
 
          }
 
          break;
 
        case 4:
 
          /* Writing 4 bytes. */
 
          /* Address 0 and 4 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 4))
 
          {
 
            wdptr = (address >> 2) & 0x1;
 
            wrsize = 0x8ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            wrsize = 0xff;
 
          }
 
          break;
 
        case 5:
 
          /* Writing 5 bytes. */
 
          /* Address 0 and 3 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 3))
 
          {
 
            wdptr = (address >> 1) & 0x1;
 
            wrsize = 0x7ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            wrsize = 0xff;
 
          }
 
          break;
 
        case 6:
 
          /* Writing 6 bytes. */
 
          /* Addresses 0 and 2 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 2))
 
          {
 
            wdptr = (address >> 1) & 0x1;
 
            wrsize = 0x9ul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            wrsize = 0xff;
 
          }
 
          break;
 
        default:
 
          /* Writing 7 bytes. */
 
          /* Addresses 0 and 1 are valid. */
 
          if(((address & 0x7) == 0) ||
 
             ((address & 0x7) == 1))
 
          {
 
            wdptr = address & 0x1;
 
            wrsize = 0xaul;
 
          }
 
          else
 
          {
 
            /* Not supported by protocol. */
 
            wdptr = 0xff;
 
            wrsize = 0xff;
 
          }
 
          break;
 
      }
 
      break;
 
    case 1:
 
      /* Writing 8 bytes. */
 
      /* Only even double-word address are valid. */
 
      if((address % 8) == 0)
 
      {
 
        wdptr = 0;
 
        wrsize = 0xbul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        wrsize = 0xff;
 
      }
 
      break;
 
    case 2:
 
      /* Writing 16 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address % 8) == 0)
 
      {
 
        wdptr = 1;
 
        wrsize = 0xbul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        wrsize = 0xff;
 
      }
 
      break;
 
    case 3:
 
    case 4:
 
      /* Writing 32 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 0;
 
        wrsize = 0xcul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        wrsize = 0xff;
 
      }
 
      break;
 
    case 5:
 
    case 6:
 
    case 7:
 
    case 8:
 
      /* Writing 64 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        wrsize = 0xcul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        wrsize = 0xff;
 
      }
 
      break;
 
    case 9:
 
    case 10:
 
    case 11:
 
    case 12:
 
    case 13:
 
    case 14:
 
    case 15:
 
    case 16:
 
      /* Writing 128 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        wrsize = 0xdul;
 
      }
 
      else
 
      {
 
        /* Not supported by protocol. */
 
        wdptr = 0xff;
 
        wrsize = 0xff;
 
      }
 
      break;
 
    case 17:
 
    case 18:
 
    case 19:
 
    case 20:
 
    case 21:
 
    case 22:
 
    case 23:
 
    case 24:
 
    case 25:
 
    case 26:
 
    case 27:
 
    case 28:
 
    case 29:
 
    case 30:
 
    case 31:
 
    case 32:
 
      /* Writing 256 bytes max. */
 
      /* Only even double-word address are valid. */
 
      if((address & 0x7) == 0)
 
      {
 
        wdptr = 1;
 
        wrsize = 0xful;
 
      }
      }
      else
      else
      {
      {
        /* Not supported by protocol. */
        /* A link-request-symbol has been transmitted. */
        wdptr = 0xff;
 
        wrsize = 0xff;
 
      }
 
      break;
 
    default:
 
      /* Not supported by protocol. */
 
      wdptr = 0xff;
 
      wrsize = 0xff;
 
      break;
 
  }
 
 
 
  return ((((uint16_t) wrsize) << 8) | ((uint16_t) wdptr));
 
}
 
 
 
 
 
void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
 
{
 
  switch(wrsize)
 
  {
 
    case 0:
 
    case 1:
 
    case 2:
 
    case 3:
 
      *offset = wdptr << 2;
 
      *offset |= wrsize;
 
      *size = 1;
 
      break;
 
    case 4:
 
    case 6:
 
      *offset = wdptr << 2;
 
      *offset |= wrsize & 0x02;
 
      *size = 2;
 
      break;
 
    case 5:
 
      *offset = wdptr * 5;
 
      *size = 3;
 
      break;
 
    case 8:
 
      *offset = wdptr * 4;
 
      *size = 4;
 
      break;
 
    case 7:
 
      *offset = wdptr * 3;
 
      *size = 5;
 
      break;
 
    case 9:
 
      *offset = wdptr * 2;
 
      *size = 6;
 
      break;
 
    case 10:
 
      *offset = wdptr * 1;
 
      *size = 7;
 
      break;
 
    case 11:
 
      *offset = 0;
 
      *size = 8 + 8*wdptr;
 
      break;
 
    case 12:
 
      *offset = 0;
 
      *size = 32 + 32*wdptr;
 
      break;
 
    case 13:
 
      *offset = 0;
 
      *size = 128*wdptr;
 
      break;
 
    case 14:
 
      *offset = 0;
 
      *size = 0;
 
      break;
 
    case 15:
 
      *offset = 0;
 
      *size = 256*wdptr;
 
      break;
 
  }
 
}
 
 
 
 
 
static RioSymbol CreateControlSymbol( const uint8_t stype0,
 
                                      const uint8_t parameter0, const uint8_t parameter1,
 
                                      const uint8_t stype1, const uint8_t cmd)
 
{
 
  RioSymbol s;
 
 
 
  s.type = RIO_SYMBOL_TYPE_CONTROL;
 
 
 
  s.data = ((uint32_t)stype0 & (uint32_t)0x07ul) << 21;
 
  s.data |= ((uint32_t)parameter0 & (uint32_t)0x1ful) << 16;
 
  s.data |= ((uint32_t)parameter1 & (uint32_t)0x1ful) << 11;
 
  s.data |= ((uint32_t)stype1 & (uint32_t)0x07ul) << 8;
 
  s.data |= ((uint32_t)cmd & (uint32_t)0x7ul) << 5;
 
  s.data |= Crc5(s.data, 0x1fu);
 
 
 
  return s;
 
}
 
 
 
 
 
static uint8_t Crc5( const uint32_t data, const uint8_t crc)
 
{
 
  static const uint8_t crcTable[] = {
 
    0x00u, 0x15u, 0x1fu, 0x0au, 0x0bu, 0x1eu, 0x14u, 0x01u,
 
    0x16u, 0x03u, 0x09u, 0x1cu, 0x1du, 0x08u, 0x02u, 0x17u,
 
    0x19u, 0x0cu, 0x06u, 0x13u, 0x12u, 0x07u, 0x0du, 0x18u,
 
    0x0fu, 0x1au, 0x10u, 0x05u, 0x04u, 0x11u, 0x1bu, 0x0eu
 
  };
 
 
 
  uint8_t result;
 
  uint8_t index;
 
 
 
  result = crc;
 
  index  = (uint8_t)((data >> 19) & (uint32_t)0x1ful) ^ result;
 
  result = crcTable[index];
 
  index  = (uint8_t)((data >> 14) & (uint32_t)0x1ful) ^ result;
 
  result = crcTable[index];
 
  index  = (uint8_t)((data >> 9) & (uint32_t)0x1ful) ^ result;
 
  result = crcTable[index];
 
  index  = (uint8_t)((data >> 4) & (uint32_t)0x1eul) ^ result;
 
  result = crcTable[index];
 
 
 
  return result;
 
}
 
 
 
 
 
static uint16_t Crc16( const uint16_t data, const uint16_t crc)
 
{
 
  static const uint16_t crcTable[] = {
 
    0x0000u, 0x1021u, 0x2042u, 0x3063u, 0x4084u, 0x50a5u, 0x60c6u, 0x70e7u,
 
    0x8108u, 0x9129u, 0xa14au, 0xb16bu, 0xc18cu, 0xd1adu, 0xe1ceu, 0xf1efu,
 
    0x1231u, 0x0210u, 0x3273u, 0x2252u, 0x52b5u, 0x4294u, 0x72f7u, 0x62d6u,
 
    0x9339u, 0x8318u, 0xb37bu, 0xa35au, 0xd3bdu, 0xc39cu, 0xf3ffu, 0xe3deu,
 
    0x2462u, 0x3443u, 0x0420u, 0x1401u, 0x64e6u, 0x74c7u, 0x44a4u, 0x5485u,
 
    0xa56au, 0xb54bu, 0x8528u, 0x9509u, 0xe5eeu, 0xf5cfu, 0xc5acu, 0xd58du,
 
    0x3653u, 0x2672u, 0x1611u, 0x0630u, 0x76d7u, 0x66f6u, 0x5695u, 0x46b4u,
 
    0xb75bu, 0xa77au, 0x9719u, 0x8738u, 0xf7dfu, 0xe7feu, 0xd79du, 0xc7bcu,
 
    0x48c4u, 0x58e5u, 0x6886u, 0x78a7u, 0x0840u, 0x1861u, 0x2802u, 0x3823u,
 
    0xc9ccu, 0xd9edu, 0xe98eu, 0xf9afu, 0x8948u, 0x9969u, 0xa90au, 0xb92bu,
 
    0x5af5u, 0x4ad4u, 0x7ab7u, 0x6a96u, 0x1a71u, 0x0a50u, 0x3a33u, 0x2a12u,
 
    0xdbfdu, 0xcbdcu, 0xfbbfu, 0xeb9eu, 0x9b79u, 0x8b58u, 0xbb3bu, 0xab1au,
 
    0x6ca6u, 0x7c87u, 0x4ce4u, 0x5cc5u, 0x2c22u, 0x3c03u, 0x0c60u, 0x1c41u,
 
    0xedaeu, 0xfd8fu, 0xcdecu, 0xddcdu, 0xad2au, 0xbd0bu, 0x8d68u, 0x9d49u,
 
    0x7e97u, 0x6eb6u, 0x5ed5u, 0x4ef4u, 0x3e13u, 0x2e32u, 0x1e51u, 0x0e70u,
 
    0xff9fu, 0xefbeu, 0xdfddu, 0xcffcu, 0xbf1bu, 0xaf3au, 0x9f59u, 0x8f78u,
 
    0x9188u, 0x81a9u, 0xb1cau, 0xa1ebu, 0xd10cu, 0xc12du, 0xf14eu, 0xe16fu,
 
    0x1080u, 0x00a1u, 0x30c2u, 0x20e3u, 0x5004u, 0x4025u, 0x7046u, 0x6067u,
 
    0x83b9u, 0x9398u, 0xa3fbu, 0xb3dau, 0xc33du, 0xd31cu, 0xe37fu, 0xf35eu,
 
    0x02b1u, 0x1290u, 0x22f3u, 0x32d2u, 0x4235u, 0x5214u, 0x6277u, 0x7256u,
 
    0xb5eau, 0xa5cbu, 0x95a8u, 0x8589u, 0xf56eu, 0xe54fu, 0xd52cu, 0xc50du,
 
    0x34e2u, 0x24c3u, 0x14a0u, 0x0481u, 0x7466u, 0x6447u, 0x5424u, 0x4405u,
 
    0xa7dbu, 0xb7fau, 0x8799u, 0x97b8u, 0xe75fu, 0xf77eu, 0xc71du, 0xd73cu,
 
    0x26d3u, 0x36f2u, 0x0691u, 0x16b0u, 0x6657u, 0x7676u, 0x4615u, 0x5634u,
 
    0xd94cu, 0xc96du, 0xf90eu, 0xe92fu, 0x99c8u, 0x89e9u, 0xb98au, 0xa9abu,
 
    0x5844u, 0x4865u, 0x7806u, 0x6827u, 0x18c0u, 0x08e1u, 0x3882u, 0x28a3u,
 
    0xcb7du, 0xdb5cu, 0xeb3fu, 0xfb1eu, 0x8bf9u, 0x9bd8u, 0xabbbu, 0xbb9au,
 
    0x4a75u, 0x5a54u, 0x6a37u, 0x7a16u, 0x0af1u, 0x1ad0u, 0x2ab3u, 0x3a92u,
 
    0xfd2eu, 0xed0fu, 0xdd6cu, 0xcd4du, 0xbdaau, 0xad8bu, 0x9de8u, 0x8dc9u,
 
    0x7c26u, 0x6c07u, 0x5c64u, 0x4c45u, 0x3ca2u, 0x2c83u, 0x1ce0u, 0x0cc1u,
 
    0xef1fu, 0xff3eu, 0xcf5du, 0xdf7cu, 0xaf9bu, 0xbfbau, 0x8fd9u, 0x9ff8u,
 
    0x6e17u, 0x7e36u, 0x4e55u, 0x5e74u, 0x2e93u, 0x3eb2u, 0x0ed1u, 0x1ef0u
 
  };
 
 
 
  uint16_t result;
 
  uint8_t index;
 
 
 
  result = crc;
 
  index = (uint8_t) ((data >> 8)  ^ (result >> 8));
 
  result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
 
  index = (uint8_t) ((data)  ^ (result >> 8));
 
  result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
 
 
 
  return result;
 
}
 
 
 
 
 
static uint16_t Crc32( const uint32_t data, uint16_t crc)
 
{
 
  crc = Crc16((uint16_t) (data >> 16), crc);
 
  crc = Crc16((uint16_t) (data), crc);
 
  return crc;
 
}
 
 
 
 
 
 
 
 
 
 
 
static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer)
 
{
 
  Queue_t q;
 
 
 
  q.size = size;
 
  q.available = size;
 
  q.windowSize = 0u;
 
  q.windowIndex = 0u;
 
  q.frontIndex = 0u;
 
  q.backIndex = 0u;
 
  q.buffer_p = buffer;
 
 
 
  return q;
 
}
 
 
 
 
 
static uint8_t QueueAvailable( const Queue_t q)
 
{
 
  return q.available;
 
}
 
 
 
 
 
static bool_t QueueEmpty( const Queue_t q)
 
{
 
  return (bool_t) (q.available == q.size);
 
}
 
 
 
 
 
static uint8_t QueueLength( const Queue_t q)
 
{
 
  return q.size - q.available;
 
}
 
 
 
 
 
static Queue_t QueueEnqueue( Queue_t q)
 
{
 
  q.backIndex++;
 
  if(q.backIndex == q.size)
 
  {
 
    q.backIndex = 0;
 
  }
 
  q.available--;
 
  return q;
 
}
 
 
 
 
 
static Queue_t QueueDequeue( Queue_t q)
        /* Check if the link partner reply has timed out. */
{
        if((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout)
  q.frontIndex++;
 
  if(q.frontIndex == q.size)
 
  {
 
    q.frontIndex = 0;
 
  }
 
  q.available++;
 
  if(q.windowSize == 0)
 
  {
  {
    q.windowIndex = q.frontIndex;
          /* No timeout. */
 
 
 
          /* A link-request-symbol has been transmitted. */
 
          /* Send only idle-symbols until the link-response is received. */
 
          s.type = RIOSTACK_SYMBOL_TYPE_IDLE;
  }
  }
  else
  else
  {
  {
    q.windowSize--;
          /* Link response timeout. */
  }
 
  return q;
 
}
 
 
 
 
 
static bool_t QueueWindowEmpty( const Queue_t q)
          /* Check if the link-partner has not responded for too many times. */
 
          if(stack->txCounter < 5)
{
{
  return (bool_t) ((q.available + q.windowSize) == q.size);
            /* Not too many timeouts. */
}
            /* Retry and send a new link-request. */
 
 
 
 
static Queue_t QueueWindowReset(Queue_t q)
            /* Send link-request-symbol (input-status). */
{
            s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
  q.windowIndex = q.frontIndex;
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
  q.windowSize = 0;
 
  return q;
 
}
 
 
 
 
            /* Save the time when this was transmitted. */
 
            stack->txFrameTimeout[stack->txAckId] = stack->portTime;
 
 
static Queue_t QueueWindowNext(Queue_t q)
            /* Increment the number of times we have retransmitted the link-request. */
{
            stack->txCounter++;
  q.windowIndex++;
          }
  if(q.windowIndex == q.size)
          else
  {
  {
    q.windowIndex = 0;
            /* The link partner has not answered for too many times. */
 
            /* Give up and set the state to uninitialized. */
 
            stack->txState = TX_STATE_UNINITIALIZED;
 
            s.type = RIOSTACK_SYMBOL_TYPE_IDLE;
 
            ASSERT0("No link-response received, giving up.");
 
          }
  }
  }
  q.windowSize++;
 
  return q;
 
}
}
 
      break;
 
 
 
    case TX_STATE_UNINITIALIZED:
 
    default:
 
      /******************************************************************************
 
       * Wait for the port to be initialized.
 
       ******************************************************************************/
 
 
static void QueueSetSize( Queue_t q, const uint32_t size)
      /* Send only idle symbols. */
{
      s.type = RIOSTACK_SYMBOL_TYPE_IDLE;
  (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[0] = size;
      break;
}
}
 
 
 
  /* Return the created symbol. */
static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content)
  return s;
{
 
  (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[index+1ul] = content;
 
}
}
 
 
 
 
static uint32_t QueueGetFrontSize( Queue_t q)
 
{
 
  return (q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[0];
 
}
 
 
 
 
/*******************************************************************************
 
 * Local RapidIO stack helper functions.
 
 *******************************************************************************/
 
 
static uint32_t QueueGetFrontContent( const Queue_t q, const uint32_t index)
static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
{
{
  return (q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[index+1ul];
  /* Update the buffer status of the link partner. */
 
  (void) ackId;
 
  stack->txBufferStatus = bufferStatus;
}
}
 
 
 
 
static uint32_t *QueueGetFrontBuffer( const Queue_t q )
 
 
static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
{
{
  return &((q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[1]);
  uint32_t linkLatency;
}
 
 
 
 
 
static uint32_t QueueGetBackSize( const Queue_t q)
  /* Check if an acknowledge is expected and that it is for a transmitted packet. */
 
  if((stack->txAckId != stack->txAckIdWindow) && (ackId == stack->txAckId))
{
{
  return (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[0];
    /* Acknowledge for a recently transmitted packet received. */
}
 
 
 
 
 
static uint32_t *QueueGetBackBuffer( const Queue_t q )
    /* Check if the latency of this packet is larger than the largest encountered so far. */
 
    linkLatency = stack->portTime - stack->txFrameTimeout[ackId];
 
    if(linkLatency > stack->statusOutboundLinkLatencyMax)
{
{
  return &((q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[1]);
      stack->statusOutboundLinkLatencyMax = linkLatency;
}
}
 
 
 
    /* Remove the packet from the outbound queue and restart the transmission for
#ifdef MODULE_TEST
       a new packet. */
#include <stdio.h>
    stack->txQueue = QueueDequeue(stack->txQueue);
#define PrintS(s)                                \
    stack->txAckId = ACKID_INC(stack->txAckId);
  {                                               \
    stack->statusOutboundPacketComplete++;
    FILE *fd;                                     \
 
    fd=fopen("testspec.txt", "a");                \
 
    fputs(s "\n", fd);                                 \
 
    fclose(fd);                                   \
 
  }
  }
 
  else
#define TESTSTART(s) printf(s)
  {
#define TESTEND printf(" passed.\n");
    /* Acknowledge for an unexpected ackId or not waiting for an acknowledge. */
 
    /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
#define TESTCOND(got)                           \
    stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
  if (!(got))                                   \
    stack->txCounter = 0u;
  {                                             \
    stack->statusOutboundErrorPacketAccepted++;
    printf("ERROR at line %u:%s=%u (0x%08x)\n", \
 
           __LINE__, #got, (got), (got));       \
 
    exit(1);                                    \
 
  }
  }
 
 
#define TESTEXPR(got, expected)                                         \
  /* Update the buffer status of the link partner. */
  if ((got)!=(expected))                                                \
  stack->txBufferStatus = bufferStatus;
  {                                                                     \
 
    printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",    \
 
           __LINE__, #got, (got), (got), (expected), (expected));       \
 
    exit(1);                                                            \
 
  }
  }
 
 
#define TESTSYMBOL(got, expected) testSymbol(__LINE__, #got, (got), (expected))
 
 
 
void testSymbol(uint32_t line, char *expression, RioSymbol got, RioSymbol expected)
 
{
static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
  if ((got).type==(expected).type)
 
  {
 
    switch ((got).type)
 
    {
 
      case RIO_SYMBOL_TYPE_ERROR:
 
      case RIO_SYMBOL_TYPE_IDLE:
 
        break;
 
      case RIO_SYMBOL_TYPE_CONTROL:
 
        if((got).data != (expected).data)
 
        {
 
          if(STYPE0_GET((got).data) != STYPE0_GET((expected).data))
 
          {
 
            printf("ERROR at line %u:STYPE0=0x%02x expected=0x%02x\n",
 
                   line, STYPE0_GET((got).data), STYPE0_GET((expected).data));
 
          }
 
          if(PARAMETER0_GET((got).data) != PARAMETER0_GET((expected).data))
 
          {
 
            printf("ERROR at line %u:PARAMETER0=0x%02x expected=0x%02x\n",
 
                   line, PARAMETER0_GET((got).data), PARAMETER0_GET((expected).data));
 
          }
 
          if(PARAMETER1_GET((got).data) != PARAMETER1_GET((expected).data))
 
          {
 
            printf("ERROR at line %u:PARAMETER1=0x%02x expected=0x%02x\n",
 
                   line, PARAMETER1_GET((got).data), PARAMETER1_GET((expected).data));
 
          }
 
          if(STYPE1_GET((got).data) != STYPE1_GET((expected).data))
 
          {
 
            printf("ERROR at line %u:STYPE1=0x%02x expected=0x%02x\n",
 
                   line, STYPE1_GET((got).data), STYPE1_GET((expected).data));
 
          }
 
          if(CMD_GET((got).data) != CMD_GET((expected).data))
 
          {
 
            printf("ERROR at line %u:CMD=0x%02x expected=0x%02x\n",
 
                   line, CMD_GET((got).data), CMD_GET((expected).data));
 
          }
 
          if(CRC5_GET((got).data) != CRC5_GET((expected).data))
 
          {
          {
            printf("ERROR at line %u:CRC5=0x%02x expected=0x%02x\n",
  /* Check if the retried packet ackId is acceptable. */
                   line, CRC5_GET((got).data), CRC5_GET((expected).data));
  if(ackId == stack->txAckId)
          }
 
          exit(1);
 
        }
 
        break;
 
      case RIO_SYMBOL_TYPE_DATA:
 
        if((got).data != (expected).data)
 
        {
        {
          printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",
    /* The request for retry is for the current packet. */
                 line, expression, (got).data, (got).data, (expected).data, (expected).data);
    /* Force the transmitter to send a RESTART-FROM-RETRY symbol. */
          exit(1);
    stack->txState = TX_STATE_OUTPUT_RETRY_STOPPED;
        }
    stack->statusOutboundPacketRetry++;
        break;
 
    }
 
  }
  }
  else
  else
  {
  {
    printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",
    /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
           line, expression, (got).type, (got).type, (expected).type, (expected).type);
    stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
    exit(1);
    stack->txCounter = 0u;
  }
    stack->statusOutboundErrorPacketRetry++;
}
}
 
 
 
  /* Update the buffer status of the link partner. */
 
  stack->txBufferStatus = bufferStatus;
 
}
 
 
 
 
uint32_t testConfigWriteData;
 
 
 
uint8_t createDoorbell(uint32_t *doorbell, uint8_t ackId, uint16_t destid, uint16_t srcId, uint8_t tid, uint16_t info)
static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause)
{
{
  uint16_t crc;
  (void) arbitrary;
  uint32_t content;
 
 
 
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
 
  /* ackId is set when the packet is transmitted. */
 
  content = 0x001aul << 16;
 
  content |= (uint32_t) destid;
 
  crc = Crc32(content, 0xffffu);
 
  doorbell[0] = (((uint32_t) ackId) << 27) | content;
 
 
 
  /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
 
  content = ((uint32_t) srcId) << 16;
 
  content |= (uint32_t) tid;
 
  crc = Crc32(content, crc);
 
  doorbell[1] = content;
 
 
 
  /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
 
  content = ((uint32_t) info) << 16;
 
  crc = Crc16(info, crc);
 
  content |= ((uint32_t) crc);
 
  doorbell[2] = content;
 
 
 
  return 3;
 
 
 
}
 
 
 
uint32_t testConfigRead(RioStack_t *stack, uint32_t offset)
  /* Force the transmitter to enter output-error-stopped state. */
{
  stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
  switch(offset)
  stack->txCounter = 0u;
  {
 
    case 0:
 
      return 0x80000006;
 
    case 4:
 
      return 0x00a100a2;
 
    case 8:
 
      return testConfigWriteData;
 
    default:
 
      return 0x00000000;
 
  }
 
}
 
 
 
void testConfigWrite(RioStack_t *stack, uint32_t offset, uint32_t data)
  /* Record the type of error that caused the packet to not being accepted. */
{
  switch(cause)
  switch(offset)
 
  {
  {
    case 8:
    case PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID:
      testConfigWriteData = data;
      stack->statusPartnerErrorPacketAckId++;
 
      break;
 
    case PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC:
 
      stack->statusPartnerErrorControlCrc++;
 
      break;
 
    case PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC:
 
      stack->statusPartnerErrorPacketCrc++;
 
      break;
 
    case PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER:
 
      stack->statusPartnerErrorIllegalCharacter++;
      break;
      break;
    default:
    default:
      /* Dont do anything. */
      stack->statusPartnerErrorGeneral++;
      break;
      break;
  }
  }
}
}
 
 
/*******************************************************************************
 
 * Module test for this file.
 
 *******************************************************************************/
 
int32_t main(void)
 
{
 
  RioStack_t stack;
 
  RioStackObserver_t observer;
 
  uint32_t rxPacketBuffer[RIO_BUFFER_SIZE*8], txPacketBuffer[RIO_BUFFER_SIZE*8];
 
  RioSymbol s, c, d;
 
  int i, j, k;
 
  uint16_t length;
 
  uint16_t srcid;
 
  uint8_t tid;
 
  uint8_t hop;
 
  uint8_t mailbox;
 
  uint16_t info;
 
  uint32_t address;
 
  uint32_t data;
 
  uint8_t payload8[256];
 
  uint8_t payload8Expected[256];
 
  uint32_t packet[69];
 
  uint32_t packetLength;
 
 
 
 
 
  /*************************************************************************
 
   * Test prelude.
 
   * Setup the RIO stack for operation.
 
   *************************************************************************/
 
 
 
  /* Setup callback handlers for config-space accesses in the implementation-
 
     defined address range. */
 
  observer.configRead = testConfigRead;
 
  observer.configWrite = testConfigWrite;
 
 
 
  /* Open the stack and set the port status to initialized. */
 
  RIO_open(&stack, &observer, NULL,
 
           RIO_BUFFER_SIZE*8, &rxPacketBuffer[0],
 
           RIO_BUFFER_SIZE*8, &txPacketBuffer[0],
 
           0xb03b, 0x0000, 0x00000000, 0x0000, 0x0000, 0x0000, 0xffff);
 
 
 
  /* Set the port timeout. */
 
  RIO_portSetTimeout(&stack, 1);
 
 
 
  /* Set the current port time. */
 
  RIO_portSetTime(&stack, 0);
 
 
 
  /* Set master enable. */
 
  RIO_writeConfig(&stack,
 
                  PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET), 0x40000000);
 
 
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC1");
 
  PrintS("Description: Test link initialization and normal packet exchange.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send packets when port is uninitialized.");
 
  PrintS("Result: All packets should be ignored during initialization.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step1");
 
  /******************************************************************************/
 
 
 
  /* Place a packet in the outbound queue to check that it is received once
 
     the transmitter is placed in the correct state. */
 
  RIO_sendDoorbell(&stack, 1, 0, 0xdeaf);
 
 
 
  /* Check that only idle symbols are transmitted when the port has not been
 
     initialied even if statuses are received. */
 
  for(i = 0; i < 1024; i++)
 
  {
 
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /*****************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Set port initialized and get symbols from the stack.");
 
  PrintS("Result: Status-control-symbols should be generated each 256 symbol.");
 
  PrintS("----------------------------------------------------------------------");
 
  /*****************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step2");
 
  /*****************************************************************************/
 
 
 
  /* Set the port status to intialized. */
 
  RIO_portSetStatus(&stack, 1);
 
 
 
  /* Set port time. */
 
  RIO_portSetTime(&stack, 1);
 
 
 
  /* Check that status-control-symbols are transmitted once every 256 symbol. */
 
  for(j = 0; j < 15; j++)
 
  {
 
    for(i = 0; i < 255; i++)
 
    {
 
      s = RIO_portGetSymbol(&stack);
 
      TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
    }
 
    s = RIO_portGetSymbol(&stack);
 
    c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0);
 
    TESTEXPR(s.type, c.type);
 
    TESTEXPR(s.data, c.data);
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Add a status-control-symbol to the receiver.");
 
  PrintS("Result: Status-control-symbols should be generated each 15 symbol.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step3");
 
  /*****************************************************************************/
 
 
 
  /* Insert a status-control-symbol in the receive. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that status-control-symbols are transmitted once every 16 symbol. */
 
  for(i = 0; i < 15; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
 
  s = RIO_portGetSymbol(&stack);
 
  c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 4:");
 
  PrintS("Action: Add a packet to the receiver.");
 
  PrintS("Result: Packet should be ignored until the link is initialized.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step4");
 
  /*****************************************************************************/
 
 
 
  /* Send a packet. Note that the start and end of the packet contains a status. */
 
  packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that packet was not received. */
 
  TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_NONE);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 5:");
 
  PrintS("Action: Add four more status-control-symbols followed by one with error in ");
 
  PrintS("        CRC5. Then send a packet.");
 
  PrintS("Result: The receiver should remain in port initialized and packet should ");
 
  PrintS("        still be ignored.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step5");
 
  /*****************************************************************************/
 
 
 
  /* Send 4 more status-control-symbols followed by one erronous. */
 
  for(i = 0; i < 4; i++)
 
  {
 
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0);
 
  c.data ^= 1;
 
  RIO_portAddSymbol(&stack, c);
 
 
 
  /* Send a packet. Note that the start and end of the packet contains status. */
 
  packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that the packet was ignored. */
 
  TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_NONE);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 6:");
 
  PrintS("Action: Add six more status-control-symbols. Then send a packet.");
 
  PrintS("Result: The receiver should enter link initialized and the packet should ");
 
  PrintS("        be received.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step6");
 
  /*****************************************************************************/
 
 
 
  /* Send 6 more status-control-symbols. */
 
  for(i = 0; i < 6; i++)
 
  {
 
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
 
  }
 
 
 
  /* Send a packet and check that it is accepted. */
 
  /* The ackId on receiver in testobject is updated when this has been transmitted. */
 
  packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that the packet is received. */
 
  TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_DOORBELL);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 7:");
 
  PrintS("Action: Get symbols from transmitter.");
 
  PrintS("Result: Status-control-symbols should still be generated each 15 symbol ");
 
  PrintS("until a total of 15 status-control-symbols has been transmitted. Once these ");
 
  PrintS("has been transmitted, the transmitter will be link initialized.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step7");
 
  /*****************************************************************************/
 
 
 
  /* Note that the available buffers in the receiver should have decremented once
 
     since the previously received packet has not been read from the application
 
     side of the stack yet. */
 
  for(j = 0; j < 14; j++)
 
  {
 
    for(i = 0; i < 15; i++)
 
    {
 
      s = RIO_portGetSymbol(&stack);
 
      TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
    }
 
    s = RIO_portGetSymbol(&stack);
 
    c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_NOP, 0);
 
    TESTEXPR(s.type, c.type);
 
    TESTEXPR(s.data, c.data);
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 8:");
 
  PrintS("Action: Get the first symbol from the transmitter once the link-intialized ");
 
  PrintS("        state has been entered.");
 
  PrintS("Result: A packet-accepted-symbol should be received for the newly received ");
 
  PrintS("        packet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step8");
 
  /*****************************************************************************/
 
 
 
  c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 7, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 9:");
 
  PrintS("Action: Get the next symbols from the transmitter.");
 
  PrintS("Result: The packet placed in the outbound queue at startup should be ");
 
  PrintS("        received. Dont acknowledge the packet yet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step9");
 
  /*****************************************************************************/
 
 
 
  /* Create a packet. */
 
  packetLength = createDoorbell(packet, 0, 1, 0xffff, 0, 0xdeaf);
 
 
 
  /* Receive the start of the frame. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Receive the data of the frame. */
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
 
 
  /* Receive the end of the frame. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTSYMBOL(s, c);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 10:");
 
  PrintS("Action: Remove the packet from the inbound queue. Dont acknowledge the");
 
  PrintS("        transmitted packet yet.");
 
  PrintS("Result: Check that status-control-symbols are sent each 256 symbol and that ");
 
  PrintS("        the buffer count is updated when the inbound packet has been read.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step10");
 
  /*****************************************************************************/
 
 
 
  /* Simulate the application reading the received packet to free one reception
 
     buffer. */
 
  RIO_packetRemove(&stack);
 
 
 
  /* Check that the status-control-symbols are generated each 256 symbol. */
 
  for(i = 0; i < 255; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
 
 
 
  /* Check that the buffer status has been updated. */
 
  s = RIO_portGetSymbol(&stack);
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 11:");
 
  PrintS("Action: Send a packet when an acknowledge has not been received.");
 
  PrintS("Result: Only idle and status control symbols should be transmitted until ");
 
  PrintS("        the packet-accepted symbol has been received.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step11");
 
  /*****************************************************************************/
 
 
 
  /* Place a packet in the outbound queue. */
 
  RIO_sendDoorbell(&stack, 2, 1, 0xc0de);
 
 
 
  packetLength = createDoorbell(packet, 1, 2, 0xffff, 1, 0xc0de);
 
 
 
  /* Receive the start of the frame. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Receive the data of the frame. */
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
 
 
  /* Receive the end of the frame. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTSYMBOL(s, c);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 12:");
 
  PrintS("Action: Send a packet-accepted symbol.");
 
  PrintS("Result: Check that the new packet is transmitted.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step12");
 
  /*****************************************************************************/
 
 
 
  /* Send acknowledge for the first frame. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that status-control-symbols are transmitted once every 256 symbol with
 
     updated ackId. */
 
  for(i = 0; i < 255; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
 
  s = RIO_portGetSymbol(&stack);
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 13:");
 
  PrintS("Action: Send a packet-accepted symbol.");
 
  PrintS("Result: Check that only idle and status-control-symbols are transmitted ");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC1-Step13");
 
  /*****************************************************************************/
 
 
 
  /* Acknowledge the second frame. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that status-control-symbols are transmitted once every 256 symbol with
 
     updated ackId. */
 
  for(i = 0; i < 255; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
 
  s = RIO_portGetSymbol(&stack);
 
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC2");
 
  PrintS("Description: Test flow control.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send packets to receiver but don't acknowledge them.");
 
  PrintS("Result: The reception queue of the stack is full.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step1");
 
  /******************************************************************************/
 
 
 
  /* Fill input queue in receiver. */
 
  for(j = 0; j < 8; j++)
 
  {
 
    packetLength = createDoorbell(packet, 1+j, 0, 0, 1+j, 0);
 
 
 
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
 
    for(i = 0; i < packetLength; i++)
 
    {
 
      d.type = RIO_SYMBOL_TYPE_DATA;
 
      d.data = packet[i];
 
      RIO_portAddSymbol(&stack, d);
 
    }
 
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
 
 
 
    c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1+j, 7-j, STYPE1_NOP, 0);
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, c.type);
 
    TESTEXPR(s.data, c.data);
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send a packet when the inbound queue of the stack is full.");
 
  PrintS("Result: The stack sends a packet-retry symbol. The receiver will end up in ");
 
  PrintS("input-retry-stopped state.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step2");
 
  /******************************************************************************/
 
 
 
  /* Send another packet. */
 
  packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Receive indication from stack that the packet must be retried. */
 
  c = CreateControlSymbol(STYPE0_PACKET_RETRY, 9, 0, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Send a packet when the receiver is in input-retry-stopped.");
 
  PrintS("Result: The receiver should ignore the new packet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step3");
 
  /******************************************************************************/
 
 
 
  /* Resend the packet. */
 
  packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
 
  s = RIO_portGetSymbol(&stack);
 
 
 
  /* Check that nothing is transmitted. */
 
  TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
 
 
  /* REMARK: Send other symbols here to check that they are handled as expected... */
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 4:");
 
  PrintS("Action: Send restart-from-retry and resend the previous packet.");
 
  PrintS("Result: The receiver should leave the input-retry-stopped state and receive ");
 
  PrintS("        the new frame.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step4");
 
  /******************************************************************************/
 
 
 
  /* Send restart-from-retry. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_RESTART_FROM_RETRY, 0));
 
 
 
  /* Check that the transaction id is correct and remove a packet from the inbound
 
     queue. One entry in the inbound queue will be empty. */
 
  RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
 
  TESTEXPR(tid, 1);
 
  RIO_packetRemove(&stack);
 
 
 
  /* Check that the buffer status has changed to show that a buffer is available. */
 
  s = RIO_portGetSymbol(&stack);
 
  while(s.type == RIO_SYMBOL_TYPE_IDLE)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Resend the packet and check that it is received. */
 
  packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
 
  c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 0, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 5:");
 
  PrintS("Action: Place receiver in input-retry-stopped state.");
 
  PrintS("Result: Check that packets may be transmitted normally.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step5");
 
  /******************************************************************************/
 
 
 
  /* Send another packet and check that the receiver indicates that it should be retried. */
 
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
 
  c = CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 0, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send two packets to see that the first acknowledge has been processed. */
 
  RIO_sendDoorbell(&stack, 0, 2, 0xfeed);
 
  RIO_sendDoorbell(&stack, 0, 3, 0xdeed);
 
 
 
  /* Get the first packet. */
 
  packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
 
 
  /* Get the second packet. */
 
  packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTSYMBOL(s, c);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Indicate the packets must be retransmitted. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 2, 1, STYPE1_NOP, 0));
 
 
 
  /* Receive confirmation that the packet will be retransmitted. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTSYMBOL(s, c);
 
 
 
  /* Get the retransmission of the first packet. */
 
  packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
 
 
  /* Get the retransmission of the second packet. */
 
  packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTSYMBOL(s, c);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Confirm the reception of the packets. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 2, 1, STYPE1_NOP, 0));
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 3, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 6:");
 
  PrintS("Action: Send status-control-symbol to show that no packets can be ");
 
  PrintS("        transmitted.");
 
  PrintS("Result: No packets should be transmitted.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step6");
 
  /******************************************************************************/
 
 
 
  /* Send status with bufferStatus set to zero. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 0, STYPE1_NOP, 0));
 
 
 
  /* Send a packet. */
 
  RIO_sendDoorbell(&stack, 0, 4, 0xf00d);
 
 
 
  /* Check that nothing is transmitted but status-control-symbols. */
 
  for(i = 0; i < 255; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
 
  s = RIO_portGetSymbol(&stack);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_NOP, 0);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 7:");
 
  PrintS("Action: Indicate free buffers and receive a frame, then request it to be ");
 
  PrintS("retried.");
 
  PrintS("Result: The packet should be retransmitted.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step7");
 
  /******************************************************************************/
 
 
 
  /* Send status with bufferStatus set to available. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 1, STYPE1_NOP, 0));
 
 
 
  /* Get the packet but request it to be retried. */
 
  packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 4, 1, STYPE1_NOP, 0));
 
 
 
  /* Check the acknowledge of the retransmission. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Get the packet and acknowledge it. */
 
  packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 4, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 8:");
 
  PrintS("Action: Read all inbound packets from the reception queue.");
 
  PrintS("Result: The buffer status should be updated.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step8");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 8; j++)
 
  {
 
    RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
 
    TESTEXPR(tid, j+2);
 
    RIO_packetRemove(&stack);
 
 
 
    for(i = 0; i < 255; i++)
 
    {
 
      s = RIO_portGetSymbol(&stack);
 
      TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
    }
 
    s = RIO_portGetSymbol(&stack);
 
    c = CreateControlSymbol(STYPE0_STATUS, 10, j+1, STYPE1_NOP, 0);
 
    TESTEXPR(s.type, c.type);
 
    TESTEXPR(s.data, c.data);
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 9:");
 
  PrintS("Action: Send a restart-from-retry to make the receiver leave the ");
 
  PrintS("        input-retry-stopped state.");
 
  PrintS("Result: New packets should be received again.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC2-Step9");
 
  /******************************************************************************/
 
 
 
  /* Send restart-from-retry. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_RESTART_FROM_RETRY, 0));
 
 
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC3");
 
  PrintS("Description: Test receiver error handling.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send invalid ack id in packet.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate an ackId error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step1");
 
  /******************************************************************************/
 
 
 
  /* Send packet with invalid ackId, same as sent previously. */
 
  packetLength = createDoorbell(packet, 9, 0, 0, 10, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 1, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send packet with invalid CRC.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate a CRC error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step2");
 
  /******************************************************************************/
 
 
 
  /* Send packet with invalid crc. */
 
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
 
  packet[0] ^= 0x00000001;
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Send a packet that is too short.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate a packet error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step3");
 
  /******************************************************************************/
 
 
 
  /* Send packet with valid ackid and crc but too short. */
 
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
 
  d.type = RIO_SYMBOL_TYPE_DATA;
 
  d.data = packet[0];
 
  RIO_portAddSymbol(&stack, d);
 
  d.type = RIO_SYMBOL_TYPE_DATA;
 
  d.data = ((uint32_t) Crc32(packet[0] & 0x07ffffff, 0xffff)) << 16;
 
  RIO_portAddSymbol(&stack, d);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 4:");
 
  PrintS("Action: Send a packet that is too long.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate a packet error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step4");
 
  /******************************************************************************/
 
 
 
  /* Send packet with too many data symbols and without a end-of-packet. */
 
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
 
  for(i = 0; i < 70; i++)
 
  {
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    RIO_portAddSymbol(&stack, d);
 
  }
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 5:");
 
  PrintS("Action: Send a data symbol without starting a packet.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate a packet error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step5");
 
  /******************************************************************************/
 
 
 
  /* Send a data symbol. */
 
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
 
  d.type = RIO_SYMBOL_TYPE_DATA;
 
  d.data = packet[0];
 
  RIO_portAddSymbol(&stack, d);
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 6:");
 
  PrintS("Action: Send end-of-packet without matching start.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate a packet error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step6");
 
  /******************************************************************************/
 
 
 
  /* Send end-of-packet. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 7:");
 
  PrintS("Action: Send a symbol indicating a codec error.");
 
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
 
  PrintS("        should indicate a symbol error.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC3-Step7");
 
  /******************************************************************************/
 
 
 
  /* Send error-symbol. */
 
  s.type = RIO_SYMBOL_TYPE_ERROR;
 
  RIO_portAddSymbol(&stack, s);
 
 
 
  /* Check that the packet is not accepted with cause error in ackId. */
 
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 5, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send a link-request. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
 
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
 
 
 
  /* Check that a link-response is returned. */
 
  /* Note that the status of the input-port will be reported as ok since a
 
     link-request has been received. */
 
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check that a status is transmitted directly after the link-response. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC4");
 
  PrintS("Description: Test transmitter error handling.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send acknowledge for a frame that has not been transmitted and ");
 
  PrintS("        without any frame being expected.");
 
  PrintS("Result: The transmitter should enter output-error-stopped and send ");
 
  PrintS("        link-request.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC4-Step1");
 
  /******************************************************************************/
 
 
 
  /* Packet acknowledge for unsent frame. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that a link-request is received as the transmitter enters
 
     output-error-stopped state. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
 
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send link-response with expected ackId. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 5, 16, STYPE1_NOP, 0));
 
 
 
  /* Send a status directly afterwards. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that packets are relayed after this. */
 
  RIO_sendDoorbell(&stack, 0, 5, 2);
 
  packetLength = createDoorbell(packet, 5, 0, 0xffff, 5, 2);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send a packet and send acknowledge for a previous frame. Then send ");
 
  PrintS("        a link-response indicating that the packet was received (accepted ");
 
  PrintS("        but reply corrupted).");
 
  PrintS("Result: The transmitter should enter output-error-stopped state and send ");
 
  PrintS("        link-request and proceed with the next packet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC4-Step2");
 
  /******************************************************************************/
 
 
 
  /* Send a packet. */
 
  RIO_sendDoorbell(&stack, 0, 6, 2);
 
  packetLength = createDoorbell(packet, 6, 0, 0xffff, 6, 2);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send acknowledge for another packet. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that a link-request is received as the transmitter enters
 
     output-error-stopped state. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
 
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send link-response with expected ackId. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0));
 
 
 
  /* Send a status directly afterwards. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Send a packet and let the packet-accepted time out. Then send a ");
 
  PrintS("        link-response indicating that the packet was not received.");
 
  PrintS("Result: The transmitter should enter output-error-stopped state, send a");
 
  PrintS("        link-request and then resend the packet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC4-Step3");
 
  /******************************************************************************/
 
 
 
  /* Set the time at frame transmission. */
 
  RIO_portSetTime(&stack, 2);
 
 
 
  /* Send an output packet. */
 
  RIO_sendDoorbell(&stack, 0, 7, 2);
 
 
 
  /* Receive the transmitted packet. */
 
  packetLength = createDoorbell(packet, 7, 0, 0xffff, 7, 2);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Indicate that time has passed to trigger a timeout. */
 
  RIO_portSetTime(&stack, 3);
 
 
 
  /* Check that a link-request is received as the transmitter enters
 
     output-error-stopped state. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
 
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send link-response with expected ackId. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0));
 
 
 
  /* Send a status directly afterwards. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0));
 
 
 
  /* Receive retransmitted packet. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send acknowledge for the retransmitted packet. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 7, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 4:");
 
  PrintS("Action: Send a packet and then indicate that the packet was not accepted. ");
 
  PrintS("        Then send a link-response indicating that the packet was not received.");
 
  PrintS("Result: The transmitter should enter output-error-stopped state, send a");
 
  PrintS("        link-request and then resend the packet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC4-Step4");
 
  /******************************************************************************/
 
 
 
  /* Send an output packet. */
 
  RIO_sendDoorbell(&stack, 0, 8, 3);
 
 
 
  /* Receive the transmitted packet. */
 
  packetLength = createDoorbell(packet, 8, 0, 0xffff, 8, 3);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send packet-not-accepted indicating CRC error. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0));
 
 
 
  /* Check that a link-request is received as the transmitter enters
 
     output-error-stopped state. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
 
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send link-response with expected ackId. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 8, 16, STYPE1_NOP, 0));
 
 
 
  /* Send a status directly afterwards. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 8, 1, STYPE1_NOP, 0));
 
 
 
  /* Receive retransmitted packet. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send acknowledge for the retransmitted packet. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 8, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 5:");
 
  PrintS("Action: Send a packet-retry for an unexpected packet. Then send a");
 
  PrintS("        link-response indicating the expected ackId and a normal packet.");
 
  PrintS("Result: The transmitter should enter output-error-stopped state, send a");
 
  PrintS("        link-request and then the normal packet.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC4-Step5");
 
  /******************************************************************************/
 
 
 
  /* Send packet-retry indicating that a packet should be retransmitted. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 8, 1, STYPE1_NOP, 0));
 
 
 
  /* Check that a link-request is received as the transmitter enters
 
     output-error-stopped state. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
 
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send link-response with expected ackId. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 9, 16, STYPE1_NOP, 0));
 
 
 
  /* Send a status directly afterwards. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0));
 
 
 
  /* Send an output packet. */
 
  RIO_sendDoorbell(&stack, 0, 9, 4);
 
 
 
  /* Receive retransmitted packet. */
static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus)
  packetLength = createDoorbell(packet, 9, 0, 0xffff, 9, 4);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
  uint8_t window;
    d.type = RIO_SYMBOL_TYPE_DATA;
  uint8_t windowReceived;
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Send acknowledge for the retransmitted packet. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 1, STYPE1_NOP, 0));
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
 /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 6:");
 
  PrintS("Action: Fill outbound queue with packets, then check retransmission when ");
 
  PrintS("        packet-retry is encountered. ");
 
  PrintS("Result: Packets should be retried until packet-accepted is received.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC4-Step6");
 
  /******************************************************************************/
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 20, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 21, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 22, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 23, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 24, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 25, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 26, 0xbabe);
 
 
 
  TESTCOND(RIO_sendAvailable(&stack, 0));
 
  RIO_sendDoorbell(&stack, 0, 27, 0xbabe);
 
 
 
  TESTCOND(!RIO_sendAvailable(&stack, 0));
  (void) portStatus;
 
 
  /* Receive transmitted packet. */
  /* Check if this symbols is expected. */
  packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe);
  if(stack->txState == TX_STATE_OUTPUT_ERROR_STOPPED)
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
    /* Calculate the number of packets that has not received an acknowledge on our side and
    d.type = RIO_SYMBOL_TYPE_DATA;
       on the link-partner side. */
    d.data = packet[i];
    window = (stack->txAckIdWindow - stack->txAckId) & 0x1f;
    TESTEXPR(s.type, d.type);
    windowReceived = (ackId - stack->txAckId) & 0x1f;
    TESTEXPR(s.data, d.data);
 
  }
    /* Check if the link-partners response is acceptable. */
  packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe);
    if(windowReceived <= window)
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
      /* A link-response is expected. */
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
      /* Remove entries in the queue that the link-partner has sent acknowledges for that has been lost. */
    TESTEXPR(s.type, d.type);
      while(stack->txAckId != ackId)
    TESTEXPR(s.data, d.data);
 
  }
 
  packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
        stack->txQueue = QueueDequeue(stack->txQueue);
    d.type = RIO_SYMBOL_TYPE_DATA;
        stack->txAckId = ACKID_INC(stack->txAckId);
    d.data = packet[i];
        stack->statusOutboundPacketComplete++;
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
  packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
      /* Set the transmission window to the resend packets that has not been received. */
  s = RIO_portGetSymbol(&stack);
      stack->txQueue = QueueWindowReset(stack->txQueue);
  TESTEXPR(s.type, c.type);
      stack->txAckIdWindow = ackId;
  TESTEXPR(s.data, c.data);
      stack->txFrameState = TX_FRAME_START;
  for(i = 0; i < packetLength; i++)
 
  {
      /* Set the transmitter back into normal operation. */
    s = RIO_portGetSymbol(&stack);
      stack->txState = TX_STATE_LINK_INITIALIZED;
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
  packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe);
    else
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
      /* The link-partner response is unacceptable. */
    d.type = RIO_SYMBOL_TYPE_DATA;
      /* Recovery is not possible. */
    d.data = packet[i];
      stack->txState = TX_STATE_UNINITIALIZED;
    TESTEXPR(s.type, d.type);
      ASSERT0("Unrecoverable protocol error.");
    TESTEXPR(s.data, d.data);
 
  }
  }
  packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
  packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe);
  else
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
    /* Not expecting a link-response. */
    d.type = RIO_SYMBOL_TYPE_DATA;
    /* Just discard this symbol. */
    d.data = packet[i];
    /* REMARK: Add status counter here??? */
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  for(i = 0; i < 10; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
 
  }
  }
 
 
  /* Request retransmission. */
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 1, STYPE1_NOP, 0));
 
 
 
  /* Acknowledge retransmission. */
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_RESTART_FROM_RETRY, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  /* Check retransmitted packets. */
static void handleStartOfPacket(RioStack_t *stack)
  packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
  /* Check if a packet is already started. */
    d.type = RIO_SYMBOL_TYPE_DATA;
  if(stack->rxCounter != 0u)
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
  packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
    /* Packet has already started. */
    d.type = RIO_SYMBOL_TYPE_DATA;
    /* This indicates an implicit end-of-packet symbol and signals the previous packet as ready. */
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
    /* Check the packet crc. */
    TESTEXPR(s.data, d.data);
    if(stack->rxCrc == 0x0000u)
  }
 
  packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
      /* The packet has a correct CRC. */
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
 
 
 
  /* Acknowledge. */
      /* Check if the packet is long enough to contain a complete packet. */
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 10, 1, STYPE1_NOP, 0));
      if(stack->rxCounter > 3u)
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 11, 1, STYPE1_NOP, 0));
      {
 
        /* Packet long enough to process. */
 
 
  packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe);
        /* Process the newly received packet and start a new one. */
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
        handleNewPacketEnd(stack);
  s = RIO_portGetSymbol(&stack);
        handleNewPacketStart(stack);
  TESTEXPR(s.type, c.type);
      }
  TESTEXPR(s.data, c.data);
      else
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
        /* The packet has a valid CRC but is too short. */
    d.type = RIO_SYMBOL_TYPE_DATA;
        /* Packet error. Enter input-error-stopped state. */
    d.data = packet[i];
        stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
    TESTEXPR(s.type, d.type);
        stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
    TESTEXPR(s.data, d.data);
        stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
 
        stack->statusInboundErrorGeneral++;
  }
  }
  packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
 
    else
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 12, 1, STYPE1_NOP, 0));
 
 
 
  packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
      /* The packet has an invalid CRC. */
    d.type = RIO_SYMBOL_TYPE_DATA;
      /* Packet error. Enter input-error-stopped state. */
    d.data = packet[i];
      stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
    TESTEXPR(s.type, d.type);
      stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
    TESTEXPR(s.data, d.data);
      stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
 
      stack->statusInboundErrorPacketCrc++;
  }
  }
 
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 13, 1, STYPE1_NOP, 0));
 
 
 
  packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe);
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 14, 1, STYPE1_NOP, 0));
 
  for(i = 0; i < packetLength; i++)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    d.type = RIO_SYMBOL_TYPE_DATA;
 
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
  packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe);
  else
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
  for(i = 0; i < packetLength; i++)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
    /* Packet has not already started. */
    d.type = RIO_SYMBOL_TYPE_DATA;
    handleNewPacketStart(stack);
    d.data = packet[i];
 
    TESTEXPR(s.type, d.type);
 
    TESTEXPR(s.data, d.data);
 
  }
  }
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 15, 1, STYPE1_NOP, 0));
 
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
 
  s = RIO_portGetSymbol(&stack);
 
  TESTEXPR(s.type, c.type);
 
  TESTEXPR(s.data, c.data);
 
 
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 16, 1, STYPE1_NOP, 0));
 
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 17, 1, STYPE1_NOP, 0));
 
 
 
 
 
  /*************************************************************************
 
   * Reset ackIds to be able to use the stack in loopback for the testcases
 
   * below.
 
   *************************************************************************/
 
 
 
  stack.rxAckId = 0;
 
  stack.rxAckIdAcked = 0;
 
  stack.txAckId = 0;
 
  stack.txAckIdWindow = 0;
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC5");
 
  PrintS("Description: Test MAINTENANCE-READ-REQUEST, MAINTENANCE-READ-RESPONSE,");
 
  PrintS("             MAINTENANCE-WRITE-REQUEST and MAINTENANCE-WRITE-RESPONSE packets.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send two read requests to read identity and address of stack.");
 
  PrintS("Result: The identity and address defined at RIO_open should be returned.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC5-Step1");
 
  /******************************************************************************/
 
 
 
  /* Send two read requests. */
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 10, 0, 0x00000000);
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 11, 0, 0x00000060);
 
 
 
  TESTEXPR(RIO_outboundQueueLength(&stack), 2);
 
 
 
  while(RIO_inboundQueueLength(&stack) != 2)
 
  {
 
    s = RIO_portGetSymbol(&stack);
 
    RIO_portAddSymbol(&stack, s);
 
  }
  }
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xffff);
 
  TESTEXPR(tid, 10);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0x0000b03b);
 
  RIO_packetRemove(&stack);
 
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xffff);
 
  TESTEXPR(tid, 11);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0x0000ffff);
 
  RIO_packetRemove(&stack);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send a write requests to write base device id of the stack.");
 
  PrintS("Result: The identity and address defined at RIO_open should be returned.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC5-Step2");
 
  /******************************************************************************/
 
 
 
  /* Write base device id. */
static void handleEndOfPacket(RioStack_t *stack)
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 12, 0, 0x00000060, 0xdead);
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
  /* Check if the CRC is correct. */
    RIO_portAddSymbol(&stack, s);
  if(stack->rxCrc == 0x0000u)
  }
 
 
 
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 12);
 
  TESTEXPR(hop, 0xff);
 
  RIO_packetRemove(&stack);
 
 
 
  /* Read back the written base device id. */
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 14, 0, 0x00000060);
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_READ_RESPONSE)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
    /* The packet has a correct CRC. */
    RIO_portAddSymbol(&stack, s);
 
  }
 
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 14);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0x0000dead);
 
  RIO_packetRemove(&stack);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Send a write requests to write to the implementation defined ");
 
  PrintS("        configuration space of the stack.");
 
  PrintS("Result: The same data should be returned.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC5-Step3");
 
  /******************************************************************************/
 
 
 
  /* Write to implementation defined space. */
 
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 14, 0, 0x00010004, 0x01020304);
 
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 15, 0, 0x00010008, 0xc0debabe);
 
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 16, 0, 0x0001000c, 0x05060708);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
    /* Check if the packet is long enough to contain a complete packet. */
 
    if(stack->rxCounter > 3u)
  {
  {
    s = RIO_portGetSymbol(&stack);
      /* Packet long enough to process. */
    RIO_portAddSymbol(&stack, s);
 
  }
 
 
 
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 14);
 
  TESTEXPR(hop, 0xff);
 
  RIO_packetRemove(&stack);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
      /* Process the newly received packet. */
  {
      handleNewPacketEnd(stack);
    s = RIO_portGetSymbol(&stack);
 
    RIO_portAddSymbol(&stack, s);
 
  }
  }
 
    else
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 15);
 
  TESTEXPR(hop, 0xff);
 
  RIO_packetRemove(&stack);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
      /* The packet has a valid CRC but is too short. */
    RIO_portAddSymbol(&stack, s);
      /* Packet error. Enter input-error-stopped state. */
 
      stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
      stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
      stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
 
      stack->statusInboundErrorGeneral++;
  }
  }
 
  }
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
  else
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 16);
 
  TESTEXPR(hop, 0xff);
 
  RIO_packetRemove(&stack);
 
 
 
  /* Read from implementation defined space. */
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 14, 0, 0x00010000);
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 15, 0, 0x00010004);
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 16, 0, 0x00010008);
 
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 17, 0, 0x0001000c);
 
 
 
  while(RIO_inboundQueueLength(&stack) != 4)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
    /* The packet has an invalid CRC. */
    RIO_portAddSymbol(&stack, s);
    /* Packet error. Enter input-error-stopped state. */
 
    stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
 
    stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
 
    stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
 
    stack->statusInboundErrorPacketCrc++;
 
  }
  }
  }
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 14);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0x80000006);
 
  RIO_packetRemove(&stack);
 
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 15);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0x00a100a2);
 
  RIO_packetRemove(&stack);
 
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 16);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0xc0debabe);
 
  RIO_packetRemove(&stack);
 
 
 
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 17);
 
  TESTEXPR(hop, 0xff);
 
  TESTEXPR(data, 0x00000000);
 
  RIO_packetRemove(&stack);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC6");
 
  PrintS("Description: Test NREAD packets.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send one byte using NREAD and receive it at the other side.");
 
  PrintS("Result: The same NREAD should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC6-Step1");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 8; j++)
static void handleNewPacketStart(RioStack_t *stack)
  {
  {
    RIO_sendNread(&stack, 0x0060, j, 0xaaaaaaaa+j, 1);
  /* Check if there are buffers available to store the new frame. */
 
  if (QueueAvailable(stack->rxQueue) > 0u)
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
 
    {
    {
      s = RIO_portGetSymbol(&stack);
    /* There are buffers available to accept the new packet. */
      RIO_portAddSymbol(&stack, s);
 
    }
 
 
 
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
 
 
 
    TESTEXPR(tid, j);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(address, 0xaaaaaaaa+j);
 
    TESTEXPR(length, 1);
 
 
 
    RIO_packetRemove(&stack);
    /* Update the reception counter to indicate the frame has started. */
 
    stack->rxCounter = 1;
  }
  }
 
  else
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send two bytes using NREAD and receive it at the other side.");
 
  PrintS("Result: The same NREAD should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC6-Step2");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 4; j++)
 
  {
 
    RIO_sendNread(&stack, 0x0060, j, 0x00000008+2*j, 2);
 
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
 
    {
    {
      s = RIO_portGetSymbol(&stack);
    /* There are no buffers available. */
      RIO_portAddSymbol(&stack, s);
    /* Go to input retry stopped state. */
 
    stack->statusInboundPacketRetry++;
 
    stack->txState = TX_STATE_SEND_PACKET_RETRY;
 
    stack->rxState = RX_STATE_INPUT_RETRY_STOPPED;
    }
    }
 
 
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
 
 
 
    TESTEXPR(tid, j);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(address, 0x00000008+2*j);
 
    TESTEXPR(length, 2);
 
 
 
    RIO_packetRemove(&stack);
 
  }
  }
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Send three to seven bytes using NREAD and receive it at the other ");
 
  PrintS("        side.");
 
  PrintS("Result: The same NREAD should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC6-Step3");
 
  /******************************************************************************/
 
 
 
  for(k = 3; k < 8; k++)
 
  {
 
    for(j = 0; j < 2; j++)
 
    {
 
      RIO_sendNread(&stack, 0x0060, j, 0x00000008+(8-k)*j, k);
 
 
 
      while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
static void handleNewPacketEnd(RioStack_t *stack)
      {
      {
        s = RIO_portGetSymbol(&stack);
  /* Save the size of the packet. */
        RIO_portAddSymbol(&stack, s);
  QueueSetSize(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul);
      }
 
 
 
      RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
 
 
 
      TESTEXPR(tid, j);
  /* Always forward the packet to the top of the stack. */
      TESTEXPR(srcid, 0xdead);
  stack->rxQueue = QueueEnqueue(stack->rxQueue);
      TESTEXPR(address, 0x00000008+(8-k)*j);
 
      TESTEXPR(length, k);
 
 
 
      RIO_packetRemove(&stack);
  /* Make sure the CRC is reset to an invalid value to avoid a packet
    }
     accidentally being accepted. */
  }
  stack->rxCrc = 0xffff;
 
 
  /******************************************************************************/
  /* Reset the reception counter. */
  TESTEND;
  stack->rxCounter = 0u;
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 4:");
 
  PrintS("Action: Send one and two double words using NREAD and receive it at the ");
 
  PrintS("        other side.");
 
  PrintS("Result: The same NREAD should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC6-Step4");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 2; j++)
  /* Update the ackId for the receiver. */
  {
  stack->rxAckId = ACKID_INC(stack->rxAckId);
    RIO_sendNread(&stack, 0x0060, j, 0x00000008+8*j, 8*j+8);
 
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
  /* Update status counter. */
    {
  stack->statusInboundPacketComplete++;
      s = RIO_portGetSymbol(&stack);
 
      RIO_portAddSymbol(&stack, s);
 
    }
    }
 
 
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
 
 
 
    TESTEXPR(tid, j);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(address, 0x00000008+8*j);
 
    TESTEXPR(length, 8*j+8);
 
 
 
    RIO_packetRemove(&stack);
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 5:");
 
  PrintS("Action: Send multiple of four full double words using NREAD and receive it");
 
  PrintS("at the other side.");
 
  PrintS("Result: The same NREAD should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC6-Step5");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 8; j++)
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd)
  {
  {
    RIO_sendNread(&stack, 0x0060, j, 0x00000008+8*j, 32*j+32);
  /* Check the command of the link-request. */
 
  if(cmd == LINK_REQUEST_INPUT_STATUS)
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
 
    {
    {
      s = RIO_portGetSymbol(&stack);
    /* Input-status requested. */
      RIO_portAddSymbol(&stack, s);
    /* Return input port status. */
    }
 
 
 
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
 
 
 
    TESTEXPR(tid, j);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(address, 0x00000008+8*j);
 
    TESTEXPR(length, 32*j+32);
 
 
 
    RIO_packetRemove(&stack);
    /* Force the transmitter to send a link-response-symbol. */
 
    stack->txState = TX_STATE_SEND_LINK_RESPONSE;
  }
  }
 
  else if(cmd == LINK_REQUEST_RESET_DEVICE)
  /* REMARK: Add negative testcase where all unallowed address, size combinations
 
     are sent...*/
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC7");
 
  PrintS("Description: Test NWRITER packets.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send one byte using NWRITER and receive it at the other side.");
 
  PrintS("Result: The same NWRITER should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC7-Step1");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 8; j++)
 
  {
  {
    for(i = 0; i < 1; i++)
    /* Reset-device requested. */
 
    /* REMARK: Support this??? */
 
  }
 
  else
    {
    {
      payload8[i] = i+j+1;
    /* Unrecognized command. */
      payload8Expected[i] = 0;
    /* Dont do anything. */
    }
    }
 
 
    RIO_sendNwrite(&stack, 0x0060, 0xaaaaaaaa+j, 1, payload8);
  /* Always cancel an ongoing frame when a link-request has been received. */
 
  stack->rxCounter = 0;
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE)
  /* Receiving this indicates the link partner having encountered a potential problem. */
    {
  /* Count the number of times this happens. */
      s = RIO_portGetSymbol(&stack);
  stack->statusPartnerLinkRequest++;
      RIO_portAddSymbol(&stack, s);
 
    }
    }
 
 
    length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
 
 
 
    TESTEXPR(length, 1);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(address, 0xaaaaaaaa+j);
 
 
 
    for(i = 0; i < 1; i++)
static RioSymbol_t CreateControlSymbol(const uint8_t stype0,
 
                                       const uint8_t parameter0, const uint8_t parameter1,
 
                                       const uint8_t stype1, const uint8_t cmd)
    {
    {
      TESTEXPR(payload8Expected[i], i+j+1);
  RioSymbol_t s;
    }
 
 
 
    RIO_packetRemove(&stack);
  s.type = RIOSTACK_SYMBOL_TYPE_CONTROL;
  }
 
 
 
  /******************************************************************************/
  s.data = ((uint32_t)stype0 & (uint32_t)0x07ul) << 21;
  TESTEND;
  s.data |= ((uint32_t)parameter0 & (uint32_t)0x1ful) << 16;
  /******************************************************************************/
  s.data |= ((uint32_t)parameter1 & (uint32_t)0x1ful) << 11;
  PrintS("----------------------------------------------------------------------");
  s.data |= ((uint32_t)stype1 & (uint32_t)0x07ul) << 8;
  PrintS("Step 2:");
  s.data |= ((uint32_t)cmd & (uint32_t)0x7ul) << 5;
  PrintS("Action: Send two bytes using NWRITE and receive it at the other side.");
  s.data |= Crc5(s.data, 0x1fu);
  PrintS("Result: The same NWRITE should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC7-Step2");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 4; j++)
  return s;
  {
 
    for(i = 0; i < 2; i++)
 
    {
 
      payload8[i] = i+j;
 
      payload8Expected[i] = 0;
 
    }
    }
 
 
    RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+2*j, 2, payload8);
 
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
 
 
static uint8_t Crc5(const uint32_t data, const uint8_t crc)
    {
    {
      s = RIO_portGetSymbol(&stack);
  static const uint8_t crcTable[] = {
      RIO_portAddSymbol(&stack, s);
    0x00u, 0x15u, 0x1fu, 0x0au, 0x0bu, 0x1eu, 0x14u, 0x01u,
    }
    0x16u, 0x03u, 0x09u, 0x1cu, 0x1du, 0x08u, 0x02u, 0x17u,
 
    0x19u, 0x0cu, 0x06u, 0x13u, 0x12u, 0x07u, 0x0du, 0x18u,
 
    0x0fu, 0x1au, 0x10u, 0x05u, 0x04u, 0x11u, 0x1bu, 0x0eu
 
  };
 
 
    length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
  uint8_t result;
 
  uint8_t index;
 
 
    TESTEXPR(tid, j);
  result = crc;
    TESTEXPR(srcid, 0xdead);
  index  = (uint8_t)((data >> 19) & (uint32_t)0x1ful) ^ result;
    TESTEXPR(address, 0x00000008+2*j);
  result = crcTable[index];
    TESTEXPR(length, 2);
  index  = (uint8_t)((data >> 14) & (uint32_t)0x1ful) ^ result;
 
  result = crcTable[index];
 
  index  = (uint8_t)((data >> 9) & (uint32_t)0x1ful) ^ result;
 
  result = crcTable[index];
 
  index  = (uint8_t)((data >> 4) & (uint32_t)0x1eul) ^ result;
 
  result = crcTable[index];
 
 
    for(i = 0; i < 2; i++)
  return result;
    {
 
      TESTEXPR(payload8Expected[i], i+j);
 
    }
    }
 
 
    RIO_packetRemove(&stack);
 
  }
 
 
 
  /******************************************************************************/
/*******************************************************************************************
  TESTEND;
 * Internal queue functions.
  /******************************************************************************/
 *******************************************************************************************/
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 3:");
 
  PrintS("Action: Send three to seven bytes using NWRITE and receive it at the other ");
 
  PrintS("        side.");
 
  PrintS("Result: The same NWRITE should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC7-Step3");
 
  /******************************************************************************/
 
 
 
  for(k = 3; k < 8; k++)
static Queue_t QueueCreate(const uint8_t size, uint32_t *buffer)
  {
 
    for(j = 0; j < 2; j++)
 
    {
 
      for(i = 0; i < k; i++)
 
      {
      {
        payload8[i] = i+j+1;
  Queue_t q;
        payload8Expected[i] = 0;
 
      }
 
 
 
      RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+(8-k)*j, k, payload8);
  q.size = size;
 
  q.available = size;
 
  q.windowSize = 0u;
 
  q.windowIndex = 0u;
 
  q.frontIndex = 0u;
 
  q.backIndex = 0u;
 
  q.buffer_p = buffer;
 
 
      while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
  return q;
      {
 
        s = RIO_portGetSymbol(&stack);
 
        RIO_portAddSymbol(&stack, s);
 
      }
      }
 
 
      length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
 
 
 
      TESTEXPR(tid, j);
 
      TESTEXPR(srcid, 0xdead);
 
      TESTEXPR(address, 0x00000008+(8-k)*j);
 
      TESTEXPR(length, k);
 
 
 
      for(i = 0; i < k; i++)
static uint8_t QueueAvailable(const Queue_t q)
      {
      {
        TESTEXPR(payload8Expected[i], i+j+1);
  return q.available;
      }
      }
 
 
      RIO_packetRemove(&stack);
 
    }
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 4:");
 
  PrintS("Action: Send full double words using NWRITE and receive it at the other side.");
 
  PrintS("Result: The same NWRITE should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC7-Step4");
 
  /******************************************************************************/
 
 
 
  for(j = 1; j < 32; j++)
static int QueueEmpty(const Queue_t q)
  {
 
    for(i = 0; i < 8*j; i++)
 
    {
    {
      payload8[i] = i+j+1;
  return (q.available == q.size);
      payload8Expected[i] = 0;
 
    }
    }
 
 
    RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+8*j, 8*j, payload8);
 
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
 
 
static uint8_t QueueLength(const Queue_t q)
    {
    {
      s = RIO_portGetSymbol(&stack);
  return q.size - q.available;
      RIO_portAddSymbol(&stack, s);
 
    }
    }
 
 
    length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
 
 
 
    TESTEXPR(tid, j);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(address, 0x00000008+8*j);
 
    TESTEXPR(length, 8*j);
 
 
 
    for(i = 0; i < 8*j; i++)
static Queue_t QueueEnqueue(Queue_t q)
 
{
 
  q.backIndex++;
 
  if(q.backIndex == q.size)
    {
    {
      TESTEXPR(payload8Expected[i], (uint8_t) (i+j+1));
    q.backIndex = 0;
    }
    }
 
  q.available--;
    RIO_packetRemove(&stack);
  return q;
  }
  }
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC8");
 
  PrintS("Description: Test RESPONSE packets.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send one byte using RESPONSE_WITH_PAYLOAD and receive it at the ");
 
  PrintS("        other side.");
 
  PrintS("Result: The same RESPONSE_WITH_PAYLOAD should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC8-Step1");
 
  /******************************************************************************/
 
 
 
  for(j = 0; j < 8; j++)
 
 
static Queue_t QueueDequeue(Queue_t q)
  {
  {
    for(i = 0; i < 1; i++)
  q.frontIndex++;
 
  if(q.frontIndex == q.size)
    {
    {
      payload8[i] = i+j+1;
    q.frontIndex = 0;
      payload8Expected[i] = 0;
 
    }
    }
 
  q.available++;
    RIO_sendResponseDonePayload(&stack, 0x0060, j, 0x00000008+j, 1, payload8);
  if(q.windowSize == 0)
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_RESPONSE_DONE_PAYLOAD)
 
    {
    {
      s = RIO_portGetSymbol(&stack);
    q.windowIndex = q.frontIndex;
      RIO_portAddSymbol(&stack, s);
 
    }
    }
 
  else
    length = RIO_receiveResponseDonePayload(&stack, &srcid, &tid, 0x00000008+j, 1, payload8Expected);
 
 
 
    TESTEXPR(tid, j);
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(length, 1);
 
 
 
    for(i = 0; i < 1; i++)
 
    {
    {
      TESTEXPR(payload8Expected[i], i+j+1);
    q.windowSize--;
    }
    }
 
  return q;
    RIO_packetRemove(&stack);
 
  }
  }
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC9");
 
  PrintS("Description: Test DOORBELL packet and its response.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send a doorbell.");
 
  PrintS("Result: The received doorbell should have the same properties as the sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC9-Step1");
 
  /******************************************************************************/
 
 
 
  RIO_sendDoorbell(&stack, 0x0060, 16, 0xbabe);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
static int QueueWindowEmpty(const Queue_t q)
  {
  {
    s = RIO_portGetSymbol(&stack);
  return ((q.available + q.windowSize) == q.size);
    RIO_portAddSymbol(&stack, s);
 
  }
  }
 
 
  RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
 
 
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 16);
 
  TESTEXPR(info, 0xbabe);
 
  RIO_packetRemove(&stack);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send a response that is used for doorbells.");
 
  PrintS("Result: The same data should be returned.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC9-Step2");
 
  /******************************************************************************/
 
 
 
  RIO_sendResponseDone(&stack, 0x0060, 16);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_RESPONSE_DONE)
static Queue_t QueueWindowReset(Queue_t q)
  {
  {
    s = RIO_portGetSymbol(&stack);
  q.windowIndex = q.frontIndex;
    RIO_portAddSymbol(&stack, s);
  q.windowSize = 0;
 
  return q;
  }
  }
 
 
  RIO_receiveResponseDone(&stack, &srcid, &tid);
 
 
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 16);
 
  RIO_packetRemove(&stack);
 
 
 
  /******************************************************************************/
static Queue_t QueueWindowNext(Queue_t q)
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC10");
 
  PrintS("Description: Test MESSAGE packets.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send increasing number of byte using MESSAGE on all mailboxes");
 
  PrintS("        and receive it at the other side.");
 
  PrintS("Result: The same MESSAGE on the correct mailbox should be received as has");
 
  PrintS("        been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC10-Step1");
 
  /******************************************************************************/
 
 
 
  for(k = 0; k < 256; k++)
 
  {
 
    for(j = 1; j < 256; j++)
 
    {
    {
      for(i = 0; i < j; i++)
  q.windowIndex++;
 
  if(q.windowIndex == q.size)
      {
      {
        payload8[i] = i+j+1;
    q.windowIndex = 0;
        payload8Expected[i] = 0;
 
      }
      }
 
  q.windowSize++;
      RIO_sendMessage(&stack, 0x0060, k, j, payload8);
  return q;
 
 
      while(RIO_eventPoll(&stack) != RIO_EVENT_MESSAGE)
 
      {
 
        s = RIO_portGetSymbol(&stack);
 
        RIO_portAddSymbol(&stack, s);
 
      }
      }
 
 
      length = RIO_receiveMessage(&stack, &srcid, &mailbox, sizeof(payload8Expected), payload8Expected);
 
 
 
      TESTEXPR(srcid, 0xdead);
 
      TESTEXPR(mailbox, k);
 
      TESTEXPR(length, (((j-1)/8)+1)*8);
 
 
 
      for(i = 0; i < j; i++)
static void QueueSetSize(Queue_t q, const uint32_t size)
      {
      {
        TESTEXPR(payload8Expected[i], (uint8_t) (i+j+1));
  (q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.backIndex))[0] = size;
      }
      }
 
 
      RIO_packetRemove(&stack);
 
    }
 
  }
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 2:");
 
  PrintS("Action: Send a MESSAGE-RESPONSE from all mailboxes.");
 
  PrintS("Result: The same MESSAGE-RESPONSE should be received as has been sent.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC10-Step2");
 
  /******************************************************************************/
 
 
 
  for(i = 0; i < 256; i++)
 
  {
 
    RIO_sendMessageResponseDone(&stack, 0x0060, i);
 
 
 
    while(RIO_eventPoll(&stack) != RIO_EVENT_MESSAGE_RESPONSE_DONE)
static void QueueSetContent(Queue_t q, const uint32_t index, const uint32_t content)
    {
    {
      s = RIO_portGetSymbol(&stack);
  (q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.backIndex))[index+1ul] = content;
      RIO_portAddSymbol(&stack, s);
 
    }
    }
 
 
    RIO_receiveMessageResponseDone(&stack, &srcid, &mailbox);
 
 
 
    TESTEXPR(srcid, 0xdead);
 
    TESTEXPR(mailbox, i);
static uint32_t QueueGetSize(Queue_t q)
    RIO_packetRemove(&stack);
{
 
  return (q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.windowIndex))[0];
  }
  }
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("TG_riostack-TC11");
 
  PrintS("Description: Test reading and writing raw packets.");
 
  PrintS("Requirement: XXXXX");
 
  PrintS("----------------------------------------------------------------------");
 
  PrintS("Step 1:");
 
  PrintS("Action: Send a packet using normal functions then copy it using the ");
 
  PrintS("        packetGet() and packetSet() functions. ");
 
  PrintS("Result: The same packet should be received when copied.");
 
  PrintS("----------------------------------------------------------------------");
 
  /******************************************************************************/
 
  TESTSTART("TG_riostack-TC11-Step1");
 
  /******************************************************************************/
 
 
 
  RIO_sendDoorbell(&stack, 0x0060, 1, 0xca1e);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
static uint32_t QueueGetFrontContent(const Queue_t q, const uint32_t index)
  {
  {
    s = RIO_portGetSymbol(&stack);
  return (q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.windowIndex))[index+1ul];
    RIO_portAddSymbol(&stack, s);
 
  }
  }
 
 
  RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
 
 
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 1);
 
  TESTEXPR(info, 0xca1e);
 
 
 
  packetLength = RIO_packetGet(&stack, sizeof(packet)/4, packet);
static uint32_t *QueueGetFrontBuffer(const Queue_t q )
  RIO_packetSet(&stack, packetLength, packet);
 
 
 
  while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
 
  {
  {
    s = RIO_portGetSymbol(&stack);
  return &((q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.windowIndex))[1]);
    RIO_portAddSymbol(&stack, s);
 
  }
  }
 
 
  TESTEXPR(srcid, 0xdead);
 
  TESTEXPR(tid, 1);
 
  TESTEXPR(info, 0xca1e);
 
  RIO_packetRemove(&stack);
 
 
 
  /******************************************************************************/
 
  TESTEND;
 
  /******************************************************************************/
 
 
 
  return 0;
static uint32_t *QueueGetBackBuffer(const Queue_t q )
 
{
 
  return &((q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.backIndex))[1]);
}
}
#endif
 
 
 
/*************************** end of file **************************************/
/*************************** end of file **************************************/
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.