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

Subversion Repositories rio

[/] [rio/] [trunk/] [sw/] [stack/] [riostack.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 20 magro732
/*******************************************************************************
2
 *
3
 * RapidIO IP Library Core
4
 *
5
 * This file is part of the RapidIO IP library project
6
 * http://www.opencores.org/cores/rio/
7
 *
8
 * Description:
9
 * This file contains a software implementation of a RapidIO stack according to
10
 * the 2.2 version, part 6, of the standard. Only short control symbols are
11
 * supported.
12
 *
13
 * Symbols are in four flavors, idle, control, data and error. They are abstract
14
 * and should be serialized by any implementation to be sent on a transmission
15
 * channel. Error symbols are never generated by the stack and are used if the
16
 * symbol decoder encounters an error that the stack should be notified of.
17
 *
18
 * Symbols are inserted into the stack by calling RIO_portAddSymbol() and symbols to
19
 * transmit are fetched from the stack using RIO_portGetSymbol(). These two
20
 * functions are the low-level interface towards a physical transmission channel.
21
 * The function RIO_portSetStatus() is used to indicate to the stack that initial
22
 * training of the symbol codec has been completed and that the transmission port
23
 * is ready to accept other symbols than idle. The procedure is to set the port
24
 * status to initialized once idle symbols are successfully received.
25
 *
26
 * On the high-level interface are rio_sendXXX() functions used to create and
27
 * insert packets into the outbound transmission queue. The RIO_eventPoll()
28
 * function is used to check if any packet is available for reading in the
29
 * inbound reception queue. These packets are then accessed using
30
 * rio_receiveXXX() functions.
31
 *
32
 * -----------------
33
 * |  OS dependent |
34
 * |  (your code)  |
35
 * -----------------
36
 *        |
37
 * -----------------
38
 * |   RioStack    |
39
 * -----------------
40
 *        |
41
 * -----------------
42
 * | Symbol Codec  |
43
 * |  (your code)  |
44
 * -----------------
45
 *        |
46
 * -----------------
47
 * |  Port driver  |
48
 * -----------------
49
 *        |
50
 * -----------------
51
 * | Physical port |
52
 * -----------------
53
 *
54
 * The symbol codec maps a RapidIO symbol to the physical transmission media.
55
 *
56
 * Some typical patterns to handle this stack are:
57
 * Initialization:
58
 *   RIO_open(...);
59
 *   RIO_portSetTimeout(...);
60
 *   ...
61
 *   <Symbol transcoder is successfully decoding symbols from the link>
62
 *   RIO_portSetStatus(1);
63
 *
64
 * Bottom-half traffic handling:
65
 *   RIO_portSetTime(...);
66
 *   <get symbol from decoder>
67
 *   RIO_portAddSymbol(...);
68
 *   s = RIO_portGetSymbol(...);
69
 *   <send symbol to encoder>
70
 *
71
 * Receiving packets:
72
 *   switch(RIO_eventPoll(...))
73
 *   {
74
 *     case RIO_EVENT_DOORBELL:
75
 *       RIO_receiveDoorbell(...);
76
 *       ...
77
 *   }
78
 *   RIO_packetRemove();
79
 *
80
 * Transmitting packets:
81
 *   if(RIO_sendAvailable(...))
82
 *   {
83
 *     RIO_sendDoorbell(...);
84
 *   }
85
 *   ...
86
 *
87
 * More details about the usage can be found in the module tests in the end of
88
 * this file.
89
 *
90
 * To Do:
91
 * -
92
 *
93
 * Author(s):
94
 * - Magnus Rosenius, magro732@opencores.org
95
 *
96
 *******************************************************************************
97
 *
98
 * Copyright (C) 2013 Authors and OPENCORES.ORG
99
 *
100
 * This source file may be used and distributed without
101
 * restriction provided that this copyright statement is not
102
 * removed from the file and that any derivative work contains
103
 * the original copyright notice and the associated disclaimer.
104
 *
105
 * This source file is free software; you can redistribute it
106
 * and/or modify it under the terms of the GNU Lesser General
107
 * Public License as published by the Free Software Foundation;
108
 * either version 2.1 of the License, or (at your option) any
109
 * later version.
110
 *
111
 * This source is distributed in the hope that it will be
112
 * useful, but WITHOUT ANY WARRANTY; without even the implied
113
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
114
 * PURPOSE. See the GNU Lesser General Public License for more
115
 * details.
116
 *
117
 * You should have received a copy of the GNU Lesser General
118
 * Public License along with this source; if not, download it
119
 * from http://www.opencores.org/lgpl.shtml
120
 *
121
 *******************************************************************************/
122
 
123
/**
124
 * \file riostack.c
125
 */
126
 
127
/*******************************************************************************
128
 * Includes
129
 *******************************************************************************/
130
 
131
#include "riostack.h"
132
 
133
 
134
/*lint -e961 Allow function like macros. */
135
/*lint -e621 Long identifier names allowed to increase readability. */
136
/*lint -w2 */
137
 
138
 
139
/* lint --estring(960,17.4) It is not possible to implement a rio stack without some
140
 * pointer arithmetic */
141
 
142
/*******************************************************************************
143
 * Local macro definitions
144
 *******************************************************************************/
145
 
146
/* Macro to update 5-bit ackId counters. */
147
#define ACKID_INC(ackId) (((ackId)+1)&0x1f)
148
 
149
/* Macros to get entries from a control symbol. */
150
#define STYPE0_GET(data) ((uint8_t) (((data) >> 21) & 0x00000007u))
151
#define PARAMETER0_GET(data) ((uint8_t) (((data) >> 16) & 0x00000001fu))
152
#define PARAMETER1_GET(data) ((uint8_t) (((data) >> 11) & 0x00000001fu))
153
#define STYPE1_GET(data) ((uint8_t) (((data) >> 8) & 0x00000007u))
154
#define CMD_GET(data) ((uint8_t) (((data) >> 5) & 0x00000007u))
155
#define CRC5_GET(data) ((uint8_t) (((data) >> 0) & 0x0000001fu))
156
 
157
/* Macros to get entries from a packet in a buffer. */
158
#define FTYPE_GET(p) (((p)[0] >> 16) & 0xf)
159
#define DESTID_GET(p) ((p)[0] & 0xffff)
160
#define SRCID_GET(p) (((p)[1] >> 16) & 0xffff)
161
#define TRANSACTION_GET(p) (((p)[1] >> 12) & 0xf)
162
#define MSGLEN_GET(p) TRANSACTION_GET(p)
163
#define SSIZE_GET(p) (((p)[1] >> 8) & 0xf)
164
#define LETTER_GET(p) (((p)[1] >> 6) & 0x3)
165
#define MBOX_GET(p) (((p)[1] >> 4) & 0x3)
166
#define MSGSEG_GET(p) ((p)[1] & 0xf)
167
#define XMBOX_GET(p) MSGSEG_GET(p)
168
#define RDSIZE_GET(p) SSIZE_GET(p)
169
#define WRSIZE_GET(p) SSIZE_GET(p)
170
#define TID_GET(p) ((p)[1] & 0xff)
171
#define HOP_GET(p) (((p)[2] >> 24) & 0xff)
172
#define CONFIG_OFFSET_GET(p) ((p)[2] & 0x00fffffcul)
173
#define INFO_GET(p) (((p)[2] >> 16) & 0xffff)
174
#define ADDRESS_GET(p) ((p)[2] & 0xfffffff8ul)
175
#define WDPTR_GET(p) (((p)[2] >> 2) & 0x1)
176
#define XAMBS_GET(p) ((p)[2] & 0x3)
177
#define DOUBLE_WORD_MSB_GET(p, i) (p)[3+(2*i+0)]
178
#define DOUBLE_WORD_LSB_GET(p, i) (p)[3+(2*i+1)]
179
 
180
/* Transmitter frame states. */
181
#define TX_FRAME_START                  ((uint8_t)0u)
182
#define TX_FRAME_BODY                   ((uint8_t)1u)
183
 
184
/* Control symbol constants. */
185
#define STYPE0_PACKET_ACCEPTED          ((uint8_t)0x00u)
186
#define STYPE0_PACKET_RETRY             ((uint8_t)0x01u)
187
#define STYPE0_PACKET_NOT_ACCEPTED      ((uint8_t)0x02u)
188
#define STYPE0_RESERVED                 ((uint8_t)0x03u)
189
#define STYPE0_STATUS                   ((uint8_t)0x04u)
190
#define STYPE0_VC_STATUS                ((uint8_t)0x05u)
191
#define STYPE0_LINK_RESPONSE            ((uint8_t)0x06u)
192
#define STYPE0_IMPLEMENTATION_DEFINED   ((uint8_t)0x07u)
193
#define STYPE1_START_OF_PACKET          ((uint8_t)0x00u)
194
#define STYPE1_STOMP                    ((uint8_t)0x01u)
195
#define STYPE1_END_OF_PACKET            ((uint8_t)0x02u)
196
#define STYPE1_RESTART_FROM_RETRY       ((uint8_t)0x03u)
197
#define STYPE1_LINK_REQUEST             ((uint8_t)0x04u)
198
#define STYPE1_MULTICAST_EVENT          ((uint8_t)0x05u)
199
#define STYPE1_RESERVED                 ((uint8_t)0x06u)
200
#define STYPE1_NOP                      ((uint8_t)0x07u)
201
 
202
/* Packet ftype constants. */
203
#define FTYPE_REQUEST 0x2
204
#define FTYPE_WRITE 0x5
205
#define FTYPE_MAINTENANCE 0x8
206
#define FTYPE_DOORBELL 0xa
207
#define FTYPE_MESSAGE 0xb
208
#define FTYPE_RESPONSE 0xd
209
 
210
/* Transaction constants. */
211
#define TRANSACTION_MAINT_READ_REQUEST 0
212
#define TRANSACTION_MAINT_WRITE_REQUEST 1
213
#define TRANSACTION_MAINT_READ_RESPONSE 2
214
#define TRANSACTION_MAINT_WRITE_RESPONSE 3
215
#define TRANSACTION_WRITE_NWRITE 4
216
#define TRANSACTION_WRITE_NWRITER 5
217
#define TRANSACTION_REQUEST_NREAD 4
218
#define TRANSACTION_RESPONSE_NO_PAYLOAD 0
219
#define TRANSACTION_RESPONSE_MESSAGE_RESPONSE 1
220
#define TRANSACTION_RESPONSE_WITH_PAYLOAD 8
221
 
222
/* Maintenance transaction lengths. */
223
#define MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE ((uint32_t) 4ul)
224
#define MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE ((uint32_t) 6ul)
225
#define MAINTENANCE_TRANSACTION_READ_RESPONSE_SIZE ((uint32_t) 6ul)
226
#define MAINTENANCE_TRANSACTION_WRITE_RESPONSE_SIZE ((uint32_t) 4ul)
227
 
228
/* Constants used to forward different errors to the link partner. */
229
#define PACKET_NOT_ACCEPTED_CAUSE_RESERVED 0u
230
#define PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID 1u
231
#define PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC 2u
232
#define PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE 3u
233
#define PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC 4u
234
#define PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER 5u
235
#define PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCE 6u
236
#define PACKET_NOT_ACCEPTED_CAUSE_DESCRAMBLER 7u
237
#define PACKET_NOT_ACCEPTED_CAUSE_GENERAL 31u
238
 
239
/* Constants used to request link-responses. */
240
#define LINK_REQUEST_RESET_DEVICE 3u
241
#define LINK_REQUEST_INPUT_STATUS 4u
242
 
243
/* Constants used to forward a port status in a link-resonse. */
244
#define LINK_RESPONSE_PORT_STATUS_ERROR 2u
245
#define LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED 4u
246
#define LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED 5u
247
#define LINK_RESPONSE_PORT_STATUS_OK 16u
248
 
249
/*******************************************************************************
250
 * Local typedefs
251
 *******************************************************************************/
252
 
253
/*******************************************************************************
254
 * Global declarations
255
 *******************************************************************************/
256
 
257
/*******************************************************************************
258
 * Local declarations
259
 *******************************************************************************/
260
 
261
/*******************************************************************************
262
 * Local function prototypes
263
 *******************************************************************************/
264
 
265
/* Helper functions for protocol events. */
266
static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus);
267
static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus);
268
static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus);
269
static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause);
270
static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus);
271
static void handleStartOfPacket(RioStack_t *stack);
272
static void handleEndOfPacket(RioStack_t *stack);
273
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd);
274
static void handleNewPacketStart(RioStack_t *stack);
275
static void handleNewPacketEnd(RioStack_t *stack);
276
 
277
/* I/O logical layer maintenance packet functions. */
278
static void sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
279
                                        const uint8_t hopCount, const uint32_t offset);
280
static void receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
281
                                           uint8_t *hopCount, uint32_t *offset);
282
static void sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
283
                                         const uint8_t hopCount, const uint32_t data);
284
static void receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
285
                                            uint8_t *hopCount, uint32_t *data);
286
static void sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
287
                                         const uint8_t hopCount, const uint32_t offset, const uint32_t data );
288
static void receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
289
                                            uint8_t *hopCount, uint32_t *offset, uint32_t *data );
290
static void sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
291
                                          const uint8_t hopCount);
292
static void receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
293
                                             uint8_t *hopCount);
294
 
295
/* I/O logical layer packet functions. */
296
static void sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
297
                        const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer,
298
                        const uint8_t ack);
299
static uint16_t receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
300
                               uint32_t *address, const uint16_t dataLength, uint8_t *data );
301
static void sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
302
                       const uint32_t address, const uint16_t dataLength);
303
static void receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
304
                          uint32_t *address, uint16_t *dataLength);
305
static void sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
306
                                     const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer);
307
static uint16_t receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
308
                                            const uint32_t address, const uint16_t dataLength, uint8_t *data );
309
static void sendResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
310
                          const uint8_t status);
311
static void receiveResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid);
312
 
313
/* Message passing logical layer packet functions. */
314
static void sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
315
                          const uint16_t info );
316
static void receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
317
                             uint16_t *info);
318
static void sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
319
                         const uint16_t bufferSize, const uint8_t* bufferData);
320
static uint16_t receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
321
                                const uint16_t dataLength, uint8_t *data );
322
static void sendMessageResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
323
                                 const uint8_t status);
324
static void receiveMessageResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox);
325
 
326
/* Functions to help transfer data bytes to and from a packet payload. */
327
static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
328
                                 const uint16_t dataSize, uint8_t *data);
329
static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
330
                                 const uint16_t dataSize, const uint8_t *data);
331
 
332
/* Functions to help in conversions between rdsize/wrsize and size/offset. */
333
static uint16_t rdsizeGet(const uint32_t address, const uint16_t size);
334
static uint16_t wrsizeGet(const uint32_t address, const uint16_t size);
335
static void rdsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size);
336
static void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size);
337
 
338
/**
339
 * \brief Create a control symbol.
340
 *
341
 * \param[in] stype0 The stype0 value.
342
 * \param[in] parameter0 The parameter0 value.
343
 * \param[in] parameter1 The parameter1 value.
344
 * \param[in] stype1 The stype1 value.
345
 * \param[in] cmd The cmd value.
346
 * \param[out] None
347
 * \return The control symbol that were created from the input parameters.
348
 *
349
 * This function creates a control symbol with the specified arguments and
350
 * calculates a CRC-5 checksum according to the standard specification.
351
 */
352
static RioSymbol CreateControlSymbol( const uint8_t stype0,
353
                                      const uint8_t parameter0, const uint8_t parameter1,
354
                                      const uint8_t stype1, const uint8_t cmd);
355
 
356
/**
357
 * \brief Function to calculate ITU-CRC5, polynom=0x15.
358
 *
359
 * \param[in] data The data of a control symbol.
360
 * \param[in] crc The crc to initiate the result with.
361
 * \return A new CRC-5 value.
362
 */
363
static uint8_t Crc5( const uint32_t data, const uint8_t crc);
364
 
365
/**
366
 * \brief Function to calculate CITT-CRC16, polynom=0x1021.
367
 *
368
 * \param[in] data The data to calculate CRC-16 on.
369
 * \param[in] crc The crc to initiate the result with.
370
 * \param[out] None
371
 * \return A new CRC-16 value.
372
 *
373
 * This function calculates and returns a new CRC-16 value based on
374
 * new data and a previous CRC-16 value.
375
 */
376
static uint16_t Crc16( const uint16_t data, const uint16_t crc);
377
 
378
/**
379
 * \brief Function to calculate CITT-CRC16, polynom=0x1021.
380
 *
381
 * \param[in] data The data to calculate CRC-16 on.
382
 * \param[in] crc The crc to initiate the result with.
383
 * \param[out] None
384
 * \return A new CRC-16 value.
385
 *
386
 * This function calculates and returns a new CRC-16 value based on
387
 * new data and a previous CRC-16 value.
388
 */
389
static uint16_t Crc32( const uint32_t data, uint16_t crc);
390
 
391
/**
392
 * \brief Create a queue with a specified size and a buffer attached to it.
393
 *
394
 * \param[in] The number of entries in the queue.
395
 * \param[in] A pointer to the buffer to store the content in.
396
 * \return A queue with the specified size and where new data will be stored
397
 * to the specified buffer.
398
 */
399
static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer);
400
 
401
/**
402
 * \brief Get number of available elements.
403
 *
404
 * \param[in] q The queue to operate on.
405
 * \return The number of free packet buffers in the queue.
406
 */
407
static uint8_t QueueAvailable( const Queue_t q );
408
 
409
/**
410
 * \brief Get if the queue is empty or not.
411
 *
412
 * \param[in] q The queue to operate on.
413
 * \return Non-zero if the queue is empty.
414
 */
415
static bool_t QueueEmpty( const Queue_t q);
416
 
417
/**
418
 * \brief Get the length of a queue.
419
 *
420
 * \param[in] q The queue to operate on.
421
 * \return The number of elements in the queue.
422
 */
423
static uint8_t QueueLength( const Queue_t q);
424
 
425
/**
426
 * \brief Add a new element to the queue.
427
 *
428
 * \param[in] q The queue to operate on.
429
 * \return A queue with one added element.
430
 */
431
static Queue_t QueueEnqueue( Queue_t q);
432
 
433
/**
434
 * \brief Remove an element from the queue.
435
 *
436
 * \param[in] q The queue to operate on.
437
 * \return A queue with on removed element.
438
 */
439
static Queue_t QueueDequeue( Queue_t q);
440
 
441
/**
442
 * \brief Check if the readout window is empty.
443
 *
444
 * \param[in] q The queue to operate on.
445
 * \return If the readout window is empty.
446
 */
447
static bool_t QueueWindowEmpty( const Queue_t q);
448
 
449
/**
450
 * \brief Reset the window to none.
451
 *
452
 * \param[in] q The queue to operate on.
453
 * \return The updated Queue_t structure.
454
 */
455
static Queue_t QueueWindowReset(Queue_t q);
456
 
457
/**
458
 * \brief Increase the window to the next pending element.
459
 *
460
 * \param[in] q The queue to operate on.
461
 * \return The updated Queue_t structure.
462
 */
463
static Queue_t QueueWindowNext(Queue_t q);
464
 
465
/**
466
 * \brief Set actual size of the newest element.
467
 *
468
 * \param[in] q The queue to operate on.
469
 * \param[in] size The size to set the newest content size to.
470
 */
471
static void QueueSetSize( Queue_t q, const uint32_t size);
472
 
473
/**
474
 * \brief Set content at a specified index in the newest element.
475
 *
476
 * \param[in] q The queue to operate on.
477
 * \param[in] index posititon into the element
478
 * \param[in] content The content to set at the specified index in the newest queue element.
479
 */
480
static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content);
481
 
482
/**
483
 * \brief Get the size of the newest element.
484
 *
485
 * \param[in] q The queue to operate on.
486
 * \return The size of the currently pending element.
487
 */
488
static uint32_t QueueGetBackSize( Queue_t q);
489
 
490
/**
491
 * \brief Get a pointer to the buffer of the newest element.
492
 *
493
 * \param[in] q The queue to operate on.
494
 * \return A pointer to the content.
495
 */
496
static uint32_t *QueueGetBackBuffer( Queue_t q );
497
 
498
/**
499
 * \brief Get the size of the oldest element.
500
 * \param[in] q The queue to operate on.
501
 * \return The size of the element.
502
 */
503
static uint32_t QueueGetFrontSize( Queue_t q );
504
 
505
/**
506
 * \brief Get the content of the oldest element at specified index.
507
 * \param[in] q The queue to operate on.
508
 * \param[in] index The index into the element to get the content from.
509
 * \return content of element at index position.
510
 */
511
static uint32_t QueueGetFrontContent( Queue_t q, const uint32_t index);
512
 
513
/**
514
 * \brief Get a pointer to the buffer of the oldest element.
515
 *
516
 * \param[in] q The queue to operate on.
517
 * \return A pointer to the content.
518
 */
519
static uint32_t *QueueGetFrontBuffer( Queue_t q );
520
 
521
 
522
 
523
/*******************************************************************************
524
 * Global functions
525
 *******************************************************************************/
526
 
527
 
528
void RIO_open( RioStack_t *stack, const RioStackObserver_t *observer, const void *private,
529
               const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer,
530
               const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer,
531
               const uint16_t configDeviceVendorId, const uint16_t configDeviceId, const uint32_t configDeviceRevisionId,
532
               const uint16_t configAssyVendorId, const uint16_t configAssyId, const uint16_t configAssyRevisionId,
533
               const uint16_t configBaseDeviceId )
534
{
535
  /* Port time and timeout limit. */
536
  stack->portTime = 0u;
537
  stack->portTimeout = 1000u;
538
 
539
  /* Setup the receiver. */
540
  stack->rxState = RX_STATE_UNINITIALIZED;
541
  stack->rxCounter = 0u;
542
  stack->rxCrc = 0xffffu;
543
  stack->rxStatusReceived = 0u;
544
  stack->rxAckId = 0u;
545
  stack->rxAckIdAcked = 0u;
546
  stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
547
  stack->rxQueue = QueueCreate((uint8_t) (rxPacketBufferSize/RIO_BUFFER_SIZE), rxPacketBuffer);
548
 
549
  /* Setup the transmitter. */
550
  stack->txState = TX_STATE_UNINITIALIZED;
551
  stack->txCounter = 0u;
552
  stack->txStatusCounter = 0u;
553
  stack->txFrameState = TX_FRAME_START;
554
  stack->txAckId = 0u;
555
  stack->txAckIdWindow = 0u;
556
  stack->txQueue = QueueCreate((uint8_t) (txPacketBufferSize/RIO_BUFFER_SIZE), txPacketBuffer);
557
 
558
  /* Set our own device address to use in the packets. */
559
  stack->deviceIdentity = configDeviceId;
560
  stack->deviceVendorIdentity = configDeviceVendorId;
561
  stack->deviceRev = configDeviceRevisionId;
562
  stack->assyIdentity = configAssyId;
563
  stack->assyVendorIdentity = configAssyVendorId;
564
  stack->assyRev = configAssyRevisionId;
565
  stack->baseDeviceId = configBaseDeviceId;
566
 
567
  /* Initialize the host base lock CSR. */
568
  stack->hostBaseDeviceIdLock = 0xfffffffful;
569
  stack->componentTag = 0ul;
570
 
571
  /* Bits that are updated by the configuration procedure. */
572
  stack->host = 0u;
573
  stack->masterEnable = 0u;
574
  stack->discovered = 0u;
575
 
576
  /* Setup status counters for inbound direction. */
577
  stack->statusInboundPacketComplete = 0ul;
578
  stack->statusInboundPacketRetry = 0ul;
579
  stack->statusInboundErrorControlCrc = 0ul;
580
  stack->statusInboundErrorPacketAckId = 0ul;
581
  stack->statusInboundErrorPacketCrc = 0ul;
582
  stack->statusInboundErrorIllegalCharacter = 0ul;
583
  stack->statusInboundErrorGeneral = 0ul;
584
  stack->statusInboundErrorPacketUnsupported = 0ul;
585
 
586
  /* Setup status counters for outbound direction. */
587
  stack->statusOutboundPacketComplete = 0ul;
588
  stack->statusOutboundPacketRetry = 0ul;
589
  stack->statusOutboundErrorTimeout = 0ul;
590
  stack->statusOutboundErrorPacketAccepted = 0ul;
591
  stack->statusOutboundErrorPacketRetry = 0ul;
592
 
593
  /* Setup status counters for potential problems on the link-partner. */
594
  stack->statusPartnerLinkRequest = 0ul;
595
  stack->statusPartnerErrorControlCrc = 0ul;
596
  stack->statusPartnerErrorPacketAckId = 0ul;
597
  stack->statusPartnerErrorPacketCrc = 0ul;
598
  stack->statusPartnerErrorIllegalCharacter = 0ul;
599
  stack->statusPartnerErrorGeneral = 0ul;
600
 
601
  /* Set callback structure. */
602
  stack->observer = observer;
603
 
604
  /* Set pointer to user private data. */
605
  stack->private = private;
606
}
607
 
608
 
609
/*******************************************************************************************
610
 * Stack status functions.
611
 * Note that status counters are access directly in the stack-structure.
612
 *******************************************************************************************/
613
 
614
RioStatusType RIO_getStatus( RioStack_t *stack )
615
{
616
  RioStatusType status;
617
 
618
 
619
  /* Check if both receiver and transmitter is up and running. */
620
  if((stack->rxState == RX_STATE_LINK_INITIALIZED) &&
621
     (stack->txState == TX_STATE_LINK_INITIALIZED))
622
  {
623
    /* Both receiver and transmitter is up. */
624
 
625
    /* Check if it is allowed to act as a master on the bus. */
626
    if(stack->masterEnable)
627
    {
628
      /* Allowed to act as master. */
629
      status = RIO_STATUS_OPERATIONAL;
630
    }
631
    else
632
    {
633
      /* Not allowed to act as master. */
634
      /* The enumeration process has not been completed yet. */
635
      status = RIO_STATUS_ENUMERATION;
636
    }
637
  }
638
  else
639
  {
640
    /* The link is not up yet. */
641
    status = RIO_STATUS_UNINITIALIZED;
642
  }
643
 
644
  return status;
645
}
646
 
647
 
648
uint8_t RIO_outboundQueueLength( RioStack_t *stack )
649
{
650
  return QueueLength(stack->txQueue);
651
}
652
 
653
 
654
uint8_t RIO_inboundQueueLength( RioStack_t *stack )
655
{
656
  return QueueLength(stack->rxQueue);
657
}
658
 
659
 
660
/*******************************************************************************************
661
 * Packet reception functions.
662
 *******************************************************************************************/
663
 
664
RioEventType RIO_eventPoll( RioStack_t *stack )
665
{
666
  RioEventType event;
667
  uint32_t *packet;
668
  uint32_t ftype;
669
  uint32_t transaction;
670
 
671
 
672
  /* Check if there are any new packets in the inbound queue. */
673
  if(!QueueEmpty(stack->rxQueue))
674
  {
675
    /* There are new pending packets. */
676
 
677
    /* Get the packet and its ftype. */
678
    packet = QueueGetFrontBuffer(stack->rxQueue);
679
    ftype = FTYPE_GET(packet);
680
    transaction = TRANSACTION_GET(packet);
681
 
682
    /* Check the type of packets, i.e. read the ftype. */
683
    switch(ftype)
684
    {
685
      case FTYPE_REQUEST:
686
        /* Request class. */
687
 
688
        /* Check transaction type. */
689
        switch(transaction)
690
        {
691
          case TRANSACTION_REQUEST_NREAD:
692
            /* Supported NREAD request. */
693
            event = RIO_EVENT_NREAD;
694
            break;
695
 
696
          default:
697
            /* Unsupported request transaction. */
698
            /* REMARK: Throw these away for now. */
699
            stack->statusInboundErrorPacketUnsupported++;
700
            stack->rxQueue = QueueDequeue(stack->rxQueue);
701
            event = RIO_EVENT_NONE;
702
            break;
703
        }
704
        break;
705
 
706
      case FTYPE_WRITE:
707
        /* Write class. */
708
 
709
        /* Check transaction type. */
710
        switch(transaction)
711
        {
712
          case TRANSACTION_WRITE_NWRITE:
713
            /* NWRITE transaction. */
714
            if(QueueGetFrontSize(stack->rxQueue) >= 6ul)
715
            {
716
              /* Supported NWRITE request. */
717
              event = RIO_EVENT_NWRITE;
718
            }
719
            else
720
            {
721
              /* Unsupported size. */
722
              /* REMARK: Throw these away for now. */
723
              stack->statusInboundErrorPacketUnsupported++;
724
              stack->rxQueue = QueueDequeue(stack->rxQueue);
725
              event = RIO_EVENT_NONE;
726
            }
727
            break;
728
 
729
          case TRANSACTION_WRITE_NWRITER:
730
            /* NWRITE_R transaction. */
731
            if(QueueGetFrontSize(stack->rxQueue) >= 6ul)
732
            {
733
              /* Supported NWRITE_R request. */
734
              event = RIO_EVENT_NWRITE_R;
735
            }
736
            else
737
            {
738
              /* Unsupported size. */
739
              /* REMARK: Throw these away for now. */
740
              stack->statusInboundErrorPacketUnsupported++;
741
              stack->rxQueue = QueueDequeue(stack->rxQueue);
742
              event = RIO_EVENT_NONE;
743
            }
744
            break;
745
 
746
          default:
747
            /* Unsupported write transaction. */
748
            /* REMARK: Throw these away for now. */
749
            stack->statusInboundErrorPacketUnsupported++;
750
            stack->rxQueue = QueueDequeue(stack->rxQueue);
751
            event = RIO_EVENT_NONE;
752
            break;
753
        }
754
        break;
755
 
756
      case FTYPE_MAINTENANCE:
757
        /* Maintenance class. */
758
 
759
        /* Check transaction type. */
760
        /* Normally, only responses could be received here unless the stack is compiled as transparent.
761
           Maintenance requests are answered by the portAddSymbol() function. */
762
        switch(transaction)
763
        {
764
          case TRANSACTION_MAINT_READ_REQUEST:
765
            /* Maintenance read request transaction. */
766
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE)
767
            {
768
              /* Supported maintenance read response. */
769
              event = RIO_EVENT_MAINT_READ_REQUEST;
770
            }
771
            else
772
            {
773
              /* Unsupported maintenance read request. */
774
              /* REMARK: Throw these away for now. */
775
              stack->statusInboundErrorPacketUnsupported++;
776
              stack->rxQueue = QueueDequeue(stack->rxQueue);
777
              event = RIO_EVENT_NONE;
778
            }
779
            break;
780
 
781
          case TRANSACTION_MAINT_WRITE_REQUEST:
782
            /* Maintenance write request transaction. */
783
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE)
784
            {
785
              /* Supported maintenance write request. */
786
              event = RIO_EVENT_MAINT_WRITE_REQUEST;
787
            }
788
            else
789
            {
790
              /* Unsupported maintenance write response. */
791
              /* REMARK: Throw these away for now. */
792
              stack->statusInboundErrorPacketUnsupported++;
793
              stack->rxQueue = QueueDequeue(stack->rxQueue);
794
              event = RIO_EVENT_NONE;
795
            }
796
            break;
797
 
798
          case TRANSACTION_MAINT_READ_RESPONSE:
799
            /* Maintenance read response transaction. */
800
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_RESPONSE_SIZE)
801
            {
802
              /* Supported maintenance read response. */
803
              event = RIO_EVENT_MAINT_READ_RESPONSE;
804
            }
805
            else
806
            {
807
              /* Unsupported maintenance read response. */
808
              /* REMARK: Throw these away for now. */
809
              stack->statusInboundErrorPacketUnsupported++;
810
              stack->rxQueue = QueueDequeue(stack->rxQueue);
811
              event = RIO_EVENT_NONE;
812
            }
813
            break;
814
 
815
          case TRANSACTION_MAINT_WRITE_RESPONSE:
816
            /* Maintenance write response transaction. */
817
            if(QueueGetFrontSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_RESPONSE_SIZE)
818
            {
819
              /* Supported maintenance write response. */
820
              event = RIO_EVENT_MAINT_WRITE_RESPONSE;
821
            }
822
            else
823
            {
824
              /* Unsupported maintenance write response. */
825
              /* REMARK: Throw these away for now. */
826
              stack->statusInboundErrorPacketUnsupported++;
827
              stack->rxQueue = QueueDequeue(stack->rxQueue);
828
              event = RIO_EVENT_NONE;
829
            }
830
            break;
831
 
832
          default:
833
            /* Unsupported maintenance transaction. */
834
            /* REMARK: Throw these away for now. */
835
            stack->statusInboundErrorPacketUnsupported++;
836
            stack->rxQueue = QueueDequeue(stack->rxQueue);
837
            event = RIO_EVENT_NONE;
838
            break;
839
        }
840
        break;
841
 
842
      case FTYPE_DOORBELL:
843
        /* Doorbell class. */
844
 
845
        /* Check size of message. */
846
        if(QueueGetFrontSize(stack->rxQueue) == 3ul)
847
        {
848
          /* Supported doorbell. */
849
          event = RIO_EVENT_DOORBELL;
850
        }
851
        else
852
        {
853
          /* Unsupported doorbell request. */
854
          /* REMARK: Throw these away for now. */
855
          stack->statusInboundErrorPacketUnsupported++;
856
          stack->rxQueue = QueueDequeue(stack->rxQueue);
857
          event = RIO_EVENT_NONE;
858
        }
859
        break;
860
 
861
      case FTYPE_MESSAGE:
862
        /* Message class. */
863
 
864
        /* Check msglen to see if this packet continues. */
865
        if(MSGLEN_GET(packet) == 0ul)
866
        {
867
          /* Single-packet message. */
868
          event = RIO_EVENT_MESSAGE;
869
        }
870
        else
871
        {
872
          /* Unsupported message type. */
873
          /* REMARK: Throw these away for now. */
874
          stack->statusInboundErrorPacketUnsupported++;
875
          stack->rxQueue = QueueDequeue(stack->rxQueue);
876
          event = RIO_EVENT_NONE;
877
        }
878
        break;
879
 
880
      case FTYPE_RESPONSE:
881
        /* Response class. */
882
 
883
        /* Check transaction field. */
884
        switch(transaction)
885
        {
886
          case TRANSACTION_RESPONSE_NO_PAYLOAD:
887
            /* Response transaction without payload. */
888
 
889
            /* Check status field. */
890
            switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
891
            {
892
              case 0x00000000:
893
                event = RIO_EVENT_RESPONSE_DONE;
894
                break;
895
              case 0x00000300:
896
                event = RIO_EVENT_RESPONSE_RETRY;
897
                break;
898
              case 0x00000700:
899
                event = RIO_EVENT_RESPONSE_ERROR;
900
                break;
901
              default:
902
                /* Unsupported response status. */
903
                /* REMARK: Throw these away for now. */
904
                stack->statusInboundErrorPacketUnsupported++;
905
                stack->rxQueue = QueueDequeue(stack->rxQueue);
906
                event = RIO_EVENT_NONE;
907
                break;
908
            }
909
            break;
910
 
911
          case TRANSACTION_RESPONSE_MESSAGE_RESPONSE:
912
            /* Message response transaction. */
913
 
914
            /* Check status field. */
915
            switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
916
            {
917
              case 0x00000000:
918
                event = RIO_EVENT_MESSAGE_RESPONSE_DONE;
919
                break;
920
              case 0x00000300:
921
                event = RIO_EVENT_MESSAGE_RESPONSE_RETRY;
922
                break;
923
              case 0x00000700:
924
                event = RIO_EVENT_MESSAGE_RESPONSE_ERROR;
925
                break;
926
              default:
927
                /* Unsupported message response status. */
928
                /* REMARK: Throw these away for now. */
929
                stack->statusInboundErrorPacketUnsupported++;
930
                stack->rxQueue = QueueDequeue(stack->rxQueue);
931
                event = RIO_EVENT_NONE;
932
                break;
933
            }
934
            break;
935
 
936
          case TRANSACTION_RESPONSE_WITH_PAYLOAD:
937
            /* Response with payload transaction. */
938
 
939
            /* Check status field. */
940
            switch(QueueGetFrontContent(stack->rxQueue, 1ul) & 0x00000f00ul)
941
            {
942
              case 0x00000000:
943
                event = RIO_EVENT_RESPONSE_DONE_PAYLOAD;
944
                break;
945
              case 0x00000300:
946
                event = RIO_EVENT_RESPONSE_RETRY;
947
                break;
948
              case 0x00000700:
949
                event = RIO_EVENT_RESPONSE_ERROR;
950
                break;
951
              default:
952
                /* Unsupported response with payload status. */
953
                /* REMARK: Throw these away for now. */
954
                stack->statusInboundErrorPacketUnsupported++;
955
                stack->rxQueue = QueueDequeue(stack->rxQueue);
956
                event = RIO_EVENT_NONE;
957
                break;
958
            }
959
            break;
960
 
961
          default:
962
            /* Unsupported response transaction. */
963
            /* REMARK: Throw these away for now. */
964
            stack->statusInboundErrorPacketUnsupported++;
965
            stack->rxQueue = QueueDequeue(stack->rxQueue);
966
            event = RIO_EVENT_NONE;
967
            break;
968
        }
969
        break;
970
 
971
      default:
972
        /* Unsupported class. */
973
        /* REMARK: Throw these away for now. */
974
        stack->statusInboundErrorPacketUnsupported++;
975
        stack->rxQueue = QueueDequeue(stack->rxQueue);
976
        event = RIO_EVENT_NONE;
977
        break;
978
    }
979
  }
980
  else
981
  {
982
    /* No pending events available. */
983
    event = RIO_EVENT_NONE;
984
  }
985
 
986
  return event;
987
}
988
 
989
 
990
void RIO_packetRemove( RioStack_t *stack )
991
{
992
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
993
 
994
  stack->rxQueue = QueueDequeue(stack->rxQueue);
995
}
996
 
997
 
998
bool_t RIO_sendAvailable( RioStack_t *stack, const uint16_t size )
999
{
1000
  /* Return if there are buffers available and if the requested size is less
1001
     than or equal to the maximum payload that fits into one packet. */
1002
  return (bool_t) (stack->masterEnable && (size <= 256u) && (QueueAvailable(stack->txQueue) > 0u));
1003
}
1004
 
1005
 
1006
uint32_t RIO_packetGet( RioStack_t *stack, uint32_t length, uint32_t *dest)
1007
{
1008
  uint32_t i;
1009
  uint32_t size;
1010
  uint32_t *src;
1011
 
1012
 
1013
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
1014
 
1015
  /* Get the size and a pointer to the raw packet. */
1016
  size = QueueGetFrontSize(stack->rxQueue);
1017
  src = QueueGetFrontBuffer(stack->rxQueue);
1018
 
1019
  ASSERT((length >= size), "Too short destination packet.");
1020
 
1021
  /* Copy the packet to the destination packet pointer. */
1022
  for(i = 0; i < size; i++)
1023
  {
1024
    dest[i] = src[i];
1025
  }
1026
 
1027
  /* Remove the packet from the queue. */
1028
  stack->rxQueue = QueueDequeue(stack->rxQueue);
1029
 
1030
  /* Return the size of the copied packet. */
1031
  return size;
1032
}
1033
 
1034
 
1035
void RIO_packetSet( RioStack_t *stack, uint32_t length, uint32_t *src)
1036
{
1037
  uint32_t i;
1038
  uint32_t *dest;
1039
 
1040
 
1041
  ASSERT((QueueAvailable(stack->txQueue) > 0), "Writing to full transmission queue.");
1042
  ASSERT((length < RIO_PACKET_SIZE), "Writing a too large packet.");
1043
 
1044
  /* Set the size of the new packet. */
1045
  QueueSetSize(stack->txQueue, length);
1046
 
1047
  /* Get a pointer to the destination packet in the transmission queue. */
1048
  dest = QueueGetBackBuffer(stack->txQueue);
1049
 
1050
  /* Copy the packet into the transmission queue. */
1051
  for(i = 0; i < length; i++)
1052
  {
1053
    dest[i] = src[i];
1054
  }
1055
 
1056
  /* Make sure the ackId field of the copied packet is reset. */
1057
  /* Unless this is done, the ackId field of the transmitted packet may be corrupted. */
1058
  dest[0] &= 0x03ffffff;
1059
 
1060
  /* Enqueue the new packet. */
1061
  stack->txQueue = QueueEnqueue(stack->txQueue);
1062
}
1063
 
1064
/*******************************************************************************************
1065
 * Configuration-space access methods.
1066
 *******************************************************************************************/
1067
 
1068
uint32_t RIO_readConfig( RioStack_t *stack, const uint32_t offset )
1069
{
1070
  uint32_t data;
1071
 
1072
  /* Check the area of the access. */
1073
  if(offset < 0x10000ul)
1074
  {
1075
    /* Access is in not in implementation-defined space. */
1076
 
1077
    /* Check offset and return. */
1078
    switch(offset)
1079
    {
1080
      case DEVICE_IDENTITY_CAR:
1081
        data = (uint32_t)stack->deviceIdentity << 16;
1082
        data |= stack->deviceVendorIdentity;
1083
        break;
1084
      case DEVICE_INFORMATION_CAR:
1085
        data = stack->deviceRev;
1086
        break;
1087
      case ASSEMBLY_IDENTITY_CAR:
1088
        data = (uint32_t)stack->assyIdentity << 16;
1089
        data |= stack->assyVendorIdentity;
1090
        break;
1091
      case ASSEMBLY_INFORMATION_CAR:
1092
        data = (uint32_t)stack->assyRev << 16;
1093
        data |= EXTENDED_FEATURES_OFFSET;
1094
        break;
1095
      case PROCESSING_ELEMENT_FEATURES_CAR:
1096
        /* Indicate processor with extended features
1097
           and 34-bit address support. */
1098
        /* Supports common transport large systems. */
1099
        data = 0x20000019ul;
1100
        break;
1101
      case SOURCE_OPERATIONS_CAR:
1102
        /* Supporting doorbells and data messages. */
1103
        data = 0x00000c00ul;
1104
        break;
1105
      case DESTINATION_OPERATIONS_CAR:
1106
        /* Supporting doorbells and data messages. */
1107
        data = 0x00000c00ul;
1108
        break;
1109
      case PROCESSING_ELEMENT_LOGICAL_LAYER_CONTROL_CSR:
1110
        /* Supports 34-bit addresses. */
1111
        data = 0x00000001ul;
1112
        break;
1113
      case BASE_DEVICE_ID_CSR:
1114
        data = stack->baseDeviceId;
1115
        break;
1116
      case HOST_BASE_DEVICE_ID_LOCK_CSR:
1117
        data = stack->hostBaseDeviceIdLock & (uint32_t)0x0000fffful;
1118
        break;
1119
      case COMPONENT_TAG_CSR:
1120
        data = stack->componentTag;
1121
        break;
1122
      case LP_SERIAL_REGISTER_BLOCK_HEADER(EXTENDED_FEATURES_OFFSET):
1123
        /* Indicate Generic end point device and no more extended features. */
1124
        data = 0x00000001ul;
1125
        break;
1126
      case PORT_LINK_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
1127
        /* REMARK: Implement this... */
1128
        data = 0x00000000ul;
1129
        break;
1130
      case PORT_RESPONSE_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
1131
        /* REMARK: Implement this... */
1132
        data = 0x00000000ul;
1133
        break;
1134
      case PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
1135
        /* Return the host, master enable bit and the discovered bit. */
1136
        data = ((uint32_t) stack->host) << 31;
1137
        data |= ((uint32_t) stack->masterEnable) << 30;
1138
        data |= ((uint32_t) stack->discovered) << 29;
1139
        break;
1140
      case PORT_N_LOCAL_ACKID_CSR(EXTENDED_FEATURES_OFFSET, 0u):
1141
        data = ((uint32_t) stack->rxAckId) << 24;
1142
        data |= ((uint32_t) stack->txAckId) << 8;
1143
        data |= ((uint32_t) stack->txAckIdWindow);
1144
        break;
1145
      case PORT_N_ERROR_AND_STATUS_CSR(EXTENDED_FEATURES_OFFSET, 0u):
1146
        /* Indicate the port status here. */
1147
        if((stack->txState == TX_STATE_LINK_INITIALIZED) &&
1148
           (stack->rxState == RX_STATE_LINK_INITIALIZED))
1149
        {
1150
          /* Port ok. */
1151
          data = 0x00000002ul;
1152
        }
1153
        else
1154
        {
1155
          /* Port not ok. */
1156
          data = 0x00000001ul;
1157
        }
1158
        break;
1159
      default:
1160
        data = 0x00000000ul;
1161
        break;
1162
    }
1163
  }
1164
  else
1165
  {
1166
    /* Access is in implementation-defined space. */
1167
 
1168
    /* Check if there are any registered callback. */
1169
    if((stack->observer != NULL) &&
1170
       (stack->observer->configRead != NULL))
1171
    {
1172
      /* Call the observer callback to handle the access. */
1173
      data = stack->observer->configRead(stack, offset - 0x00010000ul);
1174
    }
1175
    else
1176
    {
1177
      data = 0x00000000ul;
1178
    }
1179
  }
1180
 
1181
  return data;
1182
}
1183
 
1184
 
1185
void RIO_writeConfig( RioStack_t *stack, const uint32_t offset, const uint32_t data)
1186
{
1187
  /* Check the area of the access. */
1188
  if(offset < 0x00010000ul)
1189
  {
1190
    /* Access is not in implementation-defined space. */
1191
 
1192
    /* Check offset and execute request. */
1193
    switch(offset)
1194
    {
1195
      case BASE_DEVICE_ID_CSR:
1196
        stack->baseDeviceId = (uint16_t) data;
1197
        break;
1198
      case HOST_BASE_DEVICE_ID_LOCK_CSR:
1199
        if (stack->hostBaseDeviceIdLock == 0xfffffffful)
1200
        {
1201
          stack->hostBaseDeviceIdLock = (uint16_t)data;
1202
        }
1203
        else
1204
        {
1205
          if ((stack->hostBaseDeviceIdLock & (uint32_t)0x0000fffful) ==
1206
              (data & (uint32_t)0x0000fffful))
1207
          {
1208
            stack->hostBaseDeviceIdLock = 0xfffffffful;
1209
          }
1210
          else
1211
          {
1212
            /* Ignore the write. */
1213
          }
1214
        }
1215
        break;
1216
      case COMPONENT_TAG_CSR:
1217
        stack->componentTag = data;
1218
        break;
1219
      case PORT_LINK_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
1220
        /* REMARK: Implement this... */
1221
        break;
1222
      case PORT_RESPONSE_TIMEOUT_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
1223
        /* REMARK: Implement this... */
1224
        break;
1225
      case PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET):
1226
        /* Return host, master enable bit and discovered bit. */
1227
        stack->host = (uint8_t)(data >> 31) & 1u;
1228
        stack->masterEnable = (uint8_t)(data >> 30) & 1u;
1229
        stack->discovered = (uint8_t)(data >> 29) & 1u;
1230
        break;
1231
      case PORT_N_LOCAL_ACKID_CSR(EXTENDED_FEATURES_OFFSET, 0u):
1232
        if(data & 0x80000000)
1233
        {
1234
          while(!QueueEmpty(stack->txQueue))
1235
          {
1236
            stack->txQueue = QueueDequeue(stack->txQueue);
1237
          }
1238
        }
1239
        stack->rxAckId = (uint8_t) ((data >> 24) & 0x1f);
1240
        stack->txAckId = (uint8_t) ((data >> 8) & 0x1f);
1241
        stack->txAckIdWindow = (uint8_t) (data & 0x1f);
1242
        break;
1243
      default:
1244
        break;
1245
    }
1246
  }
1247
  else
1248
  {
1249
    /* Access is in implementation-defined space. */
1250
 
1251
    /* Check if there are any registered callback. */
1252
    if((stack->observer != NULL) &&
1253
       (stack->observer->configWrite != NULL))
1254
    {
1255
      /* Call the observer callback to handle the access. */
1256
      stack->observer->configWrite(stack, offset - 0x00010000ul, data);
1257
    }
1258
    else
1259
    {
1260
      /* Dont do anything. */
1261
    }
1262
  }
1263
}
1264
 
1265
 
1266
/*******************************************************************************************
1267
 * Logical I/O MAINTENANCE-READ functions.
1268
 *******************************************************************************************/
1269
 
1270
#ifdef RIO_TRANSPARENT
1271
void RIO_sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1272
                                     const uint8_t hopCount, const uint32_t offset)
1273
{
1274
  sendMaintenanceReadRequest(stack, destid, srcid, tid, hopCount, offset);
1275
}
1276
#else
1277
void RIO_sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1278
                                     const uint8_t hopCount, const uint32_t offset)
1279
{
1280
  sendMaintenanceReadRequest(stack, destid, stack->baseDeviceId, tid, hopCount, offset);
1281
}
1282
#endif
1283
 
1284
#ifdef RIO_TRANSPARENT
1285
void RIO_receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1286
                                        uint8_t *hopCount, uint32_t *offset)
1287
{
1288
  receiveMaintenanceReadRequest( stack, destid, srcid, tid, hopCount, offset);
1289
}
1290
#else
1291
void RIO_receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1292
                                        uint8_t *hopCount, uint32_t *offset)
1293
{
1294
  receiveMaintenanceReadRequest( stack, srcid, srcid, tid, hopCount, offset);
1295
}
1296
#endif
1297
 
1298
#ifdef RIO_TRANSPARENT
1299
void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1300
                                      const uint8_t hopCount, const uint32_t data)
1301
{
1302
  sendMaintenanceReadResponse(stack, destid, srcid, tid, hopCount, data);
1303
}
1304
#else
1305
void RIO_sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1306
                                      const uint8_t hopCount, const uint32_t data)
1307
{
1308
  sendMaintenanceReadResponse(stack, destid, stack->baseDeviceId, tid, hopCount, data);
1309
}
1310
#endif
1311
 
1312
#ifdef RIO_TRANSPARENT
1313
void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1314
                                         uint8_t *hopCount, uint32_t *data)
1315
{
1316
  receiveMaintenanceReadResponse(stack, destid, srcid, tid, hopCount, data);
1317
}
1318
#else
1319
void RIO_receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1320
                                         uint8_t *hopCount, uint32_t *data)
1321
{
1322
  receiveMaintenanceReadResponse(stack, srcid, srcid, tid, hopCount, data);
1323
}
1324
#endif
1325
 
1326
/*******************************************************************************************
1327
 * Logical I/O MAINTENANCE-WRITE functions.
1328
 *******************************************************************************************/
1329
 
1330
#ifdef RIO_TRANSPARENT
1331
void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1332
                                      const uint8_t hopCount, const uint32_t offset, const uint32_t data )
1333
{
1334
  sendMaintenanceWriteRequest(stack, destid, srcid, tid, hopCount, offset, data);
1335
}
1336
#else
1337
void RIO_sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1338
                                      const uint8_t hopCount, const uint32_t offset, const uint32_t data )
1339
{
1340
  sendMaintenanceWriteRequest(stack, destid, stack->baseDeviceId, tid, hopCount, offset, data);
1341
}
1342
#endif
1343
 
1344
#ifdef RIO_TRANSPARENT
1345
void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1346
                                         uint8_t *hopCount, uint32_t *offset, uint32_t *data )
1347
{
1348
  receiveMaintenanceWriteRequest(stack, destid, srcid, tid, hopCount, offset, data);
1349
}
1350
#else
1351
void RIO_receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1352
                                         uint8_t *hopCount, uint32_t *offset, uint32_t *data )
1353
{
1354
  receiveMaintenanceWriteRequest(stack, srcid, srcid, tid, hopCount, offset, data);
1355
}
1356
#endif
1357
 
1358
#ifdef RIO_TRANSPARENT
1359
void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1360
                                       const uint8_t hopCount)
1361
{
1362
  sendMaintenanceWriteResponse(stack, destid, srcid, tid, hopCount);
1363
}
1364
#else
1365
void RIO_sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1366
                                       const uint8_t hopCount)
1367
{
1368
  sendMaintenanceWriteResponse(stack, destid, stack->baseDeviceId, tid, hopCount);
1369
}
1370
#endif
1371
 
1372
#ifdef RIO_TRANSPARENT
1373
void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1374
                                      uint8_t *hopCount)
1375
{
1376
  receiveMaintenanceWriteResponse(stack, destid, srcid, tid, hopCount);
1377
}
1378
#else
1379
void RIO_receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1380
                                      uint8_t *hopCount)
1381
{
1382
  receiveMaintenanceWriteResponse(stack, srcid, srcid, tid, hopCount);
1383
}
1384
#endif
1385
 
1386
/*******************************************************************************************
1387
 * Logical I/O NWRITE/NWRITER functions.
1388
 *******************************************************************************************/
1389
 
1390
#ifdef RIO_TRANSPARENT
1391
void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid,
1392
                     const uint32_t address, const uint16_t size, const uint8_t *data)
1393
{
1394
  sendNwrite(stack, destid, srcid, 0, address, size, data, 0u);
1395
}
1396
#else
1397
void RIO_sendNwrite( RioStack_t *stack, const uint16_t destid,
1398
                     const uint32_t address, const uint16_t size, const uint8_t *data)
1399
{
1400
  sendNwrite(stack, destid, stack->baseDeviceId, 0, address, size, data, 0u);
1401
}
1402
#endif
1403
 
1404
#ifdef RIO_TRANSPARENT
1405
void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1406
                      const uint32_t address, const uint16_t size, const uint8_t *data)
1407
{
1408
  sendNwrite(stack, destid, srcid, tid, address, size, data, 1u);
1409
}
1410
#else
1411
void RIO_sendNwriteR( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1412
                      const uint32_t address, const uint16_t size, const uint8_t *data)
1413
{
1414
  sendNwrite(stack, destid, stack->baseDeviceId, tid, address, size, data, 1u);
1415
}
1416
#endif
1417
 
1418
#ifdef RIO_TRANSPARENT
1419
uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1420
                        uint32_t *address, const uint16_t dataLength, uint8_t *data )
1421
{
1422
  return receiveNwrite(stack, destid, srcid, tid, address, dataLength, data);
1423
}
1424
#else
1425
uint16_t RIO_receiveNwrite( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1426
                        uint32_t *address, const uint16_t dataLength, uint8_t *data )
1427
{
1428
  return receiveNwrite(stack, srcid, srcid, tid, address, dataLength, data);
1429
}
1430
#endif
1431
 
1432
/*******************************************************************************************
1433
 * Logical I/O NREAD functions.
1434
 *******************************************************************************************/
1435
 
1436
#ifdef RIO_TRANSPARENT
1437
void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1438
                    const uint32_t address, const uint16_t dataLength)
1439
{
1440
  sendNread(stack, destid, srcid, tid, address, dataLength);
1441
}
1442
#else
1443
void RIO_sendNread( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1444
                    const uint32_t address, const uint16_t dataLength)
1445
{
1446
  sendNread(stack, destid, stack->baseDeviceId, tid, address, dataLength);
1447
}
1448
#endif
1449
 
1450
#ifdef RIO_TRANSPARENT
1451
void RIO_receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1452
                       uint32_t *address, uint16_t *dataLength)
1453
{
1454
  receiveNread( stack, destid, srcid, tid, address, dataLength);
1455
}
1456
#else
1457
void RIO_receiveNread( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1458
                       uint32_t *address, uint16_t *dataLength)
1459
{
1460
  receiveNread( stack, srcid, srcid, tid, address, dataLength);
1461
}
1462
#endif
1463
 
1464
/*******************************************************************************************
1465
 * Logical I/O RESPONSE-DONE-PAYLOAD, RESPONSE-DONE, RESPONSE-RETRY and RESPONSE-ERROR
1466
 * functions.
1467
 *******************************************************************************************/
1468
 
1469
 
1470
#ifdef RIO_TRANSPARENT
1471
void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1472
                                  const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
1473
{
1474
  sendResponseDonePayload(stack, destid, srcid, tid, address, bufferSize, buffer);
1475
}
1476
#else
1477
void RIO_sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1478
                                  const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
1479
{
1480
  sendResponseDonePayload(stack, destid, stack->baseDeviceId, tid, address, bufferSize, buffer);
1481
}
1482
#endif
1483
 
1484
#ifdef RIO_TRANSPARENT
1485
uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1486
                                         const uint32_t address, const uint16_t dataLength, uint8_t *data )
1487
{
1488
  return receiveResponseDonePayload(stack, destid, srcid, tid, address, dataLength, data);
1489
}
1490
#else
1491
uint16_t RIO_receiveResponseDonePayload( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1492
                                         const uint32_t address, const uint16_t dataLength, uint8_t *data )
1493
{
1494
  return receiveResponseDonePayload(stack, srcid, srcid, tid, address, dataLength, data);
1495
}
1496
#endif
1497
 
1498
#ifdef RIO_TRANSPARENT
1499
void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid)
1500
{
1501
  sendResponse(stack, destid, srcid, tid, 0x0u);
1502
}
1503
#else
1504
void RIO_sendResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t tid)
1505
{
1506
  sendResponse(stack, destid, stack->baseDeviceId, tid, 0x0u);
1507
}
1508
#endif
1509
 
1510
 
1511
#ifdef RIO_TRANSPARENT
1512
void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
1513
{
1514
  receiveResponse(stack, destid, srcid, tid);
1515
}
1516
#else
1517
void RIO_receiveResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
1518
{
1519
  receiveResponse(stack, srcid, srcid, tid);
1520
}
1521
#endif
1522
 
1523
 
1524
#ifdef RIO_TRANSPARENT
1525
void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid )
1526
{
1527
  sendResponse(stack, destid, srcid, tid, 0x3u);
1528
}
1529
#else
1530
void RIO_sendResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t tid )
1531
{
1532
  sendResponse(stack, destid, stack->baseDeviceId, tid, 0x3u);
1533
}
1534
#endif
1535
 
1536
 
1537
#ifdef RIO_TRANSPARENT
1538
void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
1539
{
1540
  receiveResponse(stack, destid, srcid, tid);
1541
}
1542
#else
1543
void RIO_receiveResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
1544
{
1545
  receiveResponse(stack, srcid, srcid, tid);
1546
}
1547
#endif
1548
 
1549
 
1550
#ifdef RIO_TRANSPARENT
1551
void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid)
1552
{
1553
  sendResponse(stack, destid, srcid, tid, 0x7u);
1554
}
1555
#else
1556
void RIO_sendResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t tid)
1557
{
1558
  sendResponse(stack, destid, stack->baseDeviceId, tid, 0x7u);
1559
}
1560
#endif
1561
 
1562
 
1563
#ifdef RIO_TRANSPARENT
1564
void RIO_receiveResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
1565
{
1566
  receiveResponse(stack, destid, srcid, tid);
1567
}
1568
#else
1569
void RIO_receiveResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *tid)
1570
{
1571
  receiveResponse(stack, srcid, srcid, tid);
1572
}
1573
#endif
1574
 
1575
 
1576
 
1577
/*******************************************************************************************
1578
 * Logical message passing DOORBELL and MESSAGE functions.
1579
 *******************************************************************************************/
1580
 
1581
#ifdef RIO_TRANSPARENT
1582
void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
1583
                       const uint16_t info )
1584
{
1585
  sendDoorbell(stack, destid, srcid, tid, info);
1586
}
1587
#else
1588
void RIO_sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint8_t tid,
1589
                       const uint16_t info )
1590
{
1591
  sendDoorbell(stack, destid, stack->baseDeviceId, tid, info);
1592
}
1593
#endif
1594
 
1595
#ifdef RIO_TRANSPARENT
1596
void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
1597
                          uint16_t *info)
1598
{
1599
  receiveDoorbell(stack, destid, srcid, tid, info);
1600
}
1601
#else
1602
void RIO_receiveDoorbell( RioStack_t *stack, uint16_t *srcid, uint8_t *tid,
1603
                          uint16_t *info)
1604
{
1605
  receiveDoorbell(stack, srcid, srcid, tid, info);
1606
}
1607
#endif
1608
 
1609
#ifdef RIO_TRANSPARENT
1610
void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
1611
                      const uint16_t bufferSize, const uint8_t* bufferData)
1612
{
1613
  sendMessage(stack, destid, srcid, mailbox, bufferSize, bufferData);
1614
}
1615
#else
1616
void RIO_sendMessage( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox,
1617
                      const uint16_t bufferSize, const uint8_t* bufferData)
1618
{
1619
  sendMessage(stack, destid, stack->baseDeviceId, mailbox, bufferSize, bufferData);
1620
}
1621
#endif
1622
 
1623
#ifdef RIO_TRANSPARENT
1624
uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
1625
                             const uint16_t dataLength, uint8_t *data )
1626
{
1627
  return receiveMessage(stack, destid, srcid, mailbox, dataLength, data);
1628
}
1629
#else
1630
uint16_t RIO_receiveMessage( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox,
1631
                             const uint16_t dataLength, uint8_t *data )
1632
{
1633
  return receiveMessage(stack, srcid, srcid, mailbox, dataLength, data);
1634
}
1635
#endif
1636
 
1637
/*******************************************************************************************
1638
 * Logical message passing MESSAGE-RESPONSE functions.
1639
 *******************************************************************************************/
1640
 
1641
#ifdef RIO_TRANSPARENT
1642
void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
1643
{
1644
  sendMessageResponse(stack, destid, srcid, mailbox, 0x0u);
1645
}
1646
#else
1647
void RIO_sendMessageResponseDone( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
1648
{
1649
  sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x0u);
1650
}
1651
#endif
1652
 
1653
 
1654
#ifdef RIO_TRANSPARENT
1655
void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
1656
{
1657
  receiveMessageResponse(stack, destid, srcid, mailbox);
1658
}
1659
#else
1660
void RIO_receiveMessageResponseDone( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
1661
{
1662
  receiveMessageResponse(stack, srcid, srcid, mailbox);
1663
}
1664
#endif
1665
 
1666
 
1667
#ifdef RIO_TRANSPARENT
1668
void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
1669
{
1670
  sendMessageResponse(stack, destid, srcid, mailbox, 0x3u);
1671
}
1672
#else
1673
void RIO_sendMessageResponseRetry( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
1674
{
1675
  sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x3u);
1676
}
1677
#endif
1678
 
1679
 
1680
#ifdef RIO_TRANSPARENT
1681
void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
1682
{
1683
  receiveMessageResponse(stack, destid, srcid, mailbox);
1684
}
1685
#else
1686
void RIO_receiveMessageResponseRetry( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
1687
{
1688
  receiveMessageResponse(stack, srcid, srcid, mailbox);
1689
}
1690
#endif
1691
 
1692
 
1693
#ifdef RIO_TRANSPARENT
1694
void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox)
1695
{
1696
  sendMessageResponse(stack, destid, srcid, mailbox, 0x7u);
1697
}
1698
#else
1699
void RIO_sendMessageResponseError( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox)
1700
{
1701
  sendMessageResponse(stack, destid, stack->baseDeviceId, mailbox, 0x7u);
1702
}
1703
#endif
1704
 
1705
 
1706
#ifdef RIO_TRANSPARENT
1707
void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
1708
{
1709
  receiveMessageResponse(stack, destid, srcid, mailbox);
1710
}
1711
#else
1712
void RIO_receiveMessageResponseError( RioStack_t *stack, uint16_t *srcid, uint8_t *mailbox)
1713
{
1714
  receiveMessageResponse(stack, srcid, srcid, mailbox);
1715
}
1716
#endif
1717
 
1718
 
1719
void RIO_portSetStatus( RioStack_t *stack, const uint8_t initialized)
1720
{
1721
  /* REMARK: Clean the queues here as well??? */
1722
  if (initialized)
1723
  {
1724
    stack->rxState = RX_STATE_PORT_INITIALIZED;
1725
    stack->rxCounter = 0u;
1726
    stack->rxCrc = 0xffffu;
1727
    stack->rxStatusReceived = 0;
1728
    stack->rxAckId = 0u;
1729
    stack->rxAckIdAcked = 0u;
1730
    stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED;
1731
 
1732
    stack->txState = TX_STATE_PORT_INITIALIZED;
1733
    stack->txCounter = 0u;
1734
    stack->txStatusCounter = 0u;
1735
    stack->txFrameState = TX_FRAME_START;
1736
    stack->txAckId = 0u;
1737
    stack->txAckIdWindow = 0u;
1738
  }
1739
  else
1740
  {
1741
    stack->rxState = RX_STATE_UNINITIALIZED;
1742
    stack->txState = TX_STATE_UNINITIALIZED;
1743
  }
1744
}
1745
 
1746
 
1747
void RIO_portSetTime( RioStack_t *stack, const uint32_t time)
1748
{
1749
  stack->portTime = time;
1750
}
1751
 
1752
 
1753
void RIO_portSetTimeout( RioStack_t *stack, const uint32_t time)
1754
{
1755
  stack->portTimeout = time;
1756
}
1757
 
1758
 
1759
void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s)
1760
{
1761
  uint8_t stype0;
1762
  uint8_t parameter0;
1763
  uint8_t parameter1;
1764
  uint8_t stype1;
1765
 
1766
 
1767
  switch(stack->rxState)
1768
  {
1769
    case RX_STATE_PORT_INITIALIZED:
1770
      /******************************************************************************
1771
       * PORT_INITIALIZED
1772
       * This state is entered to initialize the link. Only status-control-symbols
1773
       * are accepted in this state. When 7 error-free, i.e. with CRC5 correct, status
1774
       * control symbols has been received, change state to linkInitialized.
1775
       ******************************************************************************/
1776
 
1777
      /* Check the type of symbol. */
1778
      if(s.type == RIO_SYMBOL_TYPE_CONTROL)
1779
      {
1780
        /* This is a control symbol. */
1781
 
1782
        /* Check that the control symbol contains no errors. */
1783
        if(Crc5(s.data, 0x1fu) == (s.data & 0x1ful))
1784
        {
1785
          /* Error-free control symbol. */
1786
 
1787
          /* Check if the symbol is a status symbol. */
1788
          stype0 = STYPE0_GET(s.data);
1789
          if(stype0 == STYPE0_STATUS)
1790
          {
1791
            /* Status symbol received. */
1792
 
1793
            /* Indicate an error-free status has been received. */
1794
            stack->rxStatusReceived = 1;
1795
 
1796
            /* Check if enough status control symbols has been received. */
1797
            if(stack->rxCounter == 7u)
1798
            {
1799
              /* Enough correct status control symbols has been received without
1800
                 errors in between. */
1801
 
1802
              /* Setup the transmitter with the content of the symbol. */
1803
              stack->txAckId = PARAMETER0_GET(s.data);
1804
              stack->txAckIdWindow = stack->txAckId;
1805
              stack->txBufferStatus = PARAMETER1_GET(s.data);
1806
 
1807
              /* Set the transmitter in its normal operational mode. */
1808
              stack->rxState = RX_STATE_LINK_INITIALIZED;
1809
              stack->rxCounter = 0u;
1810
              DEBUG_STATE("rx:normal");
1811
            }
1812
            else
1813
            {
1814
              /* Count the number of consequitive error-free status control symbols
1815
                 that has been received. */
1816
              stack->rxCounter++;
1817
            }
1818
          }
1819
          else
1820
          {
1821
            /* The received symbol is not a status symbol. */
1822
            /* Discard it. */
1823
          }
1824
        }
1825
        else
1826
        {
1827
          /* CRC error in control symbol. */
1828
          /* Restart counting error-free status-control-symbols. */
1829
          stack->rxCounter = 0u;
1830
        }
1831
      }
1832
      else
1833
      {
1834
        /* Not a control symbol. */
1835
        /* Discard the symbol. */
1836
      }
1837
 
1838
      break;
1839
 
1840
    case RX_STATE_LINK_INITIALIZED:
1841
      /******************************************************************************
1842
       * LINK_INITIALIZED
1843
       * The normal state. Accept packets and forward them.
1844
       ******************************************************************************/
1845
 
1846
      /* Check the type of symbol. */
1847
      switch(s.type)
1848
      {
1849
        case RIO_SYMBOL_TYPE_CONTROL:
1850
          /**************************************************************************
1851
           * This is a control symbol.
1852
           **************************************************************************/
1853
 
1854
          /* Check if the CRC is correct. */
1855
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
1856
          {
1857
            /* The CRC is correct. */
1858
 
1859
            /* Get the content of the control symbol. */
1860
            stype0 = STYPE0_GET(s.data);
1861
            parameter0 = PARAMETER0_GET(s.data);
1862
            parameter1 = PARAMETER1_GET(s.data);
1863
            stype1 = STYPE1_GET(s.data);
1864
 
1865
            /**********************************************************************************
1866
             * Check the stype0 part of the symbol.
1867
             * Note that errors in this should trigger OUTPUT_ERROR_STOPPED.
1868
             **********************************************************************************/
1869
            switch(stype0)
1870
            {
1871
              case STYPE0_STATUS:
1872
                /* A status containing the current ackId and the buffer status has been
1873
                   received. */
1874
                handleStatus(stack, parameter0, parameter1);
1875
                break;
1876
 
1877
              case STYPE0_PACKET_ACCEPTED:
1878
                /* A packet has been accepted by the link partner. */
1879
                handlePacketAccepted(stack, parameter0, parameter1);
1880
                break;
1881
 
1882
              case STYPE0_PACKET_RETRY:
1883
                /* The link partner wants us to initiate a restart of the received ackId. */
1884
                handlePacketRetry(stack, parameter0, parameter1);
1885
                break;
1886
 
1887
              case STYPE0_PACKET_NOT_ACCEPTED:
1888
                /* The link partner indicates that a packet has been rejected. */
1889
                handlePacketNotAccepted(stack, parameter0, parameter1);
1890
                break;
1891
 
1892
              case STYPE0_LINK_RESPONSE:
1893
                /* The link partner has sent a response to a link-request. */
1894
                handleLinkResponse(stack, parameter0, parameter1);
1895
                break;
1896
 
1897
              case STYPE0_VC_STATUS:
1898
              case STYPE0_RESERVED:
1899
              case STYPE0_IMPLEMENTATION_DEFINED:
1900
              default:
1901
                /* Unsupported symbol received. */
1902
                /* Discard them. */
1903
                break;
1904
            }
1905
 
1906
            /**********************************************************************************
1907
             * Check the stype1 part of the symbol.
1908
             * Note that errors in this should trigger INPUT_ERROR_STOPPED.
1909
             **********************************************************************************/
1910
            switch(stype1)
1911
            {
1912
              case STYPE1_START_OF_PACKET:
1913
                /* Start of a new packet. */
1914
                handleStartOfPacket(stack);
1915
                break;
1916
 
1917
              case STYPE1_END_OF_PACKET:
1918
                /* Ending a packet. */
1919
                handleEndOfPacket(stack);
1920
                break;
1921
 
1922
              case STYPE1_STOMP:
1923
                /* Cancel the currently received frame. */
1924
                stack->rxCounter = 0;
1925
                break;
1926
 
1927
              case STYPE1_RESTART_FROM_RETRY:
1928
                /* Cancel the currently received frame when in this state. */
1929
                stack->rxCounter = 0;
1930
                break;
1931
 
1932
              case STYPE1_LINK_REQUEST:
1933
                /* A link-request has been received. */
1934
                handleLinkRequest(stack, CMD_GET(s.data));
1935
                break;
1936
 
1937
              case STYPE1_NOP:
1938
                /* No operation symbol. */
1939
                /* Discard these. */
1940
                break;
1941
 
1942
              case STYPE1_MULTICAST_EVENT:
1943
              case STYPE1_RESERVED:
1944
              default:
1945
                /* Unsupported symbol received. */
1946
                /* Discard them. */
1947
                break;
1948
            }
1949
          }
1950
          else
1951
          {
1952
            /* The control symbol CRC is incorrect. */
1953
            /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
1954
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
1955
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
1956
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
1957
            stack->statusInboundErrorControlCrc++;
1958
            DEBUG_STATE("rx:error-stopped");
1959
          }
1960
          break;
1961
 
1962
        case RIO_SYMBOL_TYPE_DATA:
1963
          /**************************************************************************
1964
           * This is a data symbol.
1965
           **************************************************************************/
1966
 
1967
          /* Check if a packet has been started and that it is not too long. */
1968
          if ((stack->rxCounter >= 1u) && (stack->rxCounter <= RIO_PACKET_SIZE))
1969
          {
1970
            /* A packet has been started. */
1971
 
1972
            /* Check if the ackId is correct on the first part of the packet. */
1973
            if ((stack->rxCounter > 1u) ||
1974
                ((stack->rxCounter == 1u) && (((uint8_t)(s.data >> 27)) == stack->rxAckId)))
1975
            {
1976
              /* The ackId is the expected one. */
1977
 
1978
              /* Check if this is the first symbol of a packet. */
1979
              if (stack->rxCounter == 1u)
1980
              {
1981
                /* This is the first symbol of the packet. */
1982
                /* Start to calculate the CRC of the packet. */
1983
                /* Note that the ackId should not be included in the CRC calculation. */
1984
                stack->rxCrc = Crc32(s.data & (uint32_t)0x03fffffful, 0xffffu);
1985
              }
1986
              else
1987
              {
1988
                /* This is not the first symbol. */
1989
                /* Continue to calculate the CRC of the packet. */
1990
                stack->rxCrc = Crc32(s.data, stack->rxCrc);
1991
              }
1992
 
1993
              /* Save the new data in the packet queue and update the reception counter. */
1994
              QueueSetContent(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul, s.data);
1995
              stack->rxCounter++;
1996
            }
1997
            else
1998
            {
1999
              DEBUG_FRAMING_RX("error=%u %u", stack->rxAckId, s.data>>27);
2000
 
2001
              /* The ackId is not correct. */
2002
              /* Packet error. Enter input-error-stopped state. */
2003
              stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
2004
              stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
2005
              stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
2006
              stack->statusInboundErrorPacketAckId++;
2007
              DEBUG_STATE("rx:error-stopped");
2008
            }
2009
          }
2010
          else
2011
          {
2012
            /* No packet has been started or the packet is too long. */
2013
            /* Packet error. Enter input-error-stopped state. */
2014
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
2015
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
2016
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
2017
            stack->statusInboundErrorGeneral++;
2018
            DEBUG_STATE("rx:error-stopped");
2019
          }
2020
          break;
2021
 
2022
        case RIO_SYMBOL_TYPE_ERROR:
2023
          /**************************************************************************
2024
           * The decoder has received a erronous symbol.
2025
           **************************************************************************/
2026
 
2027
          /* Idle symbol error. Place the receiver in input-error-stopped state. */
2028
          stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
2029
          stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
2030
          stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
2031
          stack->statusInboundErrorIllegalCharacter++;
2032
          DEBUG_STATE("rx:error-stopped");
2033
          break;
2034
 
2035
        case RIO_SYMBOL_TYPE_IDLE:
2036
        default:
2037
          /**************************************************************************
2038
           * Idle symbol or unsupported symbol.
2039
           **************************************************************************/
2040
 
2041
          /* Discard these for now. */
2042
          break;
2043
      }
2044
      break;
2045
 
2046
    case RX_STATE_INPUT_RETRY_STOPPED:
2047
      /******************************************************************************
2048
       * INPUT_RETRY_STOPPED
2049
       * This state is entered when no more buffers was available and a packet was
2050
       * received. When in this state, all packets should be discarded until a
2051
       * RESTART-FROM-RETRY symbol is received. See section 5.9.1.4 of the standard.
2052
       * Note that it is only the input side of the port that are affected, not the
2053
       * output side. Packets may still be transmitted and acknowledges should be
2054
       * accepted.
2055
       ******************************************************************************/
2056
 
2057
      /* Check the type of symbol. */
2058
      switch(s.type)
2059
      {
2060
        case RIO_SYMBOL_TYPE_CONTROL:
2061
          /* This is a control symbol. */
2062
 
2063
          /* Check if the CRC is correct. */
2064
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
2065
          {
2066
            /* The CRC is correct. */
2067
 
2068
            /* Get the content of the control symbol. */
2069
            stype0 = STYPE0_GET(s.data);
2070
            parameter0 = PARAMETER0_GET(s.data);
2071
            parameter1 = PARAMETER1_GET(s.data);
2072
            stype1 = STYPE1_GET(s.data);
2073
 
2074
            /* Check the stype0 part of the symbol. */
2075
            switch(stype0)
2076
            {
2077
              case STYPE0_STATUS:
2078
                /* A status containing the current ackId and the buffer status has been
2079
                   received. */
2080
                handleStatus(stack, parameter0, parameter1);
2081
                break;
2082
 
2083
              case STYPE0_PACKET_ACCEPTED:
2084
                /* A packet has been accepted by the link partner. */
2085
                handlePacketAccepted(stack, parameter0, parameter1);
2086
                break;
2087
 
2088
              case STYPE0_PACKET_RETRY:
2089
                /* The link partner wants us to initiate a restart of the received ackId. */
2090
                handlePacketRetry(stack, parameter0, parameter1);
2091
                break;
2092
 
2093
              case STYPE0_PACKET_NOT_ACCEPTED:
2094
                /* The link partner indicates that a packet has been rejected. */
2095
                handlePacketNotAccepted(stack, parameter0, parameter1);
2096
                break;
2097
 
2098
              case STYPE0_LINK_RESPONSE:
2099
                /* The link partner has sent a response to a link-request. */
2100
                handleLinkResponse(stack, parameter0, parameter1);
2101
                break;
2102
 
2103
              case STYPE0_VC_STATUS:
2104
              case STYPE0_RESERVED:
2105
              case STYPE0_IMPLEMENTATION_DEFINED:
2106
              default:
2107
                /* Unsupported symbol received. */
2108
                /* Discard them. */
2109
                break;
2110
            }
2111
 
2112
            /* Check the stype1 part of the symbol. */
2113
            switch(stype1)
2114
            {
2115
              case STYPE1_START_OF_PACKET:
2116
                /* Starting new frames are ignored in this state. */
2117
                break;
2118
 
2119
              case STYPE1_END_OF_PACKET:
2120
                /* Ending new frames are ignored in this state. */
2121
                break;
2122
 
2123
              case STYPE1_STOMP:
2124
                /* Restarting frames are ignored in this state. */
2125
                break;
2126
 
2127
              case STYPE1_RESTART_FROM_RETRY:
2128
                /* The link partner has confirmed our packet-retry-symbol. */
2129
                /* Go back to the normal state and reset the frame reception. */
2130
                stack->rxState = RX_STATE_LINK_INITIALIZED;
2131
                stack->rxCounter = 0u;
2132
                DEBUG_STATE("rx:normal(restart)");
2133
                break;
2134
 
2135
              case STYPE1_LINK_REQUEST:
2136
                /* A link-request has been received. */
2137
                handleLinkRequest(stack, CMD_GET(s.data));
2138
                stack->rxState = RX_STATE_LINK_INITIALIZED;
2139
                DEBUG_STATE("rx:normal(link-req)");
2140
                break;
2141
 
2142
              case STYPE1_NOP:
2143
                /* No operation symbol. */
2144
                /* Discard these. */
2145
                break;
2146
 
2147
              case STYPE1_MULTICAST_EVENT:
2148
              case STYPE1_RESERVED:
2149
              default:
2150
                /* Unsupported symbol received. */
2151
                /* Discard them. */
2152
                break;
2153
            }
2154
          }
2155
          else
2156
          {
2157
            /* The control symbol CRC is incorrect. */
2158
            /* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */
2159
            stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
2160
            stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
2161
            stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
2162
            stack->statusInboundErrorControlCrc++;
2163
            DEBUG_STATE("rx:error-stopped");
2164
          }
2165
          break;
2166
 
2167
        case RIO_SYMBOL_TYPE_ERROR:
2168
          /* Idle symbol error. Place the receiver in input-error-stopped state. */
2169
          stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
2170
          stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
2171
          stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER;
2172
          stack->statusInboundErrorIllegalCharacter++;
2173
          DEBUG_STATE("rx:error-stopped");
2174
          break;
2175
 
2176
        case RIO_SYMBOL_TYPE_DATA:
2177
        case RIO_SYMBOL_TYPE_IDLE:
2178
        default:
2179
          /* Data or idle symbol. */
2180
          /* Discard these in this state. */
2181
          break;
2182
      }
2183
      break;
2184
 
2185
    case RX_STATE_INPUT_ERROR_STOPPED:
2186
      /******************************************************************************
2187
       * INPUT_ERROR_STOPPED
2188
       * This state is entered when an error situation has occurred. When in this
2189
       * state, all symbols should be discarded until a link-request-symbols has
2190
       * been received. See section 5.13.2.6 in part 6 of the standard.
2191
       * Note that it is only the input side of the port that are affected, not the
2192
       * output side. Packets may still be transmitted and acknowledges should be
2193
       * accepted.
2194
       ******************************************************************************/
2195
 
2196
      /* Check the type of symbol. */
2197
      switch(s.type)
2198
      {
2199
        case RIO_SYMBOL_TYPE_CONTROL:
2200
          /* This is a control symbol. */
2201
 
2202
          /* Check if the CRC is correct. */
2203
          if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful))
2204
          {
2205
            /* The CRC is correct. */
2206
 
2207
            /* Get the content of the control symbol. */
2208
            stype0 = STYPE0_GET(s.data);
2209
            parameter0 = PARAMETER0_GET(s.data);
2210
            parameter1 = PARAMETER1_GET(s.data);
2211
            stype1 = STYPE1_GET(s.data);
2212
 
2213
            /* Check the stype0 part of the symbol. */
2214
            switch(stype0)
2215
            {
2216
              case STYPE0_STATUS:
2217
                /* A status containing the current ackId and the buffer status has been
2218
                   received. */
2219
                handleStatus(stack, parameter0, parameter1);
2220
                break;
2221
 
2222
              case STYPE0_PACKET_ACCEPTED:
2223
                /* A packet has been accepted by the link partner. */
2224
                handlePacketAccepted(stack, parameter0, parameter1);
2225
                break;
2226
 
2227
              case STYPE0_PACKET_RETRY:
2228
                /* The link partner wants us to initiate a restart of the received ackId. */
2229
                handlePacketRetry(stack, parameter0, parameter1);
2230
                break;
2231
 
2232
              case STYPE0_PACKET_NOT_ACCEPTED:
2233
                /* The link partner indicates that a packet has been rejected. */
2234
                handlePacketNotAccepted(stack, parameter0, parameter1);
2235
                break;
2236
 
2237
              case STYPE0_LINK_RESPONSE:
2238
                /* The link partner has sent a response to a link-request. */
2239
                handleLinkResponse(stack, parameter0, parameter1);
2240
                break;
2241
 
2242
              case STYPE0_VC_STATUS:
2243
              case STYPE0_RESERVED:
2244
              case STYPE0_IMPLEMENTATION_DEFINED:
2245
              default:
2246
                /* Unsupported symbol received. */
2247
                /* Discard them. */
2248
                break;
2249
            }
2250
 
2251
            /* Check the stype1 part of the symbol. */
2252
            switch(stype1)
2253
            {
2254
              case STYPE1_START_OF_PACKET:
2255
                /* Starting new frames are ignored in this state. */
2256
                break;
2257
 
2258
              case STYPE1_END_OF_PACKET:
2259
                /* Ending new frames are ignored in this state. */
2260
                break;
2261
 
2262
              case STYPE1_STOMP:
2263
                /* Restarting frames are ignored in this state. */
2264
                break;
2265
 
2266
              case STYPE1_RESTART_FROM_RETRY:
2267
                /* Restart-from-retry are ignored in this state.  */
2268
                break;
2269
 
2270
              case STYPE1_LINK_REQUEST:
2271
                /* This is the symbol we have been waiting for. */
2272
                /* Force the transmitter to send a link-response and go back into the normal
2273
                   operational state. */
2274
                /* The transmitter will always send a status as the first symbol after this. */
2275
                handleLinkRequest(stack, CMD_GET(s.data));
2276
                stack->rxState = RX_STATE_LINK_INITIALIZED;
2277
                DEBUG_STATE("rx:normal(link-req)");
2278
                break;
2279
 
2280
              case STYPE1_NOP:
2281
                /* No operation symbol. */
2282
                /* Discard these. */
2283
                break;
2284
 
2285
              case STYPE1_MULTICAST_EVENT:
2286
              case STYPE1_RESERVED:
2287
              default:
2288
                /* Unsupported symbol received. */
2289
                /* Discard them. */
2290
                break;
2291
            }
2292
          }
2293
          else
2294
          {
2295
            /* The CRC is incorrect. */
2296
            /* Discard these in this state. */
2297
          }
2298
          break;
2299
 
2300
        case RIO_SYMBOL_TYPE_DATA:
2301
        case RIO_SYMBOL_TYPE_IDLE:
2302
        case RIO_SYMBOL_TYPE_ERROR:
2303
        default:
2304
          /* Data, idle or error symbol. */
2305
          /* Discard these in this state. */
2306
          break;
2307
      }
2308
      break;
2309
 
2310
    case RX_STATE_UNINITIALIZED:
2311
    default:
2312
      /******************************************************************************
2313
       * Wait for the port to be initialized.
2314
       ******************************************************************************/
2315
 
2316
      /* Discard all incoming symbols. */
2317
      break;
2318
  }
2319
}
2320
 
2321
 
2322
 
2323
RioSymbol RIO_portGetSymbol( RioStack_t *stack )
2324
{
2325
  RioSymbol s;
2326
 
2327
 
2328
  switch(stack->txState)
2329
  {
2330
    case TX_STATE_PORT_INITIALIZED:
2331
      /******************************************************************************
2332
       * PORT_INITIALIZED
2333
       * This state is entered to initialize the link. Send status-control-symbols
2334
       * once in a while until the receiver has received enough error-free status-
2335
       * control-symbols and we have transmitted enough status-control-symbols. Once
2336
       * an error-free status-control-symbol has been received, the statuses are
2337
       * transmitted more frequently to decrease the time for the link to be
2338
       * initialized.
2339
       ******************************************************************************/
2340
 
2341
      /* Check if an idle symbol or a status control symbol should be sent. */
2342
      if(((stack->rxStatusReceived == 0) && (stack->txCounter == 255u)) ||
2343
         ((stack->rxStatusReceived == 1) && (stack->txCounter >= 15u)))
2344
      {
2345
        /* A control symbol should be sent. */
2346
 
2347
        /* Create a new status symbol and reset the transmission counter. */
2348
        stack->txCounter = 0u;
2349
        s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2350
                                STYPE1_NOP, 0u);
2351
 
2352
        /* Check if the receiver has received any error-free status and that we
2353
           have sent at least 15 status control symbols. */
2354
        if((stack->rxStatusReceived == 1) && (stack->txStatusCounter < 15u))
2355
        {
2356
          /* Has not sent enough status control symbols. */
2357
          stack->txStatusCounter++;
2358
        }
2359
        else
2360
        {
2361
          /* Has sent enough status control symbols. */
2362
          /* Dont do anything. */
2363
        }
2364
      }
2365
      else
2366
      {
2367
        /* Idle symbol should be sent. */
2368
        s.type = RIO_SYMBOL_TYPE_IDLE;
2369
        stack->txCounter++;
2370
      }
2371
 
2372
      /* Check if we are ready to set the transmitter in a link initialized state. */
2373
      if ((stack->rxState == RX_STATE_LINK_INITIALIZED) && (stack->txStatusCounter == 15u))
2374
      {
2375
        /* Ready to go to link initialized. */
2376
        stack->txState = TX_STATE_LINK_INITIALIZED;
2377
        stack->txFrameState = TX_FRAME_START;
2378
        stack->txStatusCounter = 0u;
2379
        DEBUG_STATE("tx:normal");
2380
      }
2381
      else
2382
      {
2383
        /* Not ready to go to link initialized. */
2384
        /* Dont do anything. */
2385
      }
2386
 
2387
      break;
2388
 
2389
    case TX_STATE_LINK_INITIALIZED:
2390
      /******************************************************************************
2391
       * LINK_INITIALIZED
2392
       * The normal state. Accept packets and forward them. Send acknowledges when
2393
       * the receiver has received complete packets.
2394
       ******************************************************************************/
2395
 
2396
      /* Check if the receiver wants to acknowledge a packet. */
2397
      if(stack->rxAckId == stack->rxAckIdAcked)
2398
      {
2399
        /* The receiver does not want to acknowledge a packet. */
2400
 
2401
        /* Check if there are any outstanding packets and if it has timed out. */
2402
        if((stack->txAckId == stack->txAckIdWindow) ||
2403
           ((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout))
2404
        {
2405
          /* There are no outstanding packets or there has been no timeout. */
2406
 
2407
          /* Check if a packet is ongoing. */
2408
          if(stack->txFrameState == TX_FRAME_BODY)
2409
          {
2410
            /* A packet transmission is ongoing. */
2411
 
2412
            /* Check if the packet has been completly sent. */
2413
            if(stack->txCounter != QueueGetFrontSize(stack->txQueue))
2414
            {
2415
              /* The packet has not been completly sent. */
2416
 
2417
              /* Create a new data symbol to transmit. */
2418
              s.type = RIO_SYMBOL_TYPE_DATA;
2419
              s.data = QueueGetFrontContent(stack->txQueue, (uint32_t)stack->txCounter);
2420
 
2421
              /* Check if this is the first symbol in a packet. */
2422
              if (stack->txCounter == 0u)
2423
              {
2424
                /* Place the correct ackId in the right place. */
2425
                s.data |= (uint32_t)stack->txAckIdWindow << 27;
2426
              }
2427
              else
2428
              {
2429
                /* Dont do anything. */
2430
              }
2431
 
2432
              /* Update the transmission counter. */
2433
              stack->txCounter++;
2434
 
2435
              /* A status control symbol was not sent. Update the status counter. */
2436
              stack->txStatusCounter++;
2437
            }
2438
            else
2439
            {
2440
              /* The packet has been sent. */
2441
 
2442
              /* Save the timeout time and update to the next ackId. */
2443
              stack->txFrameTimeout[stack->txAckIdWindow] = stack->portTime;
2444
              stack->txAckIdWindow = ACKID_INC(stack->txAckIdWindow);
2445
              stack->txQueue = QueueWindowNext(stack->txQueue);
2446
 
2447
              /* Check if there are more packets pending to be sent. */
2448
              /* Also check that there are buffer available at the receiver and that not too many
2449
                 packets are outstanding. */
2450
              if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
2451
                 (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
2452
              {
2453
                /* More pending packets. */
2454
                DEBUG_FRAMING_TX("cont=%i", stack->txAckIdWindow);
2455
                /* Create a control symbol to signal that the new packet has started. */
2456
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2457
                                        STYPE1_START_OF_PACKET, 0u);
2458
 
2459
                /* Restart transmission counter. */
2460
                stack->txCounter = 0;
2461
              }
2462
              else
2463
              {
2464
                /* No more pending packets. */
2465
                DEBUG_FRAMING_TX("end=%i", stack->txAckIdWindow);
2466
                /* Create a control symbol to signal that the packet has ended. */
2467
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2468
                                        STYPE1_END_OF_PACKET, 0u);
2469
 
2470
                /* Go back to wait for a new frame. */
2471
                stack->txFrameState = TX_FRAME_START;
2472
              }
2473
 
2474
              /* A status control symbol has been sent. Reset the status counter. */
2475
              stack->txStatusCounter = 0u;
2476
            }
2477
          }
2478
          else
2479
          {
2480
            /* No packet is being sent. */
2481
 
2482
            /* Check if there are any pending packets to start sending. */
2483
            /* Also check that there are buffer available at the receiver and that not too many
2484
               packets are outstanding. */
2485
            if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) &&
2486
               (((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31))
2487
            {
2488
              /* There is a pending packet to send. */
2489
              DEBUG_FRAMING_TX("start=%i", stack->txAckIdWindow);
2490
              /* Send a start-of-packet control symbol to start to send the packet. */
2491
              s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2492
                                      STYPE1_START_OF_PACKET, 0u);
2493
              stack->txFrameState = TX_FRAME_BODY;
2494
              stack->txCounter = 0u;
2495
 
2496
              /* A status control symbol has been sent. Reset the status counter. */
2497
              stack->txStatusCounter = 0u;
2498
            }
2499
            else
2500
            {
2501
              /* There are no pending packets to send. */
2502
 
2503
              /* Check if a status control symbol must be transmitted. */
2504
              if(stack->txStatusCounter < 255u)
2505
              {
2506
                /* Not required to send a status control symbol. */
2507
 
2508
                /* Send an idle-symbol. */
2509
                s.type = RIO_SYMBOL_TYPE_IDLE;
2510
                stack->txStatusCounter++;
2511
              }
2512
              else
2513
              {
2514
                /* Must send a status control symbol. */
2515
 
2516
                /* Create a status control symbol. */
2517
                s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2518
                                        STYPE1_NOP, 0u);
2519
 
2520
                /* A status control symbol has been sent. Reset the status counter. */
2521
                stack->txStatusCounter = 0u;
2522
              }
2523
            }
2524
          }
2525
        }
2526
        else
2527
        {
2528
          /* There has been a timeout. */
2529
          /* A packet has been sent but no packet-accepted has been received. */
2530
          DEBUG_FRAMING_TX("timeout=%i", stack->txAckId);
2531
          /* Send link-request-symbol (input-status). */
2532
          s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2533
                                  STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
2534
 
2535
          /* Save the time when this was transmitted. */
2536
          stack->txFrameTimeout[stack->txAckId] = stack->portTime;
2537
 
2538
          /* Remember that this symbol has been transmitted. */
2539
          stack->txCounter = 1;
2540
 
2541
          /* Go into the output error stopped state. */
2542
          stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
2543
          stack->statusOutboundErrorTimeout++;
2544
          DEBUG_STATE("tx:error-stopped");
2545
        }
2546
      }
2547
      else
2548
      {
2549
        /* The receiver wants us to send an acknowledgement. */
2550
        s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
2551
                                STYPE1_NOP, 0u);
2552
        stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
2553
 
2554
        /* A status control symbol was not sent. Update the status counter. */
2555
        stack->txStatusCounter++;
2556
      }
2557
      break;
2558
 
2559
    case TX_STATE_SEND_PACKET_RETRY:
2560
      /******************************************************************************
2561
       * SEND_PACKET_RETRY
2562
       * This state is set by the receiver to force a packet-retry-symbol to be
2563
       * transmitted.
2564
       ******************************************************************************/
2565
 
2566
      /* Check if the receiver wants to acknowledge a packet. */
2567
      /* This must be done first or we will get an error for a missmatching
2568
         ackId in the link-partner. */
2569
      if(stack->rxAckId == stack->rxAckIdAcked)
2570
      {
2571
        /* No pending acknowledge. */
2572
 
2573
        /* Send a packet-retry symbol to tell the link partner to retry the last frame. */
2574
        s = CreateControlSymbol(STYPE0_PACKET_RETRY, stack->rxAckId, QueueAvailable(stack->rxQueue),
2575
                                STYPE1_NOP, 0u);
2576
 
2577
        /* Proceed with normal transmission. */
2578
        stack->txState = TX_STATE_LINK_INITIALIZED;
2579
 
2580
        /* A status control symbol was not sent. Update the status counter. */
2581
        stack->txStatusCounter++;
2582
      }
2583
      else
2584
      {
2585
 
2586
        /* The receiver wants us to send an acknowledgement. */
2587
        s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue),
2588
                                STYPE1_NOP, 0u);
2589
        stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked);
2590
 
2591
        /* A status control symbol was not sent. Update the status counter. */
2592
        stack->txStatusCounter++;
2593
      }
2594
      break;
2595
 
2596
    case TX_STATE_SEND_PACKET_NOT_ACCEPTED:
2597
      /******************************************************************************
2598
       * SEND_PACKET_NOT_ACCEPTED
2599
       * This state is set by the receiver to force a packet-not-accepted-symbol to be
2600
       * transmitted.
2601
       ******************************************************************************/
2602
 
2603
      /* Send a packet-not-accepted symbol to indicate an error on the link. */
2604
      s = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, stack->rxErrorCause,
2605
                              STYPE1_NOP, 0u);
2606
 
2607
      /* Proceed with normal transmission. */
2608
      stack->txState = TX_STATE_LINK_INITIALIZED;
2609
 
2610
      /* A status control symbol was not sent. Update the status counter. */
2611
      stack->txStatusCounter++;
2612
      break;
2613
 
2614
    case TX_STATE_SEND_LINK_RESPONSE:
2615
      /******************************************************************************
2616
       * SEND_LINK_RESPONSE
2617
       * This state is set by the receiver to force a link-response-symbol to be
2618
       * transmitted.
2619
       ******************************************************************************/
2620
 
2621
      DEBUG_FRAMING_RX("link-res:%u", stack->rxAckId);
2622
 
2623
      /* Check the state of the receiver. */
2624
      /* REMARK: If a link-request gives this response and a link-request also makes the receiver
2625
         enter the normal operational state, none of these states except the normal state will ever
2626
         be used... */
2627
      if((stack->rxState == RX_STATE_LINK_INITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED))
2628
      {
2629
        /* Normal state. */
2630
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_OK,
2631
                                STYPE1_NOP, 0u);
2632
      }
2633
      else if(stack->rxState == RX_STATE_INPUT_RETRY_STOPPED)
2634
      {
2635
        /* Input-retry-stopped state. */
2636
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED,
2637
                                STYPE1_NOP, 0u);
2638
      }
2639
      else if(stack->rxState == RX_STATE_INPUT_ERROR_STOPPED)
2640
      {
2641
        /* Input-error-stopped state. */
2642
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED,
2643
                                STYPE1_NOP, 0u);
2644
      }
2645
      else
2646
      {
2647
        /* Not in the defined states. */
2648
        s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR,
2649
                                STYPE1_NOP, 0u);
2650
      }
2651
 
2652
      /* Proceed with normal transmission. */
2653
      stack->txState = TX_STATE_LINK_INITIALIZED;
2654
 
2655
      /* Force a status to be transmitted the next time to comply to the input-error-stopped
2656
         state rules. */
2657
      stack->txStatusCounter = 255;
2658
      break;
2659
 
2660
    case TX_STATE_OUTPUT_RETRY_STOPPED:
2661
      /******************************************************************************
2662
       * OUTPUT_RETRY_STOPPED
2663
       * This state is entered when the link-partner has transmitted a
2664
       * packet-retry-symbol. The packet-retry-symbol is acknowledged by sending a
2665
       * restart-from-retry-symbol.
2666
       * This state follows 5.9.1.5 in part 6.
2667
       ******************************************************************************/
2668
 
2669
      /* Send a restart-from-retry symbol to acknowledge. */
2670
      s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2671
                              STYPE1_RESTART_FROM_RETRY, 0u);
2672
 
2673
      /* Restart the current frame and proceed with normal operation. */
2674
      stack->txFrameState = TX_FRAME_START;
2675
      stack->txState = TX_STATE_LINK_INITIALIZED;
2676
      stack->txCounter = 0;
2677
      DEBUG_STATE("tx:normal");
2678
 
2679
      /* Discard all packets that has not received a matching packet-accepted. */
2680
      stack->txAckIdWindow = stack->txAckId;
2681
      stack->txQueue = QueueWindowReset(stack->txQueue);
2682
 
2683
      /* A status control symbol was sent. Reset the status counter. */
2684
      stack->txStatusCounter = 0;
2685
      break;
2686
 
2687
    case TX_STATE_OUTPUT_ERROR_STOPPED:
2688
      /******************************************************************************
2689
       * OUTPUT_ERROR_STOPPED
2690
       * This state is entered when the link partner has encountered any problem
2691
       * which is indicated by sending a packet-not-accepted symbol or if a packet
2692
       * timeout has expired. The error condition is acknowledged by sending a
2693
       * link-request-symbol and then wait for a link-response reply.
2694
       * This state follows 5.13.2.7 in part 6.
2695
       ******************************************************************************/
2696
 
2697
      /* Check if a link-request-symbol has been transmitted. */
2698
      if(stack->txCounter == 0)
2699
      {
2700
        /* A link-request-symbol has not been transmitted. */
2701
 
2702
        /* Send link-request-symbol (input-status). */
2703
        s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2704
                                STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
2705
 
2706
        /* Save the time when this was transmitted. */
2707
        stack->txFrameTimeout[stack->txAckId] = stack->portTime;
2708
 
2709
        /* Remember that this symbol has been transmitted. */
2710
        stack->txCounter = 1;
2711
      }
2712
      else
2713
      {
2714
        /* A link-request-symbol has been transmitted. */
2715
 
2716
        /* Check if the link partner reply has timed out. */
2717
        if((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout)
2718
        {
2719
          /* No timeout. */
2720
 
2721
          /* A link-request-symbol has been transmitted. */
2722
          /* Send only idle-symbols until the link-response is received. */
2723
          s.type = RIO_SYMBOL_TYPE_IDLE;
2724
        }
2725
        else
2726
        {
2727
          /* Link response timeout. */
2728
 
2729
          /* Check if the link-partner has not responded for too many times. */
2730
          if(stack->txCounter < 5)
2731
          {
2732
            /* Not too many timeouts. */
2733
            /* Retry and send a new link-request. */
2734
 
2735
            /* Send link-request-symbol (input-status). */
2736
            s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue),
2737
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
2738
 
2739
            /* Save the time when this was transmitted. */
2740
            stack->txFrameTimeout[stack->txAckId] = stack->portTime;
2741
 
2742
            /* Increment the number of times we have retransmitted the link-request. */
2743
            stack->txCounter++;
2744
          }
2745
          else
2746
          {
2747
            /* The link partner has not answered for too many times. */
2748
            /* Give up and set the state to uninitialized. */
2749
            stack->txState = TX_STATE_UNINITIALIZED;
2750
            s.type = RIO_SYMBOL_TYPE_IDLE;
2751
            ASSERT0("No link-response received, giving up.");
2752
          }
2753
        }
2754
      }
2755
      break;
2756
 
2757
    case TX_STATE_UNINITIALIZED:
2758
    default:
2759
      /******************************************************************************
2760
       * Wait for the port to be initialized.
2761
       ******************************************************************************/
2762
 
2763
      /* Send only idle symbols. */
2764
      s.type = RIO_SYMBOL_TYPE_IDLE;
2765
      break;
2766
  }
2767
 
2768
  /* Return the created symbol. */
2769
  return s;
2770
}
2771
 
2772
/*******************************************************************************
2773
 * Deprecated functions
2774
 *******************************************************************************/
2775
 
2776
uint8_t RIO_packetTid( RioStack_t *stack )
2777
{
2778
  ASSERT(!QueueEmpty(stack->rxQueue) , "Reading from empty reception queue.");
2779
 
2780
  return (uint8_t) (QueueGetFrontContent(stack->rxQueue, 1ul) & 0xfful);
2781
}
2782
 
2783
 
2784
uint16_t RIO_packetDestination( RioStack_t *stack )
2785
{
2786
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2787
 
2788
  return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 0ul));
2789
}
2790
 
2791
 
2792
uint16_t RIO_packetSource( RioStack_t *stack )
2793
{
2794
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2795
 
2796
  return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 1ul) >> 16);
2797
}
2798
 
2799
 
2800
uint8_t RIO_readMaintenanceReadRequestHop( RioStack_t *stack )
2801
{
2802
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2803
 
2804
  return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
2805
}
2806
 
2807
uint32_t RIO_readMaintenanceReadRequestOffset( RioStack_t *stack )
2808
{
2809
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2810
 
2811
  return (QueueGetFrontContent(stack->rxQueue, 2ul) & 0x00fffffcul);
2812
}
2813
 
2814
uint8_t RIO_readMaintenanceReadResponseHop( RioStack_t *stack )
2815
{
2816
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2817
 
2818
  return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
2819
}
2820
 
2821
uint32_t RIO_readMaintenanceReadResponse( RioStack_t *stack )
2822
{
2823
  uint32_t readData;
2824
 
2825
 
2826
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2827
 
2828
  /* There is no way of knowing where the data is positioned. */
2829
  /* Bit-or the two words together since one of the words are zero. */
2830
  readData = QueueGetFrontContent(stack->rxQueue, 3ul);
2831
  readData |= QueueGetFrontContent(stack->rxQueue, 4ul);
2832
  return readData;
2833
}
2834
 
2835
uint8_t RIO_readMaintenanceWriteRequestHop( RioStack_t *stack )
2836
{
2837
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2838
 
2839
  return (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
2840
}
2841
 
2842
uint32_t RIO_readMaintenanceWriteRequestOffset( RioStack_t *stack )
2843
{
2844
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2845
 
2846
  return (QueueGetFrontContent(stack->rxQueue, 2ul) & 0x00fffffcul);
2847
}
2848
 
2849
uint32_t RIO_readMaintenanceWriteRequestData( RioStack_t *stack )
2850
{
2851
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2852
 
2853
  return (QueueGetFrontContent(stack->rxQueue, 3ul) | QueueGetFrontContent(stack->rxQueue, 4ul));
2854
}
2855
 
2856
uint8_t RIO_readMaintenanceWriteResponseHop( RioStack_t *stack )
2857
{
2858
  return (uint8_t) (QueueGetFrontContent(stack->rxQueue, 2ul) >> 24);
2859
}
2860
 
2861
 
2862
 
2863
void RIO_sendNwrite8( RioStack_t *stack, const uint16_t destid, const uint32_t address,
2864
                      const uint8_t data)
2865
{
2866
  sendNwrite(stack, destid, stack->baseDeviceId, 0, address, 1, &data, 0u);
2867
}
2868
 
2869
 
2870
void RIO_sendNwriteR8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address,
2871
                       const uint8_t data)
2872
{
2873
  sendNwrite(stack, destid, stack->baseDeviceId, tid, address, 1, &data, 1u);
2874
}
2875
 
2876
 
2877
uint32_t RIO_readNwriteAddress8( RioStack_t *stack )
2878
{
2879
  uint32_t address;
2880
 
2881
 
2882
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2883
 
2884
  /* Assemble the address from the wrsize field and the address itself to get a byte address. */
2885
  address = (QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0x00000003ul;
2886
  address |= QueueGetFrontContent(stack->rxQueue, 2ul) & (uint32_t)0xfffffffcul;
2887
 
2888
  return address;
2889
}
2890
 
2891
 
2892
uint8_t RIO_readNwriteSize8( RioStack_t *stack )
2893
{
2894
  uint8_t wrsize;
2895
  uint8_t n;
2896
 
2897
 
2898
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2899
 
2900
  /* Get the wrsize field from the packet and check its value. */
2901
  wrsize = (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0xful);
2902
  switch(wrsize)
2903
  {
2904
    case 0:
2905
      /* Reading one byte. */
2906
      n = 1u;
2907
      break;
2908
    case 1:
2909
      /* Reading one byte. */
2910
      n = 1u;
2911
      break;
2912
    case 2:
2913
      /* Reading one byte. */
2914
      n = 1u;
2915
      break;
2916
    case 3:
2917
      /* Reading one byte. */
2918
      n = 1u;
2919
      break;
2920
    default:
2921
      /* Unsupported. */
2922
      n = 0u;
2923
      break;
2924
  }
2925
 
2926
  return n;
2927
}
2928
 
2929
 
2930
uint8_t RIO_readNwritePayload8( RioStack_t *stack )
2931
{
2932
  uint8_t returnValue;
2933
  uint32_t readData;
2934
 
2935
 
2936
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2937
 
2938
  /* Since there is no way of knowing where the byte will be placed,
2939
     OR all bytes in the payload and return it. */
2940
  readData = QueueGetFrontContent(stack->rxQueue, 3ul);
2941
  returnValue = (uint8_t) (readData >> 24);
2942
  returnValue |= (uint8_t) (readData >> 16);
2943
  returnValue |= (uint8_t) (readData >> 8);
2944
  returnValue |= (uint8_t) (readData);
2945
  readData = QueueGetFrontContent(stack->rxQueue, 4ul);
2946
  returnValue |= (uint8_t) (readData >> 24);
2947
  returnValue |= (uint8_t) (readData >> 16);
2948
  returnValue |= (uint8_t) (readData >> 8);
2949
  returnValue |= (uint8_t) (readData);
2950
 
2951
  return returnValue;
2952
}
2953
 
2954
void RIO_sendNread8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address)
2955
{
2956
  uint32_t content;
2957
  uint16_t crc = 0xffffu;
2958
 
2959
 
2960
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
2961
 
2962
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
2963
  /* ackId is set when the packet is transmitted. */
2964
  content = ((uint32_t) 0x0012ul) << 16;
2965
  content |= (uint32_t) destid;
2966
  crc = Crc32(content, crc);
2967
  QueueSetContent(stack->txQueue, 0ul, content);
2968
 
2969
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
2970
  content = ((uint32_t) stack->baseDeviceId) << 16;
2971
  content |= ((uint32_t) 0x4ul) << 12;
2972
  content |= (address & (uint32_t)0x00000003ul) << 8;
2973
  content |= (uint32_t) tid;
2974
  crc = Crc32(content, crc);
2975
  QueueSetContent(stack->txQueue, 1ul, content);
2976
 
2977
  /* address(28:0)|wdptr|xamsbs(1:0) */
2978
  /* xamsbs cannot be used if the address is a word. */
2979
  content = address & (uint32_t)0xfffffffcul;
2980
  crc = Crc32(content, crc);
2981
  QueueSetContent(stack->txQueue, 2ul, content);
2982
 
2983
  /* crc(15:0)|pad(15:0) */
2984
  content = ((uint32_t) crc) << 16;
2985
  QueueSetContent(stack->txQueue, 3ul, content);
2986
 
2987
  /* Set the size of the packet and place it in the queue. */
2988
  QueueSetSize(stack->txQueue, 4ul);
2989
  stack->txQueue = QueueEnqueue(stack->txQueue);
2990
}
2991
 
2992
 
2993
uint32_t RIO_readNreadAddress8( RioStack_t *stack )
2994
{
2995
  uint32_t address;
2996
 
2997
 
2998
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
2999
 
3000
  /* Assemble the address from the rdsize field and the address itself to get a byte address. */
3001
  address = (QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0x00000003ul;
3002
  address |= QueueGetFrontContent(stack->rxQueue, 2ul) & (uint32_t)0xfffffffcul;
3003
 
3004
  return address;
3005
}
3006
 
3007
 
3008
uint8_t RIO_readNreadSize8( RioStack_t *stack )
3009
{
3010
  uint8_t rdsize;
3011
  uint8_t n;
3012
 
3013
 
3014
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3015
 
3016
  /* Get the rdsize field from the packet and check its value. */
3017
  rdsize = (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 8) & (uint32_t)0xful);
3018
  switch(rdsize)
3019
  {
3020
    case 0:
3021
      /* Reading one byte. */
3022
      n = 1u;
3023
      break;
3024
    case 1:
3025
      /* Reading one byte. */
3026
      n = 1u;
3027
      break;
3028
    case 2:
3029
      /* Reading one byte. */
3030
      n = 1u;
3031
      break;
3032
    case 3:
3033
      /* Reading one byte. */
3034
      n = 1u;
3035
      break;
3036
    default:
3037
      /* Unsupported. */
3038
      n = 0u;
3039
      break;
3040
  }
3041
 
3042
  return n;
3043
}
3044
 
3045
 
3046
void RIO_sendMessage8( RioStack_t *stack, const uint16_t destid, const uint8_t mailbox, const uint16_t size, const uint8_t* data)
3047
{
3048
  uint32_t content;
3049
  uint16_t crc = 0xffffu;
3050
  uint32_t packetIndex;
3051
  uint32_t dataIndex;
3052
 
3053
 
3054
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3055
  ASSERT((size <= 256), "Packet sizes over 256 are currently unsupported.");
3056
 
3057
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3058
  /* ackId is set when the packet is transmitted. */
3059
  content = ((uint32_t) 0x001bul) << 16;
3060
  content |= (uint32_t) destid;
3061
  crc = Crc32(content, crc);
3062
  QueueSetContent(stack->txQueue, 0ul, content);
3063
 
3064
  /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0|mbox(1:0)|xmbox(3:0) */
3065
  content = ((uint32_t) stack->baseDeviceId) << 16;
3066
  if(size <= 8u)
3067
  {
3068
    content |= ((uint32_t) 0x09ul) << 8;
3069
  }
3070
  else if(size <= 16u)
3071
  {
3072
    content |= ((uint32_t) 0x0aul) << 8;
3073
  }
3074
  else if(size <= 32u)
3075
  {
3076
    content |= ((uint32_t) 0x0bul) << 8;
3077
  }
3078
  else if(size <= 64u)
3079
  {
3080
    content |= ((uint32_t) 0x0cul) << 8;
3081
  }
3082
  else if(size <= 128u)
3083
  {
3084
    content |= ((uint32_t) 0x0dul) << 8;
3085
  }
3086
  else
3087
  {
3088
    content |= ((uint32_t) 0x0eul) << 8;
3089
  }
3090
  content |= ((uint32_t)mailbox & (uint32_t)0xfu) << 4;
3091
  content |= ((uint32_t)mailbox) >> 4;
3092
  crc = Crc32(content, crc);
3093
  QueueSetContent(stack->txQueue, 1ul, content);
3094
 
3095
  /* double-word0...double-wordN */
3096
  dataIndex = 0;
3097
  packetIndex = 8;
3098
  while(dataIndex < size)
3099
  {
3100
    content <<= 8;
3101
    if(packetIndex == 80)
3102
    {
3103
      content |= crc >> 8;
3104
    }
3105
    else if(packetIndex == 81)
3106
    {
3107
      content |= crc & 0xff;
3108
    }
3109
    else
3110
    {
3111
      content |= data[dataIndex++];
3112
    }
3113
 
3114
    if((packetIndex & 0x3) == 3)
3115
    {
3116
      crc = Crc32(content, crc);
3117
      QueueSetContent(stack->txQueue, packetIndex>>2, content);
3118
    }
3119
 
3120
    packetIndex++;
3121
  }
3122
 
3123
  /* Pad the data to an even double word. */
3124
  while((dataIndex & 0x7) != 0)
3125
  {
3126
    content <<= 8;
3127
    dataIndex++;
3128
 
3129
    if((packetIndex & 0x3) == 3)
3130
    {
3131
      crc = Crc32(content, crc);
3132
      QueueSetContent(stack->txQueue, packetIndex>>2, content);
3133
    }
3134
 
3135
    packetIndex++;
3136
  }
3137
 
3138
  /* Check where the CRC should be placed. */
3139
  if((packetIndex & 0x3) == 0)
3140
  {
3141
    /* crc(15:0)|pad(15:0) */
3142
    content = ((uint32_t) crc) << 16;
3143
  }
3144
  else
3145
  {
3146
    /* double-wordN-LSB|crc(15:0) */
3147
    content &= 0x0000ffff;
3148
    crc = Crc16(content, crc);
3149
    content <<= 16;
3150
    content |= crc;
3151
  }
3152
 
3153
  /* Set the crc. */
3154
  QueueSetContent(stack->txQueue, packetIndex>>2, content);
3155
 
3156
  /* Set the size of the packet and place it in the queue. */
3157
  QueueSetSize(stack->txQueue, 1+(packetIndex>>2));
3158
  stack->txQueue = QueueEnqueue(stack->txQueue);
3159
}
3160
 
3161
 
3162
uint8_t RIO_readMessageMbox( RioStack_t *stack )
3163
{
3164
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue." );
3165
 
3166
  return (uint8_t) ((QueueGetFrontContent(stack->rxQueue, 1ul) >> 4) & (uint32_t)0xful);
3167
}
3168
 
3169
 
3170
uint16_t RIO_readMessageSize8( RioStack_t *stack )
3171
{
3172
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3173
 
3174
  return (uint16_t) (4ul*(QueueGetFrontSize(stack->rxQueue) - 3ul));
3175
}
3176
 
3177
 
3178
/*lint -save -e613 */
3179
void RIO_readMessagePayload8( RioStack_t *stack, uint8_t* buffer )
3180
{
3181
  uint32_t size;
3182
  uint32_t dataIndex;
3183
  uint32_t packetIndex;
3184
  uint32_t content = 0;;
3185
 
3186
 
3187
  ASSERT((buffer != NULL), "Buffer is not allocated.");
3188
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3189
 
3190
  /* Move bytes from inbound packet queue into the user buffer. */
3191
  /* Long messages contain a CRC in byte 80-81, this is removed when the buffer
3192
     is copied. */
3193
  size = QueueGetFrontSize(stack->rxQueue);
3194
  dataIndex = 0;
3195
  packetIndex = 8;
3196
  while((packetIndex>>2) < size)
3197
  {
3198
    /* Check if a new word should be read from the inbound queue. */
3199
    if((packetIndex & 0x3) == 0)
3200
    {
3201
      /* Get a new word. */
3202
      content = QueueGetFrontContent(stack->rxQueue, packetIndex>>2);
3203
    }
3204
    else
3205
    {
3206
      /* Update the current word. Remove the MSB, it has already be moved
3207
         to the user buffer. */
3208
      content <<= 8;
3209
    }
3210
 
3211
    /* Check if the current byte is CRC. */
3212
    if((packetIndex != 80) && (packetIndex != 81))
3213
    {
3214
      /* Not CRC. */
3215
      /* Move the byte to the user buffer. */
3216
      buffer[dataIndex++] = (content >> 24);
3217
    }
3218
 
3219
    /* Increment to the next position in the packet. */
3220
    packetIndex++;
3221
  }
3222
}
3223
/*lint -restore */
3224
 
3225
uint16_t RIO_readDoorbellInfo( RioStack_t *stack )
3226
{
3227
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3228
 
3229
  return (uint16_t) (QueueGetFrontContent(stack->rxQueue, 2ul) >> 16);
3230
}
3231
 
3232
 
3233
void RIO_sendResponseDone8( RioStack_t *stack, const uint16_t destid, const uint8_t tid, const uint32_t address, const uint8_t data)
3234
{
3235
  uint32_t content;
3236
  uint16_t crc = 0xffffu;
3237
 
3238
 
3239
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3240
 
3241
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3242
  /* ackId is set when the packet is transmitted. */
3243
  content = 0x001dul << 16;
3244
  content |= (uint32_t) destid;
3245
  crc = Crc32(content, crc);
3246
  QueueSetContent(stack->txQueue, 0ul, content);
3247
 
3248
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
3249
  content = ((uint32_t) stack->baseDeviceId) << 16;
3250
  content |= (uint32_t)0x80ul << 8;
3251
  content |= (uint32_t) tid;
3252
  crc = Crc32(content, crc);
3253
  QueueSetContent(stack->txQueue, 1ul, content);
3254
 
3255
  /* double-word 0 */
3256
  switch(address & 0x7ul)
3257
  {
3258
    case 0:
3259
      /* MSB byte. */
3260
      content = ((uint32_t) data) << 24;
3261
      crc = Crc32(content, crc);
3262
      QueueSetContent(stack->txQueue, 2ul, content);
3263
      content = 0x00000000ul;
3264
      crc = Crc32(content, crc);
3265
      QueueSetContent(stack->txQueue, 3ul, content);
3266
      break;
3267
    case 1:
3268
      content = ((uint32_t) data) << 16;
3269
      crc = Crc32(content, crc);
3270
      QueueSetContent(stack->txQueue, 2ul, content);
3271
      content = 0x00000000ul;
3272
      crc = Crc32(content, crc);
3273
      QueueSetContent(stack->txQueue, 3ul, content);
3274
      break;
3275
    case 2:
3276
      content = ((uint32_t) data) << 8;
3277
      crc = Crc32(content, crc);
3278
      QueueSetContent(stack->txQueue, 2ul, content);
3279
      content = 0x00000000ul;
3280
      crc = Crc32(content, crc);
3281
      QueueSetContent(stack->txQueue, 3ul, content);
3282
      break;
3283
    case 3:
3284
      content = ((uint32_t) data);
3285
      crc = Crc32(content, crc);
3286
      QueueSetContent(stack->txQueue, 2ul, content);
3287
      content = 0x00000000ul;
3288
      crc = Crc32(content, crc);
3289
      QueueSetContent(stack->txQueue, 3ul, content);
3290
      break;
3291
    case 4:
3292
      content = 0x00000000ul;
3293
      crc = Crc32(content, crc);
3294
      QueueSetContent(stack->txQueue, 2ul, content);
3295
      content = ((uint32_t) data) << 24;
3296
      crc = Crc32(content, crc);
3297
      QueueSetContent(stack->txQueue, 3ul, content);
3298
      break;
3299
    case 5:
3300
      content = 0x00000000ul;
3301
      crc = Crc32(content, crc);
3302
      QueueSetContent(stack->txQueue, 2ul, content);
3303
      content = ((uint32_t) data) << 16;
3304
      crc = Crc32(content, crc);
3305
      QueueSetContent(stack->txQueue, 3ul, content);
3306
      break;
3307
    case 6:
3308
      content = 0x00000000ul;
3309
      crc = Crc32(content, crc);
3310
      QueueSetContent(stack->txQueue, 2ul, content);
3311
      content = ((uint32_t) data) << 8;
3312
      crc = Crc32(content, crc);
3313
      QueueSetContent(stack->txQueue, 3ul, content);
3314
      break;
3315
    default:
3316
      /* LSB byte. */
3317
      content = 0x00000000ul;
3318
      crc = Crc32(content, crc);
3319
      QueueSetContent(stack->txQueue, 2ul, content);
3320
      content = ((uint32_t) data);
3321
      crc = Crc32(content, crc);
3322
      QueueSetContent(stack->txQueue, 3ul, content);
3323
      break;
3324
  }
3325
 
3326
  /* crc(15:0)|pad(15:0) */
3327
  content = ((uint32_t) crc) << 16;
3328
  QueueSetContent(stack->txQueue, 4ul, content);
3329
 
3330
  /* Set the size of the packet and place it in the queue. */
3331
  QueueSetSize(stack->txQueue, 5ul);
3332
  stack->txQueue = QueueEnqueue(stack->txQueue);
3333
}
3334
 
3335
 
3336
uint8_t RIO_readResponseDone8( RioStack_t *stack )
3337
{
3338
  uint8_t returnValue;
3339
  uint32_t readData;
3340
 
3341
 
3342
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3343
 
3344
  /* Since there is no way of knowing where the byte will be placed,
3345
     OR all bytes in the reply and return it. */
3346
  readData = QueueGetFrontContent(stack->rxQueue, 2ul);
3347
  returnValue = (uint8_t) (readData >> 24);
3348
  returnValue |= (uint8_t) (readData >> 16);
3349
  returnValue |= (uint8_t) (readData >> 8);
3350
  returnValue |= (uint8_t) (readData);
3351
  readData = QueueGetFrontContent(stack->rxQueue, 3ul);
3352
  returnValue |= (uint8_t) (readData >> 24);
3353
  returnValue |= (uint8_t) (readData >> 16);
3354
  returnValue |= (uint8_t) (readData >> 8);
3355
  returnValue |= (uint8_t) (readData);
3356
 
3357
  return returnValue;
3358
}
3359
 
3360
 
3361
 
3362
/*******************************************************************************
3363
 * Local functions
3364
 *******************************************************************************/
3365
 
3366
 
3367
static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
3368
{
3369
  /* Update the buffer status of the link partner. */
3370
  (void) ackId;
3371
  stack->txBufferStatus = bufferStatus;
3372
}
3373
 
3374
 
3375
static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
3376
{
3377
  /* Check if an acknowledge is expected and that it is for a transmitted packet. */
3378
  if((stack->txAckId != stack->txAckIdWindow) && (ackId == stack->txAckId))
3379
  {
3380
    DEBUG_FRAMING_TX("ack=%i", ackId);
3381
    /* Acknowledge for a recently transmitted packet received. */
3382
    /* Remove the packet from the outbound queue and restart the transmission for
3383
       a new packet. */
3384
    stack->txQueue = QueueDequeue(stack->txQueue);
3385
    stack->txAckId = ACKID_INC(stack->txAckId);
3386
    stack->statusOutboundPacketComplete++;
3387
  }
3388
  else
3389
  {
3390
    DEBUG_FRAMING_TX("*ack=%i", ackId);
3391
    /* Acknowledge for an unexpected ackId or not waiting for an acknowledge. */
3392
    /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
3393
    stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
3394
    stack->txCounter = 0u;
3395
    stack->statusOutboundErrorPacketAccepted++;
3396
    DEBUG_STATE("tx:error-stopped");
3397
  }
3398
 
3399
  /* Update the buffer status of the link partner. */
3400
  stack->txBufferStatus = bufferStatus;
3401
}
3402
 
3403
 
3404
static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus)
3405
{
3406
  /* Check if the retried packet ackId is acceptable. */
3407
  if(ackId == stack->txAckId)
3408
  {
3409
    DEBUG_FRAMING_TX("retry=%u", ackId);
3410
    /* The request for retry is for the current packet. */
3411
    /* Force the transmitter to send a RESTART-FROM-RETRY symbol. */
3412
    stack->txState = TX_STATE_OUTPUT_RETRY_STOPPED;
3413
    stack->statusOutboundPacketRetry++;
3414
    DEBUG_STATE("tx:retry-stopped");
3415
  }
3416
  else
3417
  {
3418
    DEBUG_FRAMING_TX("*retry=%u %u", ackId, stack->txAckId);
3419
    /* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */
3420
    stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
3421
    stack->txCounter = 0u;
3422
    stack->statusOutboundErrorPacketRetry++;
3423
    DEBUG_STATE("tx:error-stopped");
3424
  }
3425
 
3426
  /* Update the buffer status of the link partner. */
3427
  stack->txBufferStatus = bufferStatus;
3428
}
3429
 
3430
 
3431
static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause)
3432
{
3433
  (void) arbitrary;
3434
 
3435
  /* Force the transmitter to enter output-error-stopped state. */
3436
  stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED;
3437
  stack->txCounter = 0u;
3438
 
3439
  /* Record the type of error that caused the packet to not being accepted. */
3440
  switch(cause)
3441
  {
3442
    case PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID:
3443
      stack->statusPartnerErrorPacketAckId++;
3444
      break;
3445
    case PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC:
3446
      stack->statusPartnerErrorControlCrc++;
3447
      break;
3448
    case PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC:
3449
      stack->statusPartnerErrorPacketCrc++;
3450
      break;
3451
    case PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER:
3452
      stack->statusPartnerErrorIllegalCharacter++;
3453
      break;
3454
    default:
3455
      stack->statusPartnerErrorGeneral++;
3456
      break;
3457
  }
3458
 
3459
  DEBUG_STATE("tx:error-stopped");
3460
}
3461
 
3462
 
3463
static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus)
3464
{
3465
  uint8_t window;
3466
  uint8_t windowReceived;
3467
 
3468
 
3469
  (void) portStatus;
3470
 
3471
  /* Check if this symbols is expected. */
3472
  if(stack->txState == TX_STATE_OUTPUT_ERROR_STOPPED)
3473
  {
3474
    DEBUG_FRAMING_TX("link-res:%u %u %u", stack->txAckIdWindow, stack->txAckId, ackId);
3475
 
3476
    /* Calculate the number of packets that has not received an acknowledge on our side and
3477
       on the link-partner side. */
3478
    window = (stack->txAckIdWindow - stack->txAckId) & 0x1f;
3479
    windowReceived = (ackId - stack->txAckId) & 0x1f;
3480
 
3481
    /* Check if the link-partners response is acceptable. */
3482
    if(windowReceived <= window)
3483
    {
3484
      /* A link-response is expected. */
3485
      DEBUG_STATE("tx:recover");
3486
 
3487
      /* Remove entries in the queue that the link-partner has sent acknowledges for that has been lost. */
3488
      while(stack->txAckId != ackId)
3489
      {
3490
        stack->txQueue = QueueDequeue(stack->txQueue);
3491
        stack->txAckId = ACKID_INC(stack->txAckId);
3492
        stack->statusOutboundPacketComplete++;
3493
      }
3494
 
3495
      /* Set the transmission window to the resend packets that has not been received. */
3496
      stack->txQueue = QueueWindowReset(stack->txQueue);
3497
      stack->txAckIdWindow = ackId;
3498
      stack->txFrameState = TX_FRAME_START;
3499
 
3500
      /* Set the transmitter back into normal operation. */
3501
      stack->txState = TX_STATE_LINK_INITIALIZED;
3502
    }
3503
    else
3504
    {
3505
      /* The link-partner response is unacceptable. */
3506
      /* Recovery is not possible. */
3507
      stack->txState = TX_STATE_UNINITIALIZED;
3508
      ASSERT0("Unrecoverable protocol error.");
3509
    }
3510
  }
3511
  else
3512
  {
3513
    /* Not expecting a link-response. */
3514
    /* Just discard this symbol. */
3515
    /* REMARK: Add status counter here??? */
3516
  }
3517
}
3518
 
3519
 
3520
static void handleStartOfPacket(RioStack_t *stack)
3521
{
3522
  /* Check if a packet is already started. */
3523
  if(stack->rxCounter != 0u)
3524
  {
3525
    /* Packet has already started. */
3526
    /* This indicates an implicit end-of-packet symbol and signals the previous packet as ready. */
3527
    DEBUG_FRAMING_RX("cont=%u", stack->rxAckId);
3528
 
3529
    /* Check the packet crc. */
3530
    if(stack->rxCrc == 0x0000u)
3531
    {
3532
      /* The packet has a correct CRC. */
3533
 
3534
      /* Check if the packet is long enough to contain a complete packet. */
3535
      if(stack->rxCounter > 3u)
3536
      {
3537
        /* Packet long enough to process. */
3538
 
3539
        /* Process the newly received packet and start a new one. */
3540
        handleNewPacketEnd(stack);
3541
        handleNewPacketStart(stack);
3542
      }
3543
      else
3544
      {
3545
        /* The packet has a valid CRC but is too short. */
3546
        /* Packet error. Enter input-error-stopped state. */
3547
        stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
3548
        stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
3549
        stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
3550
        stack->statusInboundErrorGeneral++;
3551
        DEBUG_STATE("rx:error-stopped");
3552
      }
3553
    }
3554
    else
3555
    {
3556
      /* The packet has an invalid CRC. */
3557
      /* Packet error. Enter input-error-stopped state. */
3558
      stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
3559
      stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
3560
      stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
3561
      stack->statusInboundErrorPacketCrc++;
3562
      DEBUG_STATE("rx:error-stopped");
3563
    }
3564
  }
3565
  else
3566
  {
3567
    /* Packet has not already started. */
3568
    DEBUG_FRAMING_RX("start=%u", stack->rxAckId);
3569
    handleNewPacketStart(stack);
3570
  }
3571
}
3572
 
3573
 
3574
static void handleEndOfPacket(RioStack_t *stack)
3575
{
3576
  DEBUG_FRAMING_RX("end=%u", stack->rxAckId);
3577
 
3578
  /* Check if the CRC is correct. */
3579
  if(stack->rxCrc == 0x0000u)
3580
  {
3581
    /* The packet has a correct CRC. */
3582
 
3583
    /* Check if the packet is long enough to contain a complete packet. */
3584
    if(stack->rxCounter > 3u)
3585
    {
3586
      /* Packet long enough to process. */
3587
 
3588
      /* Process the newly received packet. */
3589
      handleNewPacketEnd(stack);
3590
    }
3591
    else
3592
    {
3593
      /* The packet has a valid CRC but is too short. */
3594
      /* Packet error. Enter input-error-stopped state. */
3595
      stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
3596
      stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
3597
      stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL;
3598
      stack->statusInboundErrorGeneral++;
3599
      DEBUG_STATE("rx:error-stopped");
3600
    }
3601
  }
3602
  else
3603
  {
3604
    /* The packet has an invalid CRC. */
3605
    /* Packet error. Enter input-error-stopped state. */
3606
    stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED;
3607
    stack->rxState = RX_STATE_INPUT_ERROR_STOPPED;
3608
    stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
3609
    stack->statusInboundErrorPacketCrc++;
3610
    DEBUG_STATE("rx:error-stopped");
3611
  }
3612
}
3613
 
3614
 
3615
static void handleNewPacketStart(RioStack_t *stack)
3616
{
3617
  /* Check if there are buffers available to store the new frame. */
3618
  if (QueueAvailable(stack->rxQueue) > 0u)
3619
  {
3620
    /* There are buffers available to accept the new packet. */
3621
 
3622
    /* Update the reception counter to indicate the frame has started. */
3623
    stack->rxCounter = 1;
3624
  }
3625
  else
3626
  {
3627
    /* There are no buffers available. */
3628
    /* Go to input retry stopped state. */
3629
    DEBUG_FRAMING_RX("retry=%u", stack->rxAckId);
3630
    stack->statusInboundPacketRetry++;
3631
    stack->txState = TX_STATE_SEND_PACKET_RETRY;
3632
    stack->rxState = RX_STATE_INPUT_RETRY_STOPPED;
3633
    DEBUG_STATE("rx:retry-stopped");
3634
  }
3635
}
3636
 
3637
 
3638
static void handleNewPacketEnd(RioStack_t *stack)
3639
{
3640
  uint32_t *packet;
3641
  uint32_t ftype;
3642
  uint32_t transaction;
3643
 
3644
 
3645
  /* Save the size of the packet. */
3646
  QueueSetSize(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul);
3647
 
3648
  /* Get the packet and information about its type. */
3649
  packet = QueueGetBackBuffer(stack->rxQueue);
3650
  ftype = FTYPE_GET(packet);
3651
  transaction = TRANSACTION_GET(packet);
3652
 
3653
#ifdef RIO_TRANSPARENT
3654
  /* Always forward the packet to the top of the stack. */
3655
  stack->rxQueue = QueueEnqueue(stack->rxQueue);
3656
#else
3657
  /* Check if the packet should be forwarded to the top of the stack. */
3658
  if ((QueueGetBackSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE) &&
3659
      (ftype == FTYPE_MAINTENANCE) && (transaction == TRANSACTION_MAINT_READ_REQUEST))
3660
  {
3661
    /* Received maintenance read request. */
3662
    /* Send a maintenance read response. This packet is aimed at the stack, it should
3663
       not be forwarded. */
3664
    /* Note that only single word accesses are supported. */
3665
    RIO_sendMaintenanceReadResponse(stack, SRCID_GET(packet),TID_GET(packet), 0xff,
3666
                                    RIO_readConfig(stack, CONFIG_OFFSET_GET(packet)));
3667
  }
3668
  else if ((QueueGetBackSize(stack->rxQueue) == MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE) &&
3669
           (ftype == FTYPE_MAINTENANCE) && (transaction == TRANSACTION_MAINT_WRITE_REQUEST))
3670
  {
3671
    /* Received maintenance write request. */
3672
    /* Send a maintenance write response. This packet is aimed at the stack, it should
3673
       not be forwarded. */
3674
    /* Note that only single word accesses are supported. */
3675
    RIO_writeConfig(stack, CONFIG_OFFSET_GET(packet),
3676
                    DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0));
3677
    RIO_sendMaintenanceWriteResponse(stack, SRCID_GET(packet), TID_GET(packet), 0xff);
3678
  }
3679
  else
3680
  {
3681
    /* Forward this packet to the top of the stack. */
3682
    stack->rxQueue = QueueEnqueue(stack->rxQueue);
3683
  }
3684
#endif
3685
  /* Reset the reception counter. */
3686
  stack->rxCounter = 0u;
3687
 
3688
  /* Update the ackId for the receiver. */
3689
  stack->rxAckId = ACKID_INC(stack->rxAckId);
3690
 
3691
  /* Update status counter. */
3692
  stack->statusInboundPacketComplete++;
3693
}
3694
 
3695
 
3696
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd)
3697
{
3698
  /* Check the command of the link-request. */
3699
  if(cmd == LINK_REQUEST_INPUT_STATUS)
3700
  {
3701
    /* Input-status requested. */
3702
    /* Return input port status. */
3703
 
3704
    /* Force the transmitter to send a link-response-symbol. */
3705
    stack->txState = TX_STATE_SEND_LINK_RESPONSE;
3706
  }
3707
  else if(cmd == LINK_REQUEST_RESET_DEVICE)
3708
  {
3709
    /* Reset-device requested. */
3710
    /* REMARK: Support this??? */
3711
  }
3712
  else
3713
  {
3714
    /* Unrecognized command. */
3715
    /* Dont do anything. */
3716
  }
3717
 
3718
  /* Always cancel an ongoing frame when a link-request has been received. */
3719
  stack->rxCounter = 0;
3720
 
3721
  /* Receiving this indicates the link partner having encountered a potential problem. */
3722
  /* Count the number of times this happens. */
3723
  stack->statusPartnerLinkRequest++;
3724
}
3725
 
3726
 
3727
static void sendMaintenanceReadRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
3728
                                        const uint8_t hopCount, const uint32_t offset)
3729
{
3730
  uint32_t content;
3731
  uint16_t crc = 0xffffu;
3732
 
3733
 
3734
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3735
 
3736
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3737
  /* ackId is set when the packet is transmitted. */
3738
  content = 0x0018ul << 16;
3739
  content |= (uint32_t) destid;
3740
  crc = Crc32(content, crc);
3741
  QueueSetContent(stack->txQueue, 0ul, content);
3742
 
3743
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
3744
  content = ((uint32_t) srcid) << 16;
3745
  content |= (uint32_t) 0x08ul << 8;
3746
  content |= (uint32_t) tid;
3747
  crc = Crc32(content, crc);
3748
  QueueSetContent(stack->txQueue, 1ul, content);
3749
 
3750
  /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
3751
  content = ((uint32_t) hopCount) << 24;
3752
  content |= offset & (uint32_t) 0x00fffffcul;
3753
  crc = Crc32(content, crc);
3754
  QueueSetContent(stack->txQueue, 2ul, content);
3755
 
3756
  /* crc(15:0)|pad(15:0) */
3757
  content = ((uint32_t) crc) << 16;
3758
  QueueSetContent(stack->txQueue, 3ul, content);
3759
 
3760
  /* Set the size of the packet and place it in the queue. */
3761
  QueueSetSize(stack->txQueue, 4ul);
3762
  stack->txQueue = QueueEnqueue(stack->txQueue);
3763
}
3764
 
3765
static void receiveMaintenanceReadRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
3766
                                    uint8_t *hopCount, uint32_t *offset)
3767
{
3768
  uint32_t *packet;
3769
 
3770
 
3771
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3772
 
3773
  packet = QueueGetFrontBuffer(stack->rxQueue);
3774
 
3775
  *destid = DESTID_GET(packet);
3776
  *srcid = SRCID_GET(packet);
3777
  *tid = TID_GET(packet);
3778
  *hopCount = HOP_GET(packet);
3779
  *offset = CONFIG_OFFSET_GET(packet);
3780
}
3781
 
3782
static void sendMaintenanceReadResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
3783
                                         const uint8_t hopCount, const uint32_t data)
3784
{
3785
  uint32_t content;
3786
  uint16_t crc = 0xffffu;
3787
 
3788
 
3789
  /* REMARK: What should we do if there are no buffers available to send the packet... */
3790
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3791
 
3792
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3793
  /* ackId is set when the packet is transmitted. */
3794
  content = (uint32_t)0x0018ul << 16;
3795
  content |= (uint32_t) destid;
3796
  crc = Crc32(content, crc);
3797
  QueueSetContent(stack->txQueue, 0ul, content);
3798
 
3799
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
3800
  content = (uint32_t) srcid << 16;
3801
  content |= (uint32_t) 0x28ul << 8;
3802
  content |= (uint32_t) tid;
3803
  crc = Crc32(content, crc);
3804
  QueueSetContent(stack->txQueue, 1ul, content);
3805
 
3806
  /* hopcount(7:0)|reserved(23:0) */
3807
  content = (uint32_t) (hopCount << 24);
3808
  crc = Crc32(content, crc);
3809
  QueueSetContent(stack->txQueue, 2ul, content);
3810
 
3811
  /* double-word 0 */
3812
  /* Send the data in both words since this function cannot know the offset the request was sent to. */
3813
  content = data;
3814
  crc = Crc32(content, crc);
3815
  QueueSetContent(stack->txQueue, 3ul, content);
3816
  content = data;
3817
  crc = Crc32(content, crc);
3818
  QueueSetContent(stack->txQueue, 4ul, content);
3819
 
3820
  /* crc(15:0)|pad(15:0) */
3821
  content = (uint32_t)crc << 16;
3822
  QueueSetContent(stack->txQueue, 5ul, content);
3823
 
3824
  /* Set the size of the packet and place it in the queue. */
3825
  QueueSetSize(stack->txQueue, 6ul);
3826
  stack->txQueue = QueueEnqueue(stack->txQueue);
3827
}
3828
 
3829
static void receiveMaintenanceReadResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
3830
                                            uint8_t *hopCount, uint32_t *data)
3831
{
3832
  uint32_t *packet;
3833
 
3834
 
3835
  ASSERT((data != NULL), "Buffer is not allocated.");
3836
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3837
 
3838
  packet = QueueGetFrontBuffer(stack->rxQueue);
3839
 
3840
  *destid = DESTID_GET(packet);
3841
  *srcid = SRCID_GET(packet);
3842
  *tid = TID_GET(packet);
3843
  *hopCount = HOP_GET(packet);
3844
  *data = DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0);
3845
}
3846
 
3847
static void sendMaintenanceWriteRequest( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
3848
                                         const uint8_t hopCount, const uint32_t offset, const uint32_t data )
3849
{
3850
  uint32_t content;
3851
  uint16_t crc = 0xffffu;
3852
 
3853
 
3854
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3855
 
3856
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3857
  /* ackId is set when the packet is transmitted. */
3858
  content = 0x0018ul << 16;
3859
  content |= (uint32_t) destid;
3860
  crc = Crc32(content, crc);
3861
  QueueSetContent(stack->txQueue, 0ul, content);
3862
 
3863
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
3864
  content = ((uint32_t) srcid) << 16;
3865
  content |= (uint32_t)0x18ul << 8;
3866
  content |= (uint32_t) tid;
3867
  crc = Crc32(content, crc);
3868
  QueueSetContent(stack->txQueue, 1ul, content);
3869
 
3870
  /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
3871
  content = ((uint32_t) hopCount) << 24;
3872
  content |= offset & (uint32_t)0x00fffffcul;
3873
  crc = Crc32(content, crc);
3874
  QueueSetContent(stack->txQueue, 2ul, content);
3875
 
3876
  /* double-word 0 */
3877
  /* Note that both words are filled in to avoid looking at the offset. The receiver will not
3878
     look at the other part anyway. The standard does not say anything about the value of the padding. */
3879
  content = data;
3880
  crc = Crc32(content, crc);
3881
  QueueSetContent(stack->txQueue, 3ul, content);
3882
  content = data;
3883
  crc = Crc32(content, crc);
3884
  QueueSetContent(stack->txQueue, 4ul, content);
3885
 
3886
  /* crc(15:0)|pad(15:0) */
3887
  content = ((uint32_t) crc) << 16;
3888
  QueueSetContent(stack->txQueue, 5ul, content);
3889
 
3890
  /* Set the size of the packet and place it in the queue. */
3891
  QueueSetSize(stack->txQueue, 6ul);
3892
  stack->txQueue = QueueEnqueue(stack->txQueue);
3893
}
3894
 
3895
static void receiveMaintenanceWriteRequest( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
3896
                                            uint8_t *hopCount, uint32_t *offset, uint32_t *data )
3897
{
3898
  uint32_t *packet;
3899
 
3900
 
3901
  ASSERT((data != NULL), "Buffer is not allocated.");
3902
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3903
 
3904
  packet = QueueGetFrontBuffer(stack->rxQueue);
3905
 
3906
  *destid = DESTID_GET(packet);
3907
  *srcid = SRCID_GET(packet);
3908
  *tid = TID_GET(packet);
3909
  *hopCount = HOP_GET(packet);
3910
  *offset = CONFIG_OFFSET_GET(packet);
3911
  *data = DOUBLE_WORD_MSB_GET(packet, 0) | DOUBLE_WORD_LSB_GET(packet, 0);
3912
}
3913
 
3914
static void sendMaintenanceWriteResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
3915
                                          const uint8_t hopCount)
3916
{
3917
  uint32_t content;
3918
  uint16_t crc = 0xffffu;
3919
 
3920
 
3921
  /* REMARK: What should we do if there are no buffers available to send the packet... */
3922
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3923
 
3924
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3925
  /* ackId is set when the packet is transmitted. */
3926
  content = (uint32_t)0x0018ul << 16;
3927
  content |= (uint32_t) destid;
3928
  crc = Crc32(content, crc);
3929
  QueueSetContent(stack->txQueue, 0ul, content);
3930
 
3931
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
3932
  content = (uint32_t) srcid << 16;
3933
  content |= (uint32_t)0x38ul << 8;
3934
  content |= (uint32_t) tid;
3935
  crc = Crc32(content, crc);
3936
  QueueSetContent(stack->txQueue, 1ul, content);
3937
 
3938
  /* hopcount(7:0)|reserved(23:0) */
3939
  content = hopCount << 24;
3940
  crc = Crc32(content, crc);
3941
  QueueSetContent(stack->txQueue, 2ul, content);
3942
 
3943
  /* crc(15:0)|pad(15:0) */
3944
  content = (uint32_t)crc << 16;
3945
  QueueSetContent(stack->txQueue, 3ul, content);
3946
 
3947
  /* Set the size of the packet and place it in the queue. */
3948
  QueueSetSize(stack->txQueue, 4ul);
3949
  stack->txQueue = QueueEnqueue(stack->txQueue);
3950
}
3951
 
3952
static void receiveMaintenanceWriteResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
3953
                                      uint8_t *hopCount)
3954
{
3955
  uint32_t *packet;
3956
 
3957
 
3958
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
3959
 
3960
  packet = QueueGetFrontBuffer(stack->rxQueue);
3961
 
3962
  *destid = DESTID_GET(packet);
3963
  *srcid = SRCID_GET(packet);
3964
  *tid = TID_GET(packet);
3965
  *hopCount = HOP_GET(packet);
3966
}
3967
 
3968
/* REMARK: Use a packet pointer instead of using the QueueSetContent... */
3969
static void sendNwrite( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
3970
                        const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer,
3971
                        const uint8_t ack)
3972
{
3973
  uint32_t content;
3974
  uint32_t size;
3975
  uint16_t wrsize = wrsizeGet(address, bufferSize);
3976
 
3977
 
3978
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
3979
  ASSERT((wrsize != 0xffff), "Write access unsupported by protocol.");
3980
 
3981
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
3982
  /* ackId is set when the packet is transmitted. */
3983
  content = ((uint32_t)0x0015ul) << 16;
3984
  content |= (uint32_t)destid;
3985
  QueueSetContent(stack->txQueue, 0ul, content);
3986
 
3987
  /* sourceId(15:0)|transaction(3:0)|wrsize(3:0)|srcTID(7:0) */
3988
  content = ((uint32_t) srcid) << 16;
3989
  if(ack == 0u)
3990
  {
3991
    /* Send NWRITE. */
3992
    content |= (uint32_t) TRANSACTION_WRITE_NWRITE << 12;
3993
  }
3994
  else
3995
  {
3996
    /* Send NWRITE_R. */
3997
    content |= (uint32_t) TRANSACTION_WRITE_NWRITER << 12;
3998
  }
3999
  content |= (uint32_t) (wrsize & 0x0f00);
4000
  content |= (uint32_t) tid;
4001
  QueueSetContent(stack->txQueue, 1ul, content);
4002
 
4003
  /* address(28:0)|wdptr|xamsbs(1:0) */
4004
  /* wrsize also contains wdptr in the lower nibble. */
4005
  /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
4006
     34-bit address should be used, another mechanism to set it should be used. */
4007
  content = (address & 0xfffffff8ul);
4008
  content |= ((uint32_t) (wrsize & 0x000f)) << 2;
4009
  QueueSetContent(stack->txQueue, 2ul, content);
4010
 
4011
  /* Place data buffer into the payload of the packet. */
4012
  size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 12, address & 0x7, bufferSize, buffer);
4013
 
4014
  /* Set the size of the packet and place it in the queue. */
4015
  QueueSetSize(stack->txQueue, size+1);
4016
  stack->txQueue = QueueEnqueue(stack->txQueue);
4017
}
4018
 
4019
static uint16_t receiveNwrite( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
4020
                               uint32_t *address, const uint16_t dataLength, uint8_t *data )
4021
{
4022
  uint32_t *packet;
4023
  uint8_t offset;
4024
  uint16_t size;
4025
  uint8_t wrsize;
4026
  uint8_t wdptr;
4027
 
4028
 
4029
  ASSERT((data != NULL), "Buffer is not allocated.");
4030
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4031
 
4032
  packet = QueueGetFrontBuffer(stack->rxQueue);
4033
 
4034
  wrsize = WRSIZE_GET(packet);
4035
  wdptr = WDPTR_GET(packet);
4036
  wrsizeToOffset(wrsize, wdptr, &offset, &size);
4037
 
4038
  *destid = DESTID_GET(packet);
4039
  *srcid = SRCID_GET(packet);
4040
  *tid = TID_GET(packet);
4041
  *address = ADDRESS_GET(packet) | offset;
4042
 
4043
  if(size > 16)
4044
  {
4045
    /* Remove header and crc from the size count. */
4046
    size = ((QueueGetFrontSize(stack->rxQueue)-4) * 4);
4047
  }
4048
 
4049
  /* Check if there is enough room in the receiving buffer. */
4050
  if(size <= dataLength)
4051
  {
4052
    return getPacketPayload(packet, 12, offset, size, data);
4053
  }
4054
  else
4055
  {
4056
    return 0;
4057
  }
4058
}
4059
 
4060
static void sendNread( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
4061
                       const uint32_t address, const uint16_t dataLength)
4062
{
4063
  uint32_t content;
4064
  uint16_t crc = 0xffffu;
4065
  uint16_t rdsize = rdsizeGet(address, dataLength);
4066
 
4067
 
4068
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
4069
  ASSERT((rdsize != 0xffff), "Read access unsupported by protocol.");
4070
 
4071
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
4072
  /* ackId is set when the packet is transmitted. */
4073
  content = ((uint32_t) 0x0012ul) << 16;
4074
  content |= (uint32_t) destid;
4075
  crc = Crc32(content, crc);
4076
  QueueSetContent(stack->txQueue, 0ul, content);
4077
 
4078
  /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
4079
  content = ((uint32_t) srcid) << 16;
4080
  content |= ((uint32_t) TRANSACTION_REQUEST_NREAD) << 12;
4081
  content |= (uint32_t) (rdsize & 0x0f00);
4082
  content |= (uint32_t) tid;
4083
  crc = Crc32(content, crc);
4084
  QueueSetContent(stack->txQueue, 1ul, content);
4085
 
4086
  /* address(28:0)|wdptr|xamsbs(1:0) */
4087
  /* rdsize also contains wdptr in the lower nibble. */
4088
  /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
4089
     34-bit address should be used, another mechanism to set it should be used. */
4090
  content = address & 0xfffffff8ul;
4091
  content |= ((uint32_t) (rdsize & 0x000f)) << 2;
4092
  crc = Crc32(content, crc);
4093
  QueueSetContent(stack->txQueue, 2ul, content);
4094
 
4095
  /* crc(15:0)|pad(15:0) */
4096
  content = ((uint32_t) crc) << 16;
4097
  QueueSetContent(stack->txQueue, 3ul, content);
4098
 
4099
  /* Set the size of the packet and place it in the queue. */
4100
  QueueSetSize(stack->txQueue, 4ul);
4101
  stack->txQueue = QueueEnqueue(stack->txQueue);
4102
}
4103
 
4104
static void receiveNread( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
4105
                          uint32_t *address, uint16_t *dataLength)
4106
{
4107
  uint32_t *packet;
4108
  uint8_t offset;
4109
  uint16_t size;
4110
  uint8_t rdsize;
4111
  uint8_t wdptr;
4112
 
4113
 
4114
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4115
 
4116
  packet = QueueGetFrontBuffer(stack->rxQueue);
4117
 
4118
  rdsize = WRSIZE_GET(packet);
4119
  wdptr = WDPTR_GET(packet);
4120
  rdsizeToOffset(rdsize, wdptr, &offset, &size);
4121
 
4122
  *destid = DESTID_GET(packet);
4123
  *srcid = SRCID_GET(packet);
4124
  *tid = TID_GET(packet);
4125
  *address = ADDRESS_GET(packet) | offset;
4126
  *dataLength = size;
4127
}
4128
 
4129
static void sendResponseDonePayload( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
4130
                                     const uint32_t address, const uint16_t bufferSize, const uint8_t *buffer)
4131
{
4132
  uint32_t content;
4133
  uint32_t size;
4134
 
4135
 
4136
  ASSERT((buffer != NULL), "Buffer is not allocated.");
4137
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
4138
 
4139
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
4140
  /* ackId is set when the packet is transmitted. */
4141
  content = 0x001dul << 16;
4142
  content |= (uint32_t) destid;
4143
  QueueSetContent(stack->txQueue, 0ul, content);
4144
 
4145
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
4146
  content = ((uint32_t) srcid) << 16;
4147
  content |= ((uint32_t) TRANSACTION_RESPONSE_WITH_PAYLOAD) << 12;
4148
  content |= (uint32_t) tid;
4149
  QueueSetContent(stack->txQueue, 1ul, content);
4150
 
4151
  /* Place data buffer into the payload of the packet. */
4152
  size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 8, address & 0x7, bufferSize, buffer);
4153
 
4154
  /* Set the size of the packet and place it in the queue. */
4155
  QueueSetSize(stack->txQueue, size+1);
4156
  stack->txQueue = QueueEnqueue(stack->txQueue);
4157
}
4158
 
4159
 
4160
static uint16_t receiveResponseDonePayload( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
4161
                                            const uint32_t address, const uint16_t dataLength, uint8_t *data )
4162
{
4163
  uint32_t *packet;
4164
 
4165
 
4166
  ASSERT((data != NULL), "Buffer is not allocated.");
4167
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4168
 
4169
  packet = QueueGetFrontBuffer(stack->rxQueue);
4170
 
4171
  *destid = DESTID_GET(packet);
4172
  *srcid = SRCID_GET(packet);
4173
  *tid = TID_GET(packet);
4174
 
4175
  return getPacketPayload(packet, 8, address & 0x7, dataLength, data);
4176
}
4177
 
4178
 
4179
static void sendResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
4180
                          const uint8_t status)
4181
{
4182
  uint32_t content;
4183
  uint16_t crc = 0xffffu;
4184
 
4185
 
4186
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
4187
 
4188
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
4189
  /* ackId is set when the packet is transmitted. */
4190
  content = (uint32_t)0x001dul << 16;
4191
  content |= destid;
4192
  crc = Crc32(content, crc);
4193
  QueueSetContent(stack->txQueue, 0ul, content);
4194
 
4195
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
4196
  content = (uint32_t)srcid << 16;
4197
  content |= ((uint32_t)status & (uint32_t)0x0ful) << 8;
4198
  content |= tid;
4199
  crc = Crc32(content, crc);
4200
  QueueSetContent(stack->txQueue, 1ul, content);
4201
 
4202
  /* crc(15:0)|pad(15:0) */
4203
  content = (uint32_t)crc << 16;
4204
  QueueSetContent(stack->txQueue, 2ul, content);
4205
 
4206
  /* Set the size of the packet and place it in the queue. */
4207
  QueueSetSize(stack->txQueue, 3ul);
4208
  stack->txQueue = QueueEnqueue(stack->txQueue);
4209
}
4210
 
4211
 
4212
static void receiveResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid)
4213
{
4214
  uint32_t *packet;
4215
 
4216
 
4217
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4218
 
4219
  packet = QueueGetFrontBuffer(stack->rxQueue);
4220
 
4221
  *destid = DESTID_GET(packet);
4222
  *srcid = SRCID_GET(packet);
4223
  *tid = TID_GET(packet);
4224
}
4225
 
4226
 
4227
static void sendDoorbell( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t tid,
4228
                          const uint16_t info )
4229
{
4230
  uint32_t content;
4231
  uint16_t crc;
4232
 
4233
 
4234
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
4235
 
4236
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
4237
  /* ackId is set when the packet is transmitted. */
4238
  content = 0x001aul << 16;
4239
  content |= (uint32_t) destid;
4240
  crc = Crc32(content, 0xffffu);
4241
  QueueSetContent(stack->txQueue, 0ul, content);
4242
 
4243
  /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
4244
  content = ((uint32_t) srcid) << 16;
4245
  content |= (uint32_t) tid;
4246
  crc = Crc32(content, crc);
4247
  QueueSetContent(stack->txQueue, 1ul, content);
4248
 
4249
  /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
4250
  content = ((uint32_t) info) << 16;
4251
  crc = Crc16(info, crc);
4252
  content |= crc;
4253
  QueueSetContent(stack->txQueue, 2ul, content);
4254
 
4255
  /* Set the size of the packet and place it in the queue. */
4256
  QueueSetSize(stack->txQueue, 3ul);
4257
  stack->txQueue = QueueEnqueue(stack->txQueue);
4258
}
4259
 
4260
 
4261
static void receiveDoorbell( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *tid,
4262
                             uint16_t *info)
4263
{
4264
  uint32_t *packet;
4265
 
4266
 
4267
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4268
 
4269
  packet = QueueGetFrontBuffer(stack->rxQueue);
4270
 
4271
  *destid = DESTID_GET(packet);
4272
  *srcid = SRCID_GET(packet);
4273
  *tid = TID_GET(packet);
4274
  *info = INFO_GET(packet);
4275
}
4276
 
4277
 
4278
static void sendMessage( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
4279
                         const uint16_t bufferSize, const uint8_t* bufferData)
4280
{
4281
  uint32_t content;
4282
  uint32_t size;
4283
 
4284
 
4285
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
4286
  ASSERT((bufferSize <= 256), "Packet sizes larger than 256 are currently unsupported.");
4287
 
4288
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
4289
  /* ackId is set when the packet is transmitted. */
4290
  content = ((uint32_t) 0x001bul) << 16;
4291
  content |= (uint32_t) destid;
4292
  QueueSetContent(stack->txQueue, 0ul, content);
4293
 
4294
  /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0|mbox(1:0)|xmbox(3:0) */
4295
  content = ((uint32_t) srcid) << 16;
4296
  if(bufferSize <= 8u)
4297
  {
4298
    content |= ((uint32_t) 0x09ul) << 8;
4299
  }
4300
  else if(bufferSize <= 16u)
4301
  {
4302
    content |= ((uint32_t) 0x0aul) << 8;
4303
  }
4304
  else if(bufferSize <= 32u)
4305
  {
4306
    content |= ((uint32_t) 0x0bul) << 8;
4307
  }
4308
  else if(bufferSize <= 64u)
4309
  {
4310
    content |= ((uint32_t) 0x0cul) << 8;
4311
  }
4312
  else if(bufferSize <= 128u)
4313
  {
4314
    content |= ((uint32_t) 0x0dul) << 8;
4315
  }
4316
  else
4317
  {
4318
    content |= ((uint32_t) 0x0eul) << 8;
4319
  }
4320
  content |= ((uint32_t)mailbox & (uint32_t)0xfu) << 4;
4321
  content |= ((uint32_t)mailbox) >> 4;
4322
  QueueSetContent(stack->txQueue, 1ul, content);
4323
 
4324
  /* Place data buffer into the payload of the packet. */
4325
  size = setPacketPayload(QueueGetBackBuffer(stack->txQueue), 8, 0, bufferSize, bufferData);
4326
 
4327
  /* Set the size of the packet and place it in the queue. */
4328
  QueueSetSize(stack->txQueue, size+1);
4329
  stack->txQueue = QueueEnqueue(stack->txQueue);
4330
}
4331
 
4332
static uint16_t receiveMessage( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox,
4333
                                const uint16_t dataLength, uint8_t *data )
4334
{
4335
  uint32_t *packet;
4336
  uint32_t size;
4337
 
4338
 
4339
  ASSERT((data != NULL), "Buffer is not allocated.");
4340
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4341
 
4342
  /* Get a pointer to the packet. */
4343
  packet = QueueGetFrontBuffer(stack->rxQueue);
4344
 
4345
  /* The higher mailbox numbers are used with messages that cannot be multi-packets. */
4346
  *destid = DESTID_GET(packet);
4347
  *srcid = SRCID_GET(packet);
4348
  *mailbox = XMBOX_GET(packet);
4349
  *mailbox <<= 2;
4350
  *mailbox |= LETTER_GET(packet);
4351
  *mailbox <<= 2;
4352
  *mailbox |= MBOX_GET(packet);
4353
 
4354
  /* Calculate the number of bytes to transfer. */
4355
  /* Remove the header and crc from the size count. */
4356
  size = (QueueGetFrontSize(stack->rxQueue)-3) * 4;
4357
 
4358
  /* Check if there is enough room in the receiving buffer. */
4359
  if(size <= dataLength)
4360
  {
4361
    return getPacketPayload(packet, 8, 0, size, data);
4362
  }
4363
  else
4364
  {
4365
    return 0;
4366
  }
4367
 
4368
}
4369
 
4370
static void sendMessageResponse( RioStack_t *stack, const uint16_t destid, const uint16_t srcid, const uint8_t mailbox,
4371
                                 const uint8_t status)
4372
{
4373
  uint32_t content;
4374
  uint16_t crc = 0xffffu;
4375
 
4376
 
4377
  ASSERT((QueueAvailable(stack->txQueue) > 0u), "Transmission queue packet overflow.");
4378
 
4379
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
4380
  /* ackId is set when the packet is transmitted. */
4381
  content = (uint32_t)0x001dul << 16;
4382
  content |= destid;
4383
  crc = Crc32(content, crc);
4384
  QueueSetContent(stack->txQueue, 0ul, content);
4385
 
4386
  /* sourceId(15:0)|transaction(3:0)|status(3:0)|letter(1:0|mbox(1:0)|msgseg(3:0) */
4387
  content = (uint32_t)srcid << 16;
4388
  content |= (uint32_t)0x1ul << 12;
4389
  content |= ((uint32_t)status & (uint32_t)0xful) << 8;
4390
  content |= ((uint32_t)mailbox & (uint32_t)0xful) << 4;
4391
  content |= ((uint32_t)mailbox) >> 4;
4392
  crc = Crc32(content, crc);
4393
  QueueSetContent(stack->txQueue, 1ul, content);
4394
 
4395
  /* crc(15:0)|pad(15:0) */
4396
  content = (uint32_t)crc << 16;
4397
  QueueSetContent(stack->txQueue, 2ul, content);
4398
 
4399
  /* Set the size of the packet and place it in the queue. */
4400
  QueueSetSize(stack->txQueue, 3ul);
4401
  stack->txQueue = QueueEnqueue(stack->txQueue);
4402
}
4403
 
4404
static void receiveMessageResponse( RioStack_t *stack, uint16_t *destid, uint16_t *srcid, uint8_t *mailbox)
4405
{
4406
  uint32_t *packet;
4407
 
4408
 
4409
  ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue.");
4410
 
4411
  packet = QueueGetFrontBuffer(stack->rxQueue);
4412
 
4413
  *destid = DESTID_GET(packet);
4414
  *srcid = SRCID_GET(packet);
4415
  *mailbox = XMBOX_GET(packet);
4416
  *mailbox <<= 2;
4417
  *mailbox |= LETTER_GET(packet);
4418
  *mailbox <<= 2;
4419
  *mailbox |= MBOX_GET(packet);
4420
}
4421
 
4422
 
4423
static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
4424
                                 const uint16_t dataSize, uint8_t *data)
4425
{
4426
  uint32_t content = 0;
4427
  uint16_t packetIndex;
4428
  uint16_t payloadIndex;
4429
  uint16_t dataIndex;
4430
 
4431
 
4432
  /* Move bytes from inbound packet queue into the user buffer. */
4433
  /* Long packets contain a CRC in byte 80-81, this is removed when the buffer
4434
     is copied. */
4435
  packetIndex = payloadOffset;
4436
  payloadIndex = 0;
4437
  dataIndex = 0;
4438
  while(dataIndex < dataSize)
4439
  {
4440
    /* Check if a new word should be read from the inbound queue. */
4441
    if((packetIndex & 0x3) == 0)
4442
    {
4443
      /* Get a new word. */
4444
      content = packet[packetIndex>>2];
4445
    }
4446
    else
4447
    {
4448
      /* Update the current word. Remove the MSB, it has already be moved
4449
         to the user buffer. */
4450
      content <<= 8;
4451
    }
4452
 
4453
    /* Check if the current byte is CRC. */
4454
    if((packetIndex != 80) && (packetIndex != 81) && (payloadIndex >= dataOffset))
4455
    {
4456
      /* Not CRC. */
4457
      /* Move the byte to the user buffer. */
4458
      data[dataIndex++] = (content >> 24);
4459
    }
4460
 
4461
    /* Increment to the next position in the packet. */
4462
    packetIndex++;
4463
    payloadIndex++;
4464
  }
4465
 
4466
  return dataIndex;
4467
}
4468
 
4469
 
4470
static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
4471
                                 const uint16_t dataSize, const uint8_t *data)
4472
{
4473
  uint16_t crc = 0xffffu;
4474
  uint32_t content = 0;
4475
  uint16_t packetIndex;
4476
  uint16_t payloadIndex;
4477
  uint16_t dataIndex;
4478
 
4479
 
4480
  /***************************************************
4481
   * Calculate the CRC for the packet header.
4482
   ***************************************************/
4483
  for(packetIndex = 0; packetIndex < payloadOffset; packetIndex+=4)
4484
  {
4485
    crc = Crc32(packet[packetIndex>>2], crc);
4486
  }
4487
 
4488
  /***************************************************
4489
   * Pad the data before the actual data is written.
4490
   ***************************************************/
4491
  payloadIndex = 0;
4492
  while(payloadIndex < dataOffset)
4493
  {
4494
    content <<= 8;
4495
 
4496
    if((packetIndex & 0x3) == 3)
4497
    {
4498
      crc = Crc32(content, crc);
4499
      packet[packetIndex>>2] = content;
4500
    }
4501
 
4502
    payloadIndex++;
4503
    packetIndex++;
4504
  }
4505
 
4506
  /***************************************************
4507
   * Write content and any embedded CRC.
4508
   ***************************************************/
4509
  dataIndex = 0;
4510
  while(dataIndex < dataSize)
4511
  {
4512
    content <<= 8;
4513
 
4514
    /* Check if CRC or content should be entered into the packet. */
4515
    if(packetIndex == 80)
4516
    {
4517
      /* CRC MSB. */
4518
      content |= crc >> 8;
4519
    }
4520
    else if(packetIndex == 81)
4521
    {
4522
      /* CRC LSB. */
4523
      content |= crc & 0xff;
4524
    }
4525
    else
4526
    {
4527
      /* Data content. */
4528
      content |= data[dataIndex++];
4529
      payloadIndex++;
4530
    }
4531
 
4532
    if((packetIndex & 0x3) == 3)
4533
    {
4534
      crc = Crc32(content, crc);
4535
      packet[packetIndex>>2] = content;
4536
    }
4537
 
4538
    packetIndex++;
4539
  }
4540
 
4541
  /***************************************************
4542
   * Pad the data to an even double word.
4543
   ***************************************************/
4544
  while((payloadIndex & 0x7) != 0)
4545
  {
4546
    content <<= 8;
4547
 
4548
    if((packetIndex & 0x3) == 3)
4549
    {
4550
      crc = Crc32(content, crc);
4551
      packet[packetIndex>>2] = content;
4552
    }
4553
 
4554
    packetIndex++;
4555
    payloadIndex++;
4556
  }
4557
 
4558
  /***************************************************
4559
   * Write the CRC into the packet.
4560
   ***************************************************/
4561
  if((packetIndex & 0x3) == 0)
4562
  {
4563
    /* crc(15:0)|pad(15:0) */
4564
    content = ((uint32_t) crc) << 16;
4565
  }
4566
  else
4567
  {
4568
    /* double-wordN-LSB|crc(15:0) */
4569
    content &= 0x0000ffff;
4570
    crc = Crc16(content, crc);
4571
    content <<= 16;
4572
    content |= crc;
4573
  }
4574
  packet[packetIndex>>2] = content;
4575
 
4576
  return (packetIndex>>2);
4577
}
4578
 
4579
 
4580
/* \note See the RapidIO standard part1 table 4-4 for details about
4581
 * {address, size}->{wdptr, wrsize} mapping.
4582
 */
4583
static uint16_t rdsizeGet(const uint32_t address, const uint16_t size)
4584
{
4585
  uint8_t wdptr;
4586
  uint8_t rdsize;
4587
 
4588
 
4589
  switch(size/8)
4590
  {
4591
    case 0:
4592
      /**************************************************************
4593
       * Sub double-word access.
4594
       **************************************************************/
4595
      /* REMARK: The same code as in wrsizeGet for sub
4596
         double-word... use it instead??? */
4597
      switch(size%8)
4598
      {
4599
        case 0:
4600
          /* Not supported by protocol. */
4601
          wdptr = 0xff;
4602
          rdsize = 0xff;
4603
          break;
4604
        case 1:
4605
          /* Reading one byte. */
4606
          /* Any address is allowed. */
4607
          wdptr = (address >> 2) & 0x1;
4608
          rdsize = address & 0x3;
4609
          break;
4610
        case 2:
4611
          /* Reading two bytes. */
4612
          /* Address 0, 2, 4, 6 are valid. */
4613
          if((address & 0x1) == 0)
4614
          {
4615
            wdptr = (address >> 2) & 0x1;
4616
            rdsize = (address & 0x7) | 0x4;
4617
          }
4618
          else
4619
          {
4620
            /* Not supported by protocol. */
4621
            wdptr = 0xff;
4622
            rdsize = 0xff;
4623
          }
4624
          break;
4625
        case 3:
4626
          /* Reading 3 bytes. */
4627
          /* Address 0 and 5 are valid. */
4628
          if(((address & 0x7) == 0) ||
4629
             ((address & 0x7) == 5))
4630
          {
4631
            wdptr = (address >> 2) & 0x1;
4632
            rdsize = 0x5ul;
4633
          }
4634
          else
4635
          {
4636
            /* Not supported by protocol. */
4637
            wdptr = 0xff;
4638
            rdsize = 0xff;
4639
          }
4640
          break;
4641
        case 4:
4642
          /* Reading 4 bytes. */
4643
          /* Address 0 and 4 are valid. */
4644
          if(((address & 0x7) == 0) ||
4645
             ((address & 0x7) == 4))
4646
          {
4647
            wdptr = (address >> 2) & 0x1;
4648
            rdsize = 0x8ul;
4649
          }
4650
          else
4651
          {
4652
            /* Not supported by protocol. */
4653
            wdptr = 0xff;
4654
            rdsize = 0xff;
4655
          }
4656
          break;
4657
        case 5:
4658
          /* Reading 5 bytes. */
4659
          /* Address 0 and 3 are valid. */
4660
          if(((address & 0x7) == 0) ||
4661
             ((address & 0x7) == 3))
4662
          {
4663
            wdptr = (address >> 1) & 0x1;
4664
            rdsize = 0x7ul;
4665
          }
4666
          else
4667
          {
4668
            /* Not supported by protocol. */
4669
            wdptr = 0xff;
4670
            rdsize = 0xff;
4671
          }
4672
          break;
4673
        case 6:
4674
          /* Reading 6 bytes. */
4675
          /* Addresses 0 and 2 are valid. */
4676
          if(((address & 0x7) == 0) ||
4677
             ((address & 0x7) == 2))
4678
          {
4679
            wdptr = (address >> 1) & 0x1;
4680
            rdsize = 0x9ul;
4681
          }
4682
          else
4683
          {
4684
            /* Not supported by protocol. */
4685
            wdptr = 0xff;
4686
            rdsize = 0xff;
4687
          }
4688
          break;
4689
        default:
4690
          /* Reading 7 bytes. */
4691
          /* Addresses 0 and 1 are valid. */
4692
          if(((address & 0x7) == 0) ||
4693
             ((address & 0x7) == 1))
4694
          {
4695
            wdptr = address & 0x1;
4696
            rdsize = 0xaul;
4697
          }
4698
          else
4699
          {
4700
            /* Not supported by protocol. */
4701
            wdptr = 0xff;
4702
            rdsize = 0xff;
4703
          }
4704
          break;
4705
      }
4706
      break;
4707
    case 1:
4708
      /* Reading 8 bytes. */
4709
      /* Only even double-word address are valid. */
4710
      if((address % 8) == 0)
4711
      {
4712
        wdptr = 0;
4713
        rdsize = 0xbul;
4714
      }
4715
      else
4716
      {
4717
        /* Not supported by protocol. */
4718
        wdptr = 0xff;
4719
        rdsize = 0xff;
4720
      }
4721
      break;
4722
    case 2:
4723
      /* Reading 16 bytes max. */
4724
      /* Only even double-word address are valid. */
4725
      if((address % 8) == 0)
4726
      {
4727
        wdptr = 1;
4728
        rdsize = 0xbul;
4729
      }
4730
      else
4731
      {
4732
        /* Not supported by protocol. */
4733
        wdptr = 0xff;
4734
        rdsize = 0xff;
4735
      }
4736
      break;
4737
    case 3:
4738
      /* Not supported by protocol. */
4739
      wdptr = 0xff;
4740
      rdsize = 0xff;
4741
      break;
4742
    case 4:
4743
      /* Reading 32 bytes max. */
4744
      /* Only even double-word address are valid. */
4745
      if((address & 0x7) == 0)
4746
      {
4747
        wdptr = 0;
4748
        rdsize = 0xcul;
4749
      }
4750
      else
4751
      {
4752
        /* Not supported by protocol. */
4753
        wdptr = 0xff;
4754
        rdsize = 0xff;
4755
      }
4756
      break;
4757
    case 5:
4758
    case 6:
4759
    case 7:
4760
      /* Not supported by protocol. */
4761
      wdptr = 0xff;
4762
      rdsize = 0xff;
4763
      break;
4764
    case 8:
4765
      /* Reading 64 bytes max. */
4766
      /* Only even double-word address are valid. */
4767
      if((address & 0x7) == 0)
4768
      {
4769
        wdptr = 1;
4770
        rdsize = 0xcul;
4771
      }
4772
      else
4773
      {
4774
        /* Not supported by protocol. */
4775
        wdptr = 0xff;
4776
        rdsize = 0xff;
4777
      }
4778
      break;
4779
    case 9:
4780
    case 10:
4781
    case 11:
4782
      /* Not supported by protocol. */
4783
      wdptr = 0xff;
4784
      rdsize = 0xff;
4785
      break;
4786
    case 12:
4787
      /* Reading 96 bytes. */
4788
      /* Only even double-word address are valid. */
4789
      if((address & 0x7) == 0)
4790
      {
4791
        wdptr = 0;
4792
        rdsize = 0xdul;
4793
      }
4794
      else
4795
      {
4796
        /* Not supported by protocol. */
4797
        wdptr = 0xff;
4798
        rdsize = 0xff;
4799
      }
4800
      break;
4801
    case 13:
4802
    case 14:
4803
    case 15:
4804
      /* Not supported by protocol. */
4805
      wdptr = 0xff;
4806
      rdsize = 0xff;
4807
      break;
4808
    case 16:
4809
      /* Reading 128 bytes max. */
4810
      /* Only even double-word address are valid. */
4811
      if((address & 0x7) == 0)
4812
      {
4813
        wdptr = 1;
4814
        rdsize = 0xdul;
4815
      }
4816
      else
4817
      {
4818
        /* Not supported by protocol. */
4819
        wdptr = 0xff;
4820
        rdsize = 0xff;
4821
      }
4822
      break;
4823
    case 17:
4824
    case 18:
4825
    case 19:
4826
      /* Not supported by protocol. */
4827
      wdptr = 0xff;
4828
      rdsize = 0xff;
4829
      break;
4830
    case 20:
4831
      /* Reading 160 bytes. */
4832
      /* Only even double-word address are valid. */
4833
      if((address & 0x7) == 0)
4834
      {
4835
        wdptr = 0;
4836
        rdsize = 0xeul;
4837
      }
4838
      else
4839
      {
4840
        /* Not supported by protocol. */
4841
        wdptr = 0xff;
4842
        rdsize = 0xff;
4843
      }
4844
      break;
4845
    case 21:
4846
    case 22:
4847
    case 23:
4848
      /* Not supported by protocol. */
4849
      wdptr = 0xff;
4850
      rdsize = 0xff;
4851
      break;
4852
    case 24:
4853
      /* Reading 192 bytes. */
4854
      /* Only even double-word address are valid. */
4855
      if((address & 0x7) == 0)
4856
      {
4857
        wdptr = 1;
4858
        rdsize = 0xeul;
4859
      }
4860
      else
4861
      {
4862
        /* Not supported by protocol. */
4863
        wdptr = 0xff;
4864
        rdsize = 0xff;
4865
      }
4866
      break;
4867
    case 25:
4868
    case 26:
4869
    case 27:
4870
      /* Not supported by protocol. */
4871
      wdptr = 0xff;
4872
      rdsize = 0xff;
4873
      break;
4874
    case 28:
4875
      /* Reading 224 bytes. */
4876
      /* Only even double-word address are valid. */
4877
      if((address & 0x7) == 0)
4878
      {
4879
        wdptr = 0;
4880
        rdsize = 0xful;
4881
      }
4882
      else
4883
      {
4884
        /* Not supported by protocol. */
4885
        wdptr = 0xff;
4886
        rdsize = 0xff;
4887
      }
4888
      break;
4889
    case 29:
4890
    case 30:
4891
    case 31:
4892
      /* Not supported by protocol. */
4893
      wdptr = 0xff;
4894
      rdsize = 0xff;
4895
      break;
4896
    case 32:
4897
      /* Reading 256 bytes max. */
4898
      /* Only even double-word address are valid. */
4899
      if((address & 0x7) == 0)
4900
      {
4901
        wdptr = 1;
4902
        rdsize = 0xful;
4903
      }
4904
      else
4905
      {
4906
        /* Not supported by protocol. */
4907
        wdptr = 0xff;
4908
        rdsize = 0xff;
4909
      }
4910
      break;
4911
    default:
4912
      /* Not supported by protocol. */
4913
      wdptr = 0xff;
4914
      rdsize = 0xff;
4915
      break;
4916
  }
4917
 
4918
  return ((((uint16_t) rdsize) << 8) | ((uint16_t) wdptr));
4919
}
4920
 
4921
 
4922
void rdsizeToOffset(uint8_t rdsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
4923
{
4924
  switch(rdsize)
4925
  {
4926
    case 0:
4927
    case 1:
4928
    case 2:
4929
    case 3:
4930
      *offset = wdptr << 2;
4931
      *offset |= rdsize;
4932
      *size = 1;
4933
      break;
4934
    case 4:
4935
    case 6:
4936
      *offset = wdptr << 2;
4937
      *offset |= rdsize & 0x02;
4938
      *size = 2;
4939
      break;
4940
    case 5:
4941
      *offset = wdptr * 5;
4942
      *size = 3;
4943
      break;
4944
    case 8:
4945
      *offset = wdptr * 4;
4946
      *size = 4;
4947
      break;
4948
    case 7:
4949
      *offset = wdptr * 3;
4950
      *size = 5;
4951
      break;
4952
    case 9:
4953
      *offset = wdptr * 2;
4954
      *size = 6;
4955
      break;
4956
    case 10:
4957
      *offset = wdptr * 1;
4958
      *size = 7;
4959
      break;
4960
    case 11:
4961
      *offset = 0;
4962
      *size = 8 + 8*wdptr;
4963
      break;
4964
    case 12:
4965
      *offset = 0;
4966
      *size = 32 + 32*wdptr;
4967
      break;
4968
    case 13:
4969
      *offset = 0;
4970
      *size = 96 + 32*wdptr;
4971
      break;
4972
    case 14:
4973
      *offset = 0;
4974
      *size = 160 + 32*wdptr;
4975
      break;
4976
    case 15:
4977
      *offset = 0;
4978
      *size = 224 + 32*wdptr;
4979
      break;
4980
  }
4981
}
4982
 
4983
 
4984
static uint16_t wrsizeGet(const uint32_t address, const uint16_t size)
4985
{
4986
  uint8_t wdptr;
4987
  uint8_t wrsize;
4988
 
4989
 
4990
  switch(size/8)
4991
  {
4992
    case 0:
4993
      /**************************************************************
4994
       * Sub double-word access.
4995
       **************************************************************/
4996
      switch(size%8)
4997
      {
4998
        case 0:
4999
          /* Not supported by protocol. */
5000
          wdptr = 0xff;
5001
          wrsize = 0xff;
5002
          break;
5003
        case 1:
5004
          /* Writing one byte. */
5005
          /* Any address is allowed. */
5006
          wdptr = (address >> 2) & 0x1;
5007
          wrsize = address & 0x3;
5008
          break;
5009
        case 2:
5010
          /* Writing two bytes. */
5011
          /* Address 0, 2, 4, 6 are valid. */
5012
          if((address & 0x1) == 0)
5013
          {
5014
            wdptr = (address >> 2) & 0x1;
5015
            wrsize = (address & 0x7) | 0x4;
5016
          }
5017
          else
5018
          {
5019
            /* Not supported by protocol. */
5020
            wdptr = 0xff;
5021
            wrsize = 0xff;
5022
          }
5023
          break;
5024
        case 3:
5025
          /* Writing 3 bytes. */
5026
          /* Address 0 and 5 are valid. */
5027
          if(((address & 0x7) == 0) ||
5028
             ((address & 0x7) == 5))
5029
          {
5030
            wdptr = (address >> 2) & 0x1;
5031
            wrsize = 0x5ul;
5032
          }
5033
          else
5034
          {
5035
            /* Not supported by protocol. */
5036
            wdptr = 0xff;
5037
            wrsize = 0xff;
5038
          }
5039
          break;
5040
        case 4:
5041
          /* Writing 4 bytes. */
5042
          /* Address 0 and 4 are valid. */
5043
          if(((address & 0x7) == 0) ||
5044
             ((address & 0x7) == 4))
5045
          {
5046
            wdptr = (address >> 2) & 0x1;
5047
            wrsize = 0x8ul;
5048
          }
5049
          else
5050
          {
5051
            /* Not supported by protocol. */
5052
            wdptr = 0xff;
5053
            wrsize = 0xff;
5054
          }
5055
          break;
5056
        case 5:
5057
          /* Writing 5 bytes. */
5058
          /* Address 0 and 3 are valid. */
5059
          if(((address & 0x7) == 0) ||
5060
             ((address & 0x7) == 3))
5061
          {
5062
            wdptr = (address >> 1) & 0x1;
5063
            wrsize = 0x7ul;
5064
          }
5065
          else
5066
          {
5067
            /* Not supported by protocol. */
5068
            wdptr = 0xff;
5069
            wrsize = 0xff;
5070
          }
5071
          break;
5072
        case 6:
5073
          /* Writing 6 bytes. */
5074
          /* Addresses 0 and 2 are valid. */
5075
          if(((address & 0x7) == 0) ||
5076
             ((address & 0x7) == 2))
5077
          {
5078
            wdptr = (address >> 1) & 0x1;
5079
            wrsize = 0x9ul;
5080
          }
5081
          else
5082
          {
5083
            /* Not supported by protocol. */
5084
            wdptr = 0xff;
5085
            wrsize = 0xff;
5086
          }
5087
          break;
5088
        default:
5089
          /* Writing 7 bytes. */
5090
          /* Addresses 0 and 1 are valid. */
5091
          if(((address & 0x7) == 0) ||
5092
             ((address & 0x7) == 1))
5093
          {
5094
            wdptr = address & 0x1;
5095
            wrsize = 0xaul;
5096
          }
5097
          else
5098
          {
5099
            /* Not supported by protocol. */
5100
            wdptr = 0xff;
5101
            wrsize = 0xff;
5102
          }
5103
          break;
5104
      }
5105
      break;
5106
    case 1:
5107
      /* Writing 8 bytes. */
5108
      /* Only even double-word address are valid. */
5109
      if((address % 8) == 0)
5110
      {
5111
        wdptr = 0;
5112
        wrsize = 0xbul;
5113
      }
5114
      else
5115
      {
5116
        /* Not supported by protocol. */
5117
        wdptr = 0xff;
5118
        wrsize = 0xff;
5119
      }
5120
      break;
5121
    case 2:
5122
      /* Writing 16 bytes max. */
5123
      /* Only even double-word address are valid. */
5124
      if((address % 8) == 0)
5125
      {
5126
        wdptr = 1;
5127
        wrsize = 0xbul;
5128
      }
5129
      else
5130
      {
5131
        /* Not supported by protocol. */
5132
        wdptr = 0xff;
5133
        wrsize = 0xff;
5134
      }
5135
      break;
5136
    case 3:
5137
    case 4:
5138
      /* Writing 32 bytes max. */
5139
      /* Only even double-word address are valid. */
5140
      if((address & 0x7) == 0)
5141
      {
5142
        wdptr = 0;
5143
        wrsize = 0xcul;
5144
      }
5145
      else
5146
      {
5147
        /* Not supported by protocol. */
5148
        wdptr = 0xff;
5149
        wrsize = 0xff;
5150
      }
5151
      break;
5152
    case 5:
5153
    case 6:
5154
    case 7:
5155
    case 8:
5156
      /* Writing 64 bytes max. */
5157
      /* Only even double-word address are valid. */
5158
      if((address & 0x7) == 0)
5159
      {
5160
        wdptr = 1;
5161
        wrsize = 0xcul;
5162
      }
5163
      else
5164
      {
5165
        /* Not supported by protocol. */
5166
        wdptr = 0xff;
5167
        wrsize = 0xff;
5168
      }
5169
      break;
5170
    case 9:
5171
    case 10:
5172
    case 11:
5173
    case 12:
5174
    case 13:
5175
    case 14:
5176
    case 15:
5177
    case 16:
5178
      /* Writing 128 bytes max. */
5179
      /* Only even double-word address are valid. */
5180
      if((address & 0x7) == 0)
5181
      {
5182
        wdptr = 1;
5183
        wrsize = 0xdul;
5184
      }
5185
      else
5186
      {
5187
        /* Not supported by protocol. */
5188
        wdptr = 0xff;
5189
        wrsize = 0xff;
5190
      }
5191
      break;
5192
    case 17:
5193
    case 18:
5194
    case 19:
5195
    case 20:
5196
    case 21:
5197
    case 22:
5198
    case 23:
5199
    case 24:
5200
    case 25:
5201
    case 26:
5202
    case 27:
5203
    case 28:
5204
    case 29:
5205
    case 30:
5206
    case 31:
5207
    case 32:
5208
      /* Writing 256 bytes max. */
5209
      /* Only even double-word address are valid. */
5210
      if((address & 0x7) == 0)
5211
      {
5212
        wdptr = 1;
5213
        wrsize = 0xful;
5214
      }
5215
      else
5216
      {
5217
        /* Not supported by protocol. */
5218
        wdptr = 0xff;
5219
        wrsize = 0xff;
5220
      }
5221
      break;
5222
    default:
5223
      /* Not supported by protocol. */
5224
      wdptr = 0xff;
5225
      wrsize = 0xff;
5226
      break;
5227
  }
5228
 
5229
  return ((((uint16_t) wrsize) << 8) | ((uint16_t) wdptr));
5230
}
5231
 
5232
 
5233
void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
5234
{
5235
  switch(wrsize)
5236
  {
5237
    case 0:
5238
    case 1:
5239
    case 2:
5240
    case 3:
5241
      *offset = wdptr << 2;
5242
      *offset |= wrsize;
5243
      *size = 1;
5244
      break;
5245
    case 4:
5246
    case 6:
5247
      *offset = wdptr << 2;
5248
      *offset |= wrsize & 0x02;
5249
      *size = 2;
5250
      break;
5251
    case 5:
5252
      *offset = wdptr * 5;
5253
      *size = 3;
5254
      break;
5255
    case 8:
5256
      *offset = wdptr * 4;
5257
      *size = 4;
5258
      break;
5259
    case 7:
5260
      *offset = wdptr * 3;
5261
      *size = 5;
5262
      break;
5263
    case 9:
5264
      *offset = wdptr * 2;
5265
      *size = 6;
5266
      break;
5267
    case 10:
5268
      *offset = wdptr * 1;
5269
      *size = 7;
5270
      break;
5271
    case 11:
5272
      *offset = 0;
5273
      *size = 8 + 8*wdptr;
5274
      break;
5275
    case 12:
5276
      *offset = 0;
5277
      *size = 32 + 32*wdptr;
5278
      break;
5279
    case 13:
5280
      *offset = 0;
5281
      *size = 128*wdptr;
5282
      break;
5283
    case 14:
5284
      *offset = 0;
5285
      *size = 0;
5286
      break;
5287
    case 15:
5288
      *offset = 0;
5289
      *size = 256*wdptr;
5290
      break;
5291
  }
5292
}
5293
 
5294
 
5295
static RioSymbol CreateControlSymbol( const uint8_t stype0,
5296
                                      const uint8_t parameter0, const uint8_t parameter1,
5297
                                      const uint8_t stype1, const uint8_t cmd)
5298
{
5299
  RioSymbol s;
5300
 
5301
  s.type = RIO_SYMBOL_TYPE_CONTROL;
5302
 
5303
  s.data = ((uint32_t)stype0 & (uint32_t)0x07ul) << 21;
5304
  s.data |= ((uint32_t)parameter0 & (uint32_t)0x1ful) << 16;
5305
  s.data |= ((uint32_t)parameter1 & (uint32_t)0x1ful) << 11;
5306
  s.data |= ((uint32_t)stype1 & (uint32_t)0x07ul) << 8;
5307
  s.data |= ((uint32_t)cmd & (uint32_t)0x7ul) << 5;
5308
  s.data |= Crc5(s.data, 0x1fu);
5309
 
5310
  return s;
5311
}
5312
 
5313
 
5314
static uint8_t Crc5( const uint32_t data, const uint8_t crc)
5315
{
5316
  static const uint8_t crcTable[] = {
5317
    0x00u, 0x15u, 0x1fu, 0x0au, 0x0bu, 0x1eu, 0x14u, 0x01u,
5318
    0x16u, 0x03u, 0x09u, 0x1cu, 0x1du, 0x08u, 0x02u, 0x17u,
5319
    0x19u, 0x0cu, 0x06u, 0x13u, 0x12u, 0x07u, 0x0du, 0x18u,
5320
    0x0fu, 0x1au, 0x10u, 0x05u, 0x04u, 0x11u, 0x1bu, 0x0eu
5321
  };
5322
 
5323
  uint8_t result;
5324
  uint8_t index;
5325
 
5326
  result = crc;
5327
  index  = (uint8_t)((data >> 19) & (uint32_t)0x1ful) ^ result;
5328
  result = crcTable[index];
5329
  index  = (uint8_t)((data >> 14) & (uint32_t)0x1ful) ^ result;
5330
  result = crcTable[index];
5331
  index  = (uint8_t)((data >> 9) & (uint32_t)0x1ful) ^ result;
5332
  result = crcTable[index];
5333
  index  = (uint8_t)((data >> 4) & (uint32_t)0x1eul) ^ result;
5334
  result = crcTable[index];
5335
 
5336
  return result;
5337
}
5338
 
5339
 
5340
static uint16_t Crc16( const uint16_t data, const uint16_t crc)
5341
{
5342
  static const uint16_t crcTable[] = {
5343
    0x0000u, 0x1021u, 0x2042u, 0x3063u, 0x4084u, 0x50a5u, 0x60c6u, 0x70e7u,
5344
    0x8108u, 0x9129u, 0xa14au, 0xb16bu, 0xc18cu, 0xd1adu, 0xe1ceu, 0xf1efu,
5345
    0x1231u, 0x0210u, 0x3273u, 0x2252u, 0x52b5u, 0x4294u, 0x72f7u, 0x62d6u,
5346
    0x9339u, 0x8318u, 0xb37bu, 0xa35au, 0xd3bdu, 0xc39cu, 0xf3ffu, 0xe3deu,
5347
    0x2462u, 0x3443u, 0x0420u, 0x1401u, 0x64e6u, 0x74c7u, 0x44a4u, 0x5485u,
5348
    0xa56au, 0xb54bu, 0x8528u, 0x9509u, 0xe5eeu, 0xf5cfu, 0xc5acu, 0xd58du,
5349
    0x3653u, 0x2672u, 0x1611u, 0x0630u, 0x76d7u, 0x66f6u, 0x5695u, 0x46b4u,
5350
    0xb75bu, 0xa77au, 0x9719u, 0x8738u, 0xf7dfu, 0xe7feu, 0xd79du, 0xc7bcu,
5351
    0x48c4u, 0x58e5u, 0x6886u, 0x78a7u, 0x0840u, 0x1861u, 0x2802u, 0x3823u,
5352
    0xc9ccu, 0xd9edu, 0xe98eu, 0xf9afu, 0x8948u, 0x9969u, 0xa90au, 0xb92bu,
5353
    0x5af5u, 0x4ad4u, 0x7ab7u, 0x6a96u, 0x1a71u, 0x0a50u, 0x3a33u, 0x2a12u,
5354
    0xdbfdu, 0xcbdcu, 0xfbbfu, 0xeb9eu, 0x9b79u, 0x8b58u, 0xbb3bu, 0xab1au,
5355
    0x6ca6u, 0x7c87u, 0x4ce4u, 0x5cc5u, 0x2c22u, 0x3c03u, 0x0c60u, 0x1c41u,
5356
    0xedaeu, 0xfd8fu, 0xcdecu, 0xddcdu, 0xad2au, 0xbd0bu, 0x8d68u, 0x9d49u,
5357
    0x7e97u, 0x6eb6u, 0x5ed5u, 0x4ef4u, 0x3e13u, 0x2e32u, 0x1e51u, 0x0e70u,
5358
    0xff9fu, 0xefbeu, 0xdfddu, 0xcffcu, 0xbf1bu, 0xaf3au, 0x9f59u, 0x8f78u,
5359
    0x9188u, 0x81a9u, 0xb1cau, 0xa1ebu, 0xd10cu, 0xc12du, 0xf14eu, 0xe16fu,
5360
    0x1080u, 0x00a1u, 0x30c2u, 0x20e3u, 0x5004u, 0x4025u, 0x7046u, 0x6067u,
5361
    0x83b9u, 0x9398u, 0xa3fbu, 0xb3dau, 0xc33du, 0xd31cu, 0xe37fu, 0xf35eu,
5362
    0x02b1u, 0x1290u, 0x22f3u, 0x32d2u, 0x4235u, 0x5214u, 0x6277u, 0x7256u,
5363
    0xb5eau, 0xa5cbu, 0x95a8u, 0x8589u, 0xf56eu, 0xe54fu, 0xd52cu, 0xc50du,
5364
    0x34e2u, 0x24c3u, 0x14a0u, 0x0481u, 0x7466u, 0x6447u, 0x5424u, 0x4405u,
5365
    0xa7dbu, 0xb7fau, 0x8799u, 0x97b8u, 0xe75fu, 0xf77eu, 0xc71du, 0xd73cu,
5366
    0x26d3u, 0x36f2u, 0x0691u, 0x16b0u, 0x6657u, 0x7676u, 0x4615u, 0x5634u,
5367
    0xd94cu, 0xc96du, 0xf90eu, 0xe92fu, 0x99c8u, 0x89e9u, 0xb98au, 0xa9abu,
5368
    0x5844u, 0x4865u, 0x7806u, 0x6827u, 0x18c0u, 0x08e1u, 0x3882u, 0x28a3u,
5369
    0xcb7du, 0xdb5cu, 0xeb3fu, 0xfb1eu, 0x8bf9u, 0x9bd8u, 0xabbbu, 0xbb9au,
5370
    0x4a75u, 0x5a54u, 0x6a37u, 0x7a16u, 0x0af1u, 0x1ad0u, 0x2ab3u, 0x3a92u,
5371
    0xfd2eu, 0xed0fu, 0xdd6cu, 0xcd4du, 0xbdaau, 0xad8bu, 0x9de8u, 0x8dc9u,
5372
    0x7c26u, 0x6c07u, 0x5c64u, 0x4c45u, 0x3ca2u, 0x2c83u, 0x1ce0u, 0x0cc1u,
5373
    0xef1fu, 0xff3eu, 0xcf5du, 0xdf7cu, 0xaf9bu, 0xbfbau, 0x8fd9u, 0x9ff8u,
5374
    0x6e17u, 0x7e36u, 0x4e55u, 0x5e74u, 0x2e93u, 0x3eb2u, 0x0ed1u, 0x1ef0u
5375
  };
5376
 
5377
  uint16_t result;
5378
  uint8_t index;
5379
 
5380
  result = crc;
5381
  index = (uint8_t) ((data >> 8)  ^ (result >> 8));
5382
  result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
5383
  index = (uint8_t) ((data)  ^ (result >> 8));
5384
  result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
5385
 
5386
  return result;
5387
}
5388
 
5389
 
5390
static uint16_t Crc32( const uint32_t data, uint16_t crc)
5391
{
5392
  crc = Crc16((uint16_t) (data >> 16), crc);
5393
  crc = Crc16((uint16_t) (data), crc);
5394
  return crc;
5395
}
5396
 
5397
 
5398
 
5399
 
5400
 
5401
static Queue_t QueueCreate( const uint8_t size, uint32_t *buffer)
5402
{
5403
  Queue_t q;
5404
 
5405
  q.size = size;
5406
  q.available = size;
5407
  q.windowSize = 0u;
5408
  q.windowIndex = 0u;
5409
  q.frontIndex = 0u;
5410
  q.backIndex = 0u;
5411
  q.buffer_p = buffer;
5412
 
5413
  return q;
5414
}
5415
 
5416
 
5417
static uint8_t QueueAvailable( const Queue_t q)
5418
{
5419
  return q.available;
5420
}
5421
 
5422
 
5423
static bool_t QueueEmpty( const Queue_t q)
5424
{
5425
  return (bool_t) (q.available == q.size);
5426
}
5427
 
5428
 
5429
static uint8_t QueueLength( const Queue_t q)
5430
{
5431
  return q.size - q.available;
5432
}
5433
 
5434
 
5435
static Queue_t QueueEnqueue( Queue_t q)
5436
{
5437
  q.backIndex++;
5438
  if(q.backIndex == q.size)
5439
  {
5440
    q.backIndex = 0;
5441
  }
5442
  q.available--;
5443
  return q;
5444
}
5445
 
5446
 
5447
static Queue_t QueueDequeue( Queue_t q)
5448
{
5449
  q.frontIndex++;
5450
  if(q.frontIndex == q.size)
5451
  {
5452
    q.frontIndex = 0;
5453
  }
5454
  q.available++;
5455
  if(q.windowSize == 0)
5456
  {
5457
    q.windowIndex = q.frontIndex;
5458
  }
5459
  else
5460
  {
5461
    q.windowSize--;
5462
  }
5463
  return q;
5464
}
5465
 
5466
 
5467
static bool_t QueueWindowEmpty( const Queue_t q)
5468
{
5469
  return (bool_t) ((q.available + q.windowSize) == q.size);
5470
}
5471
 
5472
 
5473
static Queue_t QueueWindowReset(Queue_t q)
5474
{
5475
  q.windowIndex = q.frontIndex;
5476
  q.windowSize = 0;
5477
  return q;
5478
}
5479
 
5480
 
5481
static Queue_t QueueWindowNext(Queue_t q)
5482
{
5483
  q.windowIndex++;
5484
  if(q.windowIndex == q.size)
5485
  {
5486
    q.windowIndex = 0;
5487
  }
5488
  q.windowSize++;
5489
  return q;
5490
}
5491
 
5492
 
5493
static void QueueSetSize( Queue_t q, const uint32_t size)
5494
{
5495
  (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[0] = size;
5496
}
5497
 
5498
 
5499
static void QueueSetContent( Queue_t q, const uint32_t index, const uint32_t content)
5500
{
5501
  (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[index+1ul] = content;
5502
}
5503
 
5504
 
5505
static uint32_t QueueGetFrontSize( Queue_t q)
5506
{
5507
  return (q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[0];
5508
}
5509
 
5510
 
5511
static uint32_t QueueGetFrontContent( const Queue_t q, const uint32_t index)
5512
{
5513
  return (q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[index+1ul];
5514
}
5515
 
5516
 
5517
static uint32_t *QueueGetFrontBuffer( const Queue_t q )
5518
{
5519
  return &((q.buffer_p+(RIO_BUFFER_SIZE*q.windowIndex))[1]);
5520
}
5521
 
5522
 
5523
static uint32_t QueueGetBackSize( const Queue_t q)
5524
{
5525
  return (q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[0];
5526
}
5527
 
5528
 
5529
static uint32_t *QueueGetBackBuffer( const Queue_t q )
5530
{
5531
  return &((q.buffer_p+(RIO_BUFFER_SIZE*q.backIndex))[1]);
5532
}
5533
 
5534
 
5535
#ifdef MODULE_TEST
5536
#include <stdio.h>
5537
#define PrintS(s)                                \
5538
  {                                               \
5539
    FILE *fd;                                     \
5540
    fd=fopen("testspec.txt", "a");                \
5541
    fputs(s "\n", fd);                                 \
5542
    fclose(fd);                                   \
5543
  }
5544
 
5545
#define TESTSTART(s) printf(s)
5546
#define TESTEND printf(" passed.\n");
5547
 
5548
#define TESTCOND(got)                           \
5549
  if (!(got))                                   \
5550
  {                                             \
5551
    printf("ERROR at line %u:%s=%u (0x%08x)\n", \
5552
           __LINE__, #got, (got), (got));       \
5553
    exit(1);                                    \
5554
  }
5555
 
5556
#define TESTEXPR(got, expected)                                         \
5557
  if ((got)!=(expected))                                                \
5558
  {                                                                     \
5559
    printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",    \
5560
           __LINE__, #got, (got), (got), (expected), (expected));       \
5561
    exit(1);                                                            \
5562
  }
5563
 
5564
#define TESTSYMBOL(got, expected) testSymbol(__LINE__, #got, (got), (expected))
5565
 
5566
void testSymbol(uint32_t line, char *expression, RioSymbol got, RioSymbol expected)
5567
{
5568
  if ((got).type==(expected).type)
5569
  {
5570
    switch ((got).type)
5571
    {
5572
      case RIO_SYMBOL_TYPE_ERROR:
5573
      case RIO_SYMBOL_TYPE_IDLE:
5574
        break;
5575
      case RIO_SYMBOL_TYPE_CONTROL:
5576
        if((got).data != (expected).data)
5577
        {
5578
          if(STYPE0_GET((got).data) != STYPE0_GET((expected).data))
5579
          {
5580
            printf("ERROR at line %u:STYPE0=0x%02x expected=0x%02x\n",
5581
                   line, STYPE0_GET((got).data), STYPE0_GET((expected).data));
5582
          }
5583
          if(PARAMETER0_GET((got).data) != PARAMETER0_GET((expected).data))
5584
          {
5585
            printf("ERROR at line %u:PARAMETER0=0x%02x expected=0x%02x\n",
5586
                   line, PARAMETER0_GET((got).data), PARAMETER0_GET((expected).data));
5587
          }
5588
          if(PARAMETER1_GET((got).data) != PARAMETER1_GET((expected).data))
5589
          {
5590
            printf("ERROR at line %u:PARAMETER1=0x%02x expected=0x%02x\n",
5591
                   line, PARAMETER1_GET((got).data), PARAMETER1_GET((expected).data));
5592
          }
5593
          if(STYPE1_GET((got).data) != STYPE1_GET((expected).data))
5594
          {
5595
            printf("ERROR at line %u:STYPE1=0x%02x expected=0x%02x\n",
5596
                   line, STYPE1_GET((got).data), STYPE1_GET((expected).data));
5597
          }
5598
          if(CMD_GET((got).data) != CMD_GET((expected).data))
5599
          {
5600
            printf("ERROR at line %u:CMD=0x%02x expected=0x%02x\n",
5601
                   line, CMD_GET((got).data), CMD_GET((expected).data));
5602
          }
5603
          if(CRC5_GET((got).data) != CRC5_GET((expected).data))
5604
          {
5605
            printf("ERROR at line %u:CRC5=0x%02x expected=0x%02x\n",
5606
                   line, CRC5_GET((got).data), CRC5_GET((expected).data));
5607
          }
5608
          exit(1);
5609
        }
5610
        break;
5611
      case RIO_SYMBOL_TYPE_DATA:
5612
        if((got).data != (expected).data)
5613
        {
5614
          printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",
5615
                 line, expression, (got).data, (got).data, (expected).data, (expected).data);
5616
          exit(1);
5617
        }
5618
        break;
5619
    }
5620
  }
5621
  else
5622
  {
5623
    printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",
5624
           line, expression, (got).type, (got).type, (expected).type, (expected).type);
5625
    exit(1);
5626
  }
5627
}
5628
 
5629
 
5630
 
5631
uint32_t testConfigWriteData;
5632
 
5633
uint8_t createDoorbell(uint32_t *doorbell, uint8_t ackId, uint16_t destid, uint16_t srcId, uint8_t tid, uint16_t info)
5634
{
5635
  uint16_t crc;
5636
  uint32_t content;
5637
 
5638
  /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
5639
  /* ackId is set when the packet is transmitted. */
5640
  content = 0x001aul << 16;
5641
  content |= (uint32_t) destid;
5642
  crc = Crc32(content, 0xffffu);
5643
  doorbell[0] = (((uint32_t) ackId) << 27) | content;
5644
 
5645
  /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
5646
  content = ((uint32_t) srcId) << 16;
5647
  content |= (uint32_t) tid;
5648
  crc = Crc32(content, crc);
5649
  doorbell[1] = content;
5650
 
5651
  /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
5652
  content = ((uint32_t) info) << 16;
5653
  crc = Crc16(info, crc);
5654
  content |= ((uint32_t) crc);
5655
  doorbell[2] = content;
5656
 
5657
  return 3;
5658
 
5659
}
5660
 
5661
uint32_t testConfigRead(RioStack_t *stack, uint32_t offset)
5662
{
5663
  switch(offset)
5664
  {
5665
    case 0:
5666
      return 0x80000006;
5667
    case 4:
5668
      return 0x00a100a2;
5669
    case 8:
5670
      return testConfigWriteData;
5671
    default:
5672
      return 0x00000000;
5673
  }
5674
}
5675
 
5676
void testConfigWrite(RioStack_t *stack, uint32_t offset, uint32_t data)
5677
{
5678
  switch(offset)
5679
  {
5680
    case 8:
5681
      testConfigWriteData = data;
5682
      break;
5683
    default:
5684
      /* Dont do anything. */
5685
      break;
5686
  }
5687
}
5688
 
5689
/*******************************************************************************
5690
 * Module test for this file.
5691
 *******************************************************************************/
5692
int32_t main(void)
5693
{
5694
  RioStack_t stack;
5695
  RioStackObserver_t observer;
5696
  uint32_t rxPacketBuffer[RIO_BUFFER_SIZE*8], txPacketBuffer[RIO_BUFFER_SIZE*8];
5697
  RioSymbol s, c, d;
5698
  int i, j, k;
5699
  uint16_t length;
5700
  uint16_t srcid;
5701
  uint8_t tid;
5702
  uint8_t hop;
5703
  uint8_t mailbox;
5704
  uint16_t info;
5705
  uint32_t address;
5706
  uint32_t data;
5707
  uint8_t payload8[256];
5708
  uint8_t payload8Expected[256];
5709
  uint32_t packet[69];
5710
  uint32_t packetLength;
5711
 
5712
 
5713
  /*************************************************************************
5714
   * Test prelude.
5715
   * Setup the RIO stack for operation.
5716
   *************************************************************************/
5717
 
5718
  /* Setup callback handlers for config-space accesses in the implementation-
5719
     defined address range. */
5720
  observer.configRead = testConfigRead;
5721
  observer.configWrite = testConfigWrite;
5722
 
5723
  /* Open the stack and set the port status to initialized. */
5724
  RIO_open(&stack, &observer, NULL,
5725
           RIO_BUFFER_SIZE*8, &rxPacketBuffer[0],
5726
           RIO_BUFFER_SIZE*8, &txPacketBuffer[0],
5727
           0xb03b, 0x0000, 0x00000000, 0x0000, 0x0000, 0x0000, 0xffff);
5728
 
5729
  /* Set the port timeout. */
5730
  RIO_portSetTimeout(&stack, 1);
5731
 
5732
  /* Set the current port time. */
5733
  RIO_portSetTime(&stack, 0);
5734
 
5735
  /* Set master enable. */
5736
  RIO_writeConfig(&stack,
5737
                  PORT_GENERAL_CONTROL_CSR(EXTENDED_FEATURES_OFFSET), 0x40000000);
5738
 
5739
  /******************************************************************************/
5740
  PrintS("----------------------------------------------------------------------");
5741
  PrintS("TG_riostack");
5742
  PrintS("----------------------------------------------------------------------");
5743
  PrintS("TG_riostack-TC1");
5744
  PrintS("Description: Test link initialization and normal packet exchange.");
5745
  PrintS("Requirement: XXXXX");
5746
  PrintS("----------------------------------------------------------------------");
5747
  PrintS("Step 1:");
5748
  PrintS("Action: Send packets when port is uninitialized.");
5749
  PrintS("Result: All packets should be ignored during initialization.");
5750
  PrintS("----------------------------------------------------------------------");
5751
  /******************************************************************************/
5752
  TESTSTART("TG_riostack-TC1-Step1");
5753
  /******************************************************************************/
5754
 
5755
  /* Place a packet in the outbound queue to check that it is received once
5756
     the transmitter is placed in the correct state. */
5757
  RIO_sendDoorbell(&stack, 1, 0, 0xdeaf);
5758
 
5759
  /* Check that only idle symbols are transmitted when the port has not been
5760
     initialied even if statuses are received. */
5761
  for(i = 0; i < 1024; i++)
5762
  {
5763
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
5764
    s = RIO_portGetSymbol(&stack);
5765
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
5766
  }
5767
 
5768
  /******************************************************************************/
5769
  TESTEND;
5770
  /*****************************************************************************/
5771
  PrintS("----------------------------------------------------------------------");
5772
  PrintS("Step 2:");
5773
  PrintS("Action: Set port initialized and get symbols from the stack.");
5774
  PrintS("Result: Status-control-symbols should be generated each 256 symbol.");
5775
  PrintS("----------------------------------------------------------------------");
5776
  /*****************************************************************************/
5777
  TESTSTART("TG_riostack-TC1-Step2");
5778
  /*****************************************************************************/
5779
 
5780
  /* Set the port status to intialized. */
5781
  RIO_portSetStatus(&stack, 1);
5782
 
5783
  /* Set port time. */
5784
  RIO_portSetTime(&stack, 1);
5785
 
5786
  /* Check that status-control-symbols are transmitted once every 256 symbol. */
5787
  for(j = 0; j < 15; j++)
5788
  {
5789
    for(i = 0; i < 255; i++)
5790
    {
5791
      s = RIO_portGetSymbol(&stack);
5792
      TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
5793
    }
5794
    s = RIO_portGetSymbol(&stack);
5795
    c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0);
5796
    TESTEXPR(s.type, c.type);
5797
    TESTEXPR(s.data, c.data);
5798
  }
5799
 
5800
  /******************************************************************************/
5801
  TESTEND;
5802
  /******************************************************************************/
5803
  PrintS("----------------------------------------------------------------------");
5804
  PrintS("Step 3:");
5805
  PrintS("Action: Add a status-control-symbol to the receiver.");
5806
  PrintS("Result: Status-control-symbols should be generated each 15 symbol.");
5807
  PrintS("----------------------------------------------------------------------");
5808
  /******************************************************************************/
5809
  TESTSTART("TG_riostack-TC1-Step3");
5810
  /*****************************************************************************/
5811
 
5812
  /* Insert a status-control-symbol in the receive. */
5813
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
5814
 
5815
  /* Check that status-control-symbols are transmitted once every 16 symbol. */
5816
  for(i = 0; i < 15; i++)
5817
  {
5818
    s = RIO_portGetSymbol(&stack);
5819
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
5820
  }
5821
  s = RIO_portGetSymbol(&stack);
5822
  c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0);
5823
  TESTEXPR(s.type, c.type);
5824
  TESTEXPR(s.data, c.data);
5825
 
5826
  /******************************************************************************/
5827
  TESTEND;
5828
  /******************************************************************************/
5829
  PrintS("----------------------------------------------------------------------");
5830
  PrintS("Step 4:");
5831
  PrintS("Action: Add a packet to the receiver.");
5832
  PrintS("Result: Packet should be ignored until the link is initialized.");
5833
  PrintS("----------------------------------------------------------------------");
5834
  /******************************************************************************/
5835
  TESTSTART("TG_riostack-TC1-Step4");
5836
  /*****************************************************************************/
5837
 
5838
  /* Send a packet. Note that the start and end of the packet contains a status. */
5839
  packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
5840
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
5841
  for(i = 0; i < packetLength; i++)
5842
  {
5843
    d.type = RIO_SYMBOL_TYPE_DATA;
5844
    d.data = packet[i];
5845
    RIO_portAddSymbol(&stack, d);
5846
  }
5847
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
5848
 
5849
  /* Check that packet was not received. */
5850
  TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_NONE);
5851
 
5852
  /******************************************************************************/
5853
  TESTEND;
5854
  /******************************************************************************/
5855
  PrintS("----------------------------------------------------------------------");
5856
  PrintS("Step 5:");
5857
  PrintS("Action: Add four more status-control-symbols followed by one with error in ");
5858
  PrintS("        CRC5. Then send a packet.");
5859
  PrintS("Result: The receiver should remain in port initialized and packet should ");
5860
  PrintS("        still be ignored.");
5861
  PrintS("----------------------------------------------------------------------");
5862
  /******************************************************************************/
5863
  TESTSTART("TG_riostack-TC1-Step5");
5864
  /*****************************************************************************/
5865
 
5866
  /* Send 4 more status-control-symbols followed by one erronous. */
5867
  for(i = 0; i < 4; i++)
5868
  {
5869
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
5870
  }
5871
  c = CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0);
5872
  c.data ^= 1;
5873
  RIO_portAddSymbol(&stack, c);
5874
 
5875
  /* Send a packet. Note that the start and end of the packet contains status. */
5876
  packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
5877
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
5878
  for(i = 0; i < packetLength; i++)
5879
  {
5880
    d.type = RIO_SYMBOL_TYPE_DATA;
5881
    d.data = packet[i];
5882
    RIO_portAddSymbol(&stack, d);
5883
  }
5884
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
5885
 
5886
  /* Check that the packet was ignored. */
5887
  TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_NONE);
5888
 
5889
  /******************************************************************************/
5890
  TESTEND;
5891
  /******************************************************************************/
5892
  PrintS("----------------------------------------------------------------------");
5893
  PrintS("Step 6:");
5894
  PrintS("Action: Add six more status-control-symbols. Then send a packet.");
5895
  PrintS("Result: The receiver should enter link initialized and the packet should ");
5896
  PrintS("        be received.");
5897
  PrintS("----------------------------------------------------------------------");
5898
  /******************************************************************************/
5899
  TESTSTART("TG_riostack-TC1-Step6");
5900
  /*****************************************************************************/
5901
 
5902
  /* Send 6 more status-control-symbols. */
5903
  for(i = 0; i < 6; i++)
5904
  {
5905
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0));
5906
  }
5907
 
5908
  /* Send a packet and check that it is accepted. */
5909
  /* The ackId on receiver in testobject is updated when this has been transmitted. */
5910
  packetLength = createDoorbell(packet, 0, 0, 0, 0, 0);
5911
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0));
5912
  for(i = 0; i < packetLength; i++)
5913
  {
5914
    d.type = RIO_SYMBOL_TYPE_DATA;
5915
    d.data = packet[i];
5916
    RIO_portAddSymbol(&stack, d);
5917
  }
5918
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0));
5919
 
5920
  /* Check that the packet is received. */
5921
  TESTEXPR(RIO_eventPoll(&stack), RIO_EVENT_DOORBELL);
5922
 
5923
  /******************************************************************************/
5924
  TESTEND;
5925
  /******************************************************************************/
5926
  PrintS("----------------------------------------------------------------------");
5927
  PrintS("Step 7:");
5928
  PrintS("Action: Get symbols from transmitter.");
5929
  PrintS("Result: Status-control-symbols should still be generated each 15 symbol ");
5930
  PrintS("until a total of 15 status-control-symbols has been transmitted. Once these ");
5931
  PrintS("has been transmitted, the transmitter will be link initialized.");
5932
  PrintS("----------------------------------------------------------------------");
5933
  /******************************************************************************/
5934
  TESTSTART("TG_riostack-TC1-Step7");
5935
  /*****************************************************************************/
5936
 
5937
  /* Note that the available buffers in the receiver should have decremented once
5938
     since the previously received packet has not been read from the application
5939
     side of the stack yet. */
5940
  for(j = 0; j < 14; j++)
5941
  {
5942
    for(i = 0; i < 15; i++)
5943
    {
5944
      s = RIO_portGetSymbol(&stack);
5945
      TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
5946
    }
5947
    s = RIO_portGetSymbol(&stack);
5948
    c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_NOP, 0);
5949
    TESTEXPR(s.type, c.type);
5950
    TESTEXPR(s.data, c.data);
5951
  }
5952
 
5953
  /******************************************************************************/
5954
  TESTEND;
5955
  /******************************************************************************/
5956
  PrintS("----------------------------------------------------------------------");
5957
  PrintS("Step 8:");
5958
  PrintS("Action: Get the first symbol from the transmitter once the link-intialized ");
5959
  PrintS("        state has been entered.");
5960
  PrintS("Result: A packet-accepted-symbol should be received for the newly received ");
5961
  PrintS("        packet.");
5962
  PrintS("----------------------------------------------------------------------");
5963
  /******************************************************************************/
5964
  TESTSTART("TG_riostack-TC1-Step8");
5965
  /*****************************************************************************/
5966
 
5967
  c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 7, STYPE1_NOP, 0);
5968
  s = RIO_portGetSymbol(&stack);
5969
  TESTEXPR(s.type, c.type);
5970
  TESTEXPR(s.data, c.data);
5971
 
5972
  /******************************************************************************/
5973
  TESTEND;
5974
  /******************************************************************************/
5975
  PrintS("----------------------------------------------------------------------");
5976
  PrintS("Step 9:");
5977
  PrintS("Action: Get the next symbols from the transmitter.");
5978
  PrintS("Result: The packet placed in the outbound queue at startup should be ");
5979
  PrintS("        received. Dont acknowledge the packet yet.");
5980
  PrintS("----------------------------------------------------------------------");
5981
  /******************************************************************************/
5982
  TESTSTART("TG_riostack-TC1-Step9");
5983
  /*****************************************************************************/
5984
 
5985
  /* Create a packet. */
5986
  packetLength = createDoorbell(packet, 0, 1, 0xffff, 0, 0xdeaf);
5987
 
5988
  /* Receive the start of the frame. */
5989
  c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_START_OF_PACKET, 0);
5990
  s = RIO_portGetSymbol(&stack);
5991
  TESTEXPR(s.type, c.type);
5992
  TESTEXPR(s.data, c.data);
5993
 
5994
  /* Receive the data of the frame. */
5995
  for(i = 0; i < packetLength; i++)
5996
  {
5997
    s = RIO_portGetSymbol(&stack);
5998
    d.type = RIO_SYMBOL_TYPE_DATA;
5999
    d.data = packet[i];
6000
    TESTEXPR(s.type, d.type);
6001
    TESTEXPR(s.data, d.data);
6002
  }
6003
 
6004
  /* Receive the end of the frame. */
6005
  c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_END_OF_PACKET, 0);
6006
  s = RIO_portGetSymbol(&stack);
6007
  TESTSYMBOL(s, c);
6008
 
6009
  /******************************************************************************/
6010
  TESTEND;
6011
  /******************************************************************************/
6012
  PrintS("----------------------------------------------------------------------");
6013
  PrintS("Step 10:");
6014
  PrintS("Action: Remove the packet from the inbound queue. Dont acknowledge the");
6015
  PrintS("        transmitted packet yet.");
6016
  PrintS("Result: Check that status-control-symbols are sent each 256 symbol and that ");
6017
  PrintS("        the buffer count is updated when the inbound packet has been read.");
6018
  PrintS("----------------------------------------------------------------------");
6019
  /******************************************************************************/
6020
  TESTSTART("TG_riostack-TC1-Step10");
6021
  /*****************************************************************************/
6022
 
6023
  /* Simulate the application reading the received packet to free one reception
6024
     buffer. */
6025
  RIO_packetRemove(&stack);
6026
 
6027
  /* Check that the status-control-symbols are generated each 256 symbol. */
6028
  for(i = 0; i < 255; i++)
6029
  {
6030
    s = RIO_portGetSymbol(&stack);
6031
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
6032
  }
6033
 
6034
  /* Check that the buffer status has been updated. */
6035
  s = RIO_portGetSymbol(&stack);
6036
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
6037
  TESTEXPR(s.type, c.type);
6038
  TESTEXPR(s.data, c.data);
6039
 
6040
  /******************************************************************************/
6041
  TESTEND;
6042
  /******************************************************************************/
6043
  PrintS("----------------------------------------------------------------------");
6044
  PrintS("Step 11:");
6045
  PrintS("Action: Send a packet when an acknowledge has not been received.");
6046
  PrintS("Result: Only idle and status control symbols should be transmitted until ");
6047
  PrintS("        the packet-accepted symbol has been received.");
6048
  PrintS("----------------------------------------------------------------------");
6049
  /******************************************************************************/
6050
  TESTSTART("TG_riostack-TC1-Step11");
6051
  /*****************************************************************************/
6052
 
6053
  /* Place a packet in the outbound queue. */
6054
  RIO_sendDoorbell(&stack, 2, 1, 0xc0de);
6055
 
6056
  packetLength = createDoorbell(packet, 1, 2, 0xffff, 1, 0xc0de);
6057
 
6058
  /* Receive the start of the frame. */
6059
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_START_OF_PACKET, 0);
6060
  s = RIO_portGetSymbol(&stack);
6061
  TESTEXPR(s.type, c.type);
6062
  TESTEXPR(s.data, c.data);
6063
 
6064
  /* Receive the data of the frame. */
6065
  for(i = 0; i < packetLength; i++)
6066
  {
6067
    s = RIO_portGetSymbol(&stack);
6068
    d.type = RIO_SYMBOL_TYPE_DATA;
6069
    d.data = packet[i];
6070
    TESTEXPR(s.type, d.type);
6071
    TESTEXPR(s.data, d.data);
6072
  }
6073
 
6074
  /* Receive the end of the frame. */
6075
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_END_OF_PACKET, 0);
6076
  s = RIO_portGetSymbol(&stack);
6077
  TESTSYMBOL(s, c);
6078
 
6079
  /******************************************************************************/
6080
  TESTEND;
6081
  /******************************************************************************/
6082
  PrintS("----------------------------------------------------------------------");
6083
  PrintS("Step 12:");
6084
  PrintS("Action: Send a packet-accepted symbol.");
6085
  PrintS("Result: Check that the new packet is transmitted.");
6086
  PrintS("----------------------------------------------------------------------");
6087
  /******************************************************************************/
6088
  TESTSTART("TG_riostack-TC1-Step12");
6089
  /*****************************************************************************/
6090
 
6091
  /* Send acknowledge for the first frame. */
6092
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 1, STYPE1_NOP, 0));
6093
 
6094
  /* Check that status-control-symbols are transmitted once every 256 symbol with
6095
     updated ackId. */
6096
  for(i = 0; i < 255; i++)
6097
  {
6098
    s = RIO_portGetSymbol(&stack);
6099
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
6100
  }
6101
  s = RIO_portGetSymbol(&stack);
6102
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
6103
  TESTEXPR(s.type, c.type);
6104
  TESTEXPR(s.data, c.data);
6105
 
6106
  /******************************************************************************/
6107
  TESTEND;
6108
  /******************************************************************************/
6109
  PrintS("----------------------------------------------------------------------");
6110
  PrintS("Step 13:");
6111
  PrintS("Action: Send a packet-accepted symbol.");
6112
  PrintS("Result: Check that only idle and status-control-symbols are transmitted ");
6113
  PrintS("----------------------------------------------------------------------");
6114
  /******************************************************************************/
6115
  TESTSTART("TG_riostack-TC1-Step13");
6116
  /*****************************************************************************/
6117
 
6118
  /* Acknowledge the second frame. */
6119
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1, 1, STYPE1_NOP, 0));
6120
 
6121
  /* Check that status-control-symbols are transmitted once every 256 symbol with
6122
     updated ackId. */
6123
  for(i = 0; i < 255; i++)
6124
  {
6125
    s = RIO_portGetSymbol(&stack);
6126
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
6127
  }
6128
  s = RIO_portGetSymbol(&stack);
6129
  c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0);
6130
  TESTEXPR(s.type, c.type);
6131
  TESTEXPR(s.data, c.data);
6132
 
6133
  /******************************************************************************/
6134
  TESTEND;
6135
  /******************************************************************************/
6136
  PrintS("----------------------------------------------------------------------");
6137
  PrintS("TG_riostack-TC2");
6138
  PrintS("Description: Test flow control.");
6139
  PrintS("Requirement: XXXXX");
6140
  PrintS("----------------------------------------------------------------------");
6141
  PrintS("Step 1:");
6142
  PrintS("Action: Send packets to receiver but don't acknowledge them.");
6143
  PrintS("Result: The reception queue of the stack is full.");
6144
  PrintS("----------------------------------------------------------------------");
6145
  /******************************************************************************/
6146
  TESTSTART("TG_riostack-TC2-Step1");
6147
  /******************************************************************************/
6148
 
6149
  /* Fill input queue in receiver. */
6150
  for(j = 0; j < 8; j++)
6151
  {
6152
    packetLength = createDoorbell(packet, 1+j, 0, 0, 1+j, 0);
6153
 
6154
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
6155
    for(i = 0; i < packetLength; i++)
6156
    {
6157
      d.type = RIO_SYMBOL_TYPE_DATA;
6158
      d.data = packet[i];
6159
      RIO_portAddSymbol(&stack, d);
6160
    }
6161
    RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
6162
 
6163
    c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1+j, 7-j, STYPE1_NOP, 0);
6164
    s = RIO_portGetSymbol(&stack);
6165
    TESTEXPR(s.type, c.type);
6166
    TESTEXPR(s.data, c.data);
6167
  }
6168
 
6169
  /******************************************************************************/
6170
  TESTEND;
6171
  /******************************************************************************/
6172
  PrintS("----------------------------------------------------------------------");
6173
  PrintS("Step 2:");
6174
  PrintS("Action: Send a packet when the inbound queue of the stack is full.");
6175
  PrintS("Result: The stack sends a packet-retry symbol. The receiver will end up in ");
6176
  PrintS("input-retry-stopped state.");
6177
  PrintS("----------------------------------------------------------------------");
6178
  /******************************************************************************/
6179
  TESTSTART("TG_riostack-TC2-Step2");
6180
  /******************************************************************************/
6181
 
6182
  /* Send another packet. */
6183
  packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
6184
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
6185
  for(i = 0; i < packetLength; i++)
6186
  {
6187
    d.type = RIO_SYMBOL_TYPE_DATA;
6188
    d.data = packet[i];
6189
    RIO_portAddSymbol(&stack, d);
6190
  }
6191
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
6192
 
6193
  /* Receive indication from stack that the packet must be retried. */
6194
  c = CreateControlSymbol(STYPE0_PACKET_RETRY, 9, 0, STYPE1_NOP, 0);
6195
  s = RIO_portGetSymbol(&stack);
6196
  TESTEXPR(s.type, c.type);
6197
  TESTEXPR(s.data, c.data);
6198
 
6199
  /******************************************************************************/
6200
  TESTEND;
6201
  /******************************************************************************/
6202
  PrintS("----------------------------------------------------------------------");
6203
  PrintS("Step 3:");
6204
  PrintS("Action: Send a packet when the receiver is in input-retry-stopped.");
6205
  PrintS("Result: The receiver should ignore the new packet.");
6206
  PrintS("----------------------------------------------------------------------");
6207
  /******************************************************************************/
6208
  TESTSTART("TG_riostack-TC2-Step3");
6209
  /******************************************************************************/
6210
 
6211
  /* Resend the packet. */
6212
  packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
6213
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
6214
  for(i = 0; i < packetLength; i++)
6215
  {
6216
    d.type = RIO_SYMBOL_TYPE_DATA;
6217
    d.data = packet[i];
6218
    RIO_portAddSymbol(&stack, d);
6219
  }
6220
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
6221
  s = RIO_portGetSymbol(&stack);
6222
 
6223
  /* Check that nothing is transmitted. */
6224
  TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
6225
 
6226
  /* REMARK: Send other symbols here to check that they are handled as expected... */
6227
 
6228
  /******************************************************************************/
6229
  TESTEND;
6230
  /******************************************************************************/
6231
  PrintS("----------------------------------------------------------------------");
6232
  PrintS("Step 4:");
6233
  PrintS("Action: Send restart-from-retry and resend the previous packet.");
6234
  PrintS("Result: The receiver should leave the input-retry-stopped state and receive ");
6235
  PrintS("        the new frame.");
6236
  PrintS("----------------------------------------------------------------------");
6237
  /******************************************************************************/
6238
  TESTSTART("TG_riostack-TC2-Step4");
6239
  /******************************************************************************/
6240
 
6241
  /* Send restart-from-retry. */
6242
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_RESTART_FROM_RETRY, 0));
6243
 
6244
  /* Check that the transaction id is correct and remove a packet from the inbound
6245
     queue. One entry in the inbound queue will be empty. */
6246
  RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
6247
  TESTEXPR(tid, 1);
6248
  RIO_packetRemove(&stack);
6249
 
6250
  /* Check that the buffer status has changed to show that a buffer is available. */
6251
  s = RIO_portGetSymbol(&stack);
6252
  while(s.type == RIO_SYMBOL_TYPE_IDLE)
6253
  {
6254
    s = RIO_portGetSymbol(&stack);
6255
  }
6256
  c = CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0);
6257
  TESTEXPR(s.type, c.type);
6258
  TESTEXPR(s.data, c.data);
6259
 
6260
  /* Resend the packet and check that it is received. */
6261
  packetLength = createDoorbell(packet, 9, 0, 0, 9, 0);
6262
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
6263
  for(i = 0; i < packetLength; i++)
6264
  {
6265
    d.type = RIO_SYMBOL_TYPE_DATA;
6266
    d.data = packet[i];
6267
    RIO_portAddSymbol(&stack, d);
6268
  }
6269
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
6270
  c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 0, STYPE1_NOP, 0);
6271
  s = RIO_portGetSymbol(&stack);
6272
  TESTEXPR(s.type, c.type);
6273
  TESTEXPR(s.data, c.data);
6274
 
6275
  /******************************************************************************/
6276
  TESTEND;
6277
  /******************************************************************************/
6278
  PrintS("----------------------------------------------------------------------");
6279
  PrintS("Step 5:");
6280
  PrintS("Action: Place receiver in input-retry-stopped state.");
6281
  PrintS("Result: Check that packets may be transmitted normally.");
6282
  PrintS("----------------------------------------------------------------------");
6283
  /******************************************************************************/
6284
  TESTSTART("TG_riostack-TC2-Step5");
6285
  /******************************************************************************/
6286
 
6287
  /* Send another packet and check that the receiver indicates that it should be retried. */
6288
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
6289
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0));
6290
  for(i = 0; i < packetLength; i++)
6291
  {
6292
    d.type = RIO_SYMBOL_TYPE_DATA;
6293
    d.data = packet[i];
6294
    RIO_portAddSymbol(&stack, d);
6295
  }
6296
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0));
6297
  c = CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 0, STYPE1_NOP, 0);
6298
  s = RIO_portGetSymbol(&stack);
6299
  TESTEXPR(s.type, c.type);
6300
  TESTEXPR(s.data, c.data);
6301
 
6302
  /* Send two packets to see that the first acknowledge has been processed. */
6303
  RIO_sendDoorbell(&stack, 0, 2, 0xfeed);
6304
  RIO_sendDoorbell(&stack, 0, 3, 0xdeed);
6305
 
6306
  /* Get the first packet. */
6307
  packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed);
6308
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
6309
  s = RIO_portGetSymbol(&stack);
6310
  TESTEXPR(s.type, c.type);
6311
  TESTEXPR(s.data, c.data);
6312
  for(i = 0; i < packetLength; i++)
6313
  {
6314
    s = RIO_portGetSymbol(&stack);
6315
    d.type = RIO_SYMBOL_TYPE_DATA;
6316
    d.data = packet[i];
6317
    TESTEXPR(s.type, d.type);
6318
    TESTEXPR(s.data, d.data);
6319
  }
6320
 
6321
  /* Get the second packet. */
6322
  packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed);
6323
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
6324
  s = RIO_portGetSymbol(&stack);
6325
  TESTSYMBOL(s, c);
6326
  for(i = 0; i < packetLength; i++)
6327
  {
6328
    s = RIO_portGetSymbol(&stack);
6329
    d.type = RIO_SYMBOL_TYPE_DATA;
6330
    d.data = packet[i];
6331
    TESTEXPR(s.type, d.type);
6332
    TESTEXPR(s.data, d.data);
6333
  }
6334
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
6335
  s = RIO_portGetSymbol(&stack);
6336
  TESTEXPR(s.type, c.type);
6337
  TESTEXPR(s.data, c.data);
6338
 
6339
  /* Indicate the packets must be retransmitted. */
6340
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 2, 1, STYPE1_NOP, 0));
6341
 
6342
  /* Receive confirmation that the packet will be retransmitted. */
6343
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0);
6344
  s = RIO_portGetSymbol(&stack);
6345
  TESTSYMBOL(s, c);
6346
 
6347
  /* Get the retransmission of the first packet. */
6348
  packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed);
6349
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
6350
  s = RIO_portGetSymbol(&stack);
6351
  TESTEXPR(s.type, c.type);
6352
  TESTEXPR(s.data, c.data);
6353
  for(i = 0; i < packetLength; i++)
6354
  {
6355
    s = RIO_portGetSymbol(&stack);
6356
    d.type = RIO_SYMBOL_TYPE_DATA;
6357
    d.data = packet[i];
6358
    TESTEXPR(s.type, d.type);
6359
    TESTEXPR(s.data, d.data);
6360
  }
6361
 
6362
  /* Get the retransmission of the second packet. */
6363
  packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed);
6364
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
6365
  s = RIO_portGetSymbol(&stack);
6366
  TESTSYMBOL(s, c);
6367
  for(i = 0; i < packetLength; i++)
6368
  {
6369
    s = RIO_portGetSymbol(&stack);
6370
    d.type = RIO_SYMBOL_TYPE_DATA;
6371
    d.data = packet[i];
6372
    TESTEXPR(s.type, d.type);
6373
    TESTEXPR(s.data, d.data);
6374
  }
6375
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
6376
  s = RIO_portGetSymbol(&stack);
6377
  TESTEXPR(s.type, c.type);
6378
  TESTEXPR(s.data, c.data);
6379
 
6380
  /* Confirm the reception of the packets. */
6381
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 2, 1, STYPE1_NOP, 0));
6382
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 3, 1, STYPE1_NOP, 0));
6383
 
6384
  /******************************************************************************/
6385
  TESTEND;
6386
  /******************************************************************************/
6387
  PrintS("----------------------------------------------------------------------");
6388
  PrintS("Step 6:");
6389
  PrintS("Action: Send status-control-symbol to show that no packets can be ");
6390
  PrintS("        transmitted.");
6391
  PrintS("Result: No packets should be transmitted.");
6392
  PrintS("----------------------------------------------------------------------");
6393
  /******************************************************************************/
6394
  TESTSTART("TG_riostack-TC2-Step6");
6395
  /******************************************************************************/
6396
 
6397
  /* Send status with bufferStatus set to zero. */
6398
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 0, STYPE1_NOP, 0));
6399
 
6400
  /* Send a packet. */
6401
  RIO_sendDoorbell(&stack, 0, 4, 0xf00d);
6402
 
6403
  /* Check that nothing is transmitted but status-control-symbols. */
6404
  for(i = 0; i < 255; i++)
6405
  {
6406
    s = RIO_portGetSymbol(&stack);
6407
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
6408
  }
6409
  s = RIO_portGetSymbol(&stack);
6410
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_NOP, 0);
6411
  TESTEXPR(s.type, c.type);
6412
  TESTEXPR(s.data, c.data);
6413
 
6414
  /******************************************************************************/
6415
  TESTEND;
6416
  /******************************************************************************/
6417
  PrintS("----------------------------------------------------------------------");
6418
  PrintS("Step 7:");
6419
  PrintS("Action: Indicate free buffers and receive a frame, then request it to be ");
6420
  PrintS("retried.");
6421
  PrintS("Result: The packet should be retransmitted.");
6422
  PrintS("----------------------------------------------------------------------");
6423
  /******************************************************************************/
6424
  TESTSTART("TG_riostack-TC2-Step7");
6425
  /******************************************************************************/
6426
 
6427
  /* Send status with bufferStatus set to available. */
6428
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 1, STYPE1_NOP, 0));
6429
 
6430
  /* Get the packet but request it to be retried. */
6431
  packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d);
6432
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
6433
  s = RIO_portGetSymbol(&stack);
6434
  TESTEXPR(s.type, c.type);
6435
  TESTEXPR(s.data, c.data);
6436
  for(i = 0; i < packetLength; i++)
6437
  {
6438
    s = RIO_portGetSymbol(&stack);
6439
    d.type = RIO_SYMBOL_TYPE_DATA;
6440
    d.data = packet[i];
6441
    TESTEXPR(s.type, d.type);
6442
    TESTEXPR(s.data, d.data);
6443
  }
6444
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
6445
  s = RIO_portGetSymbol(&stack);
6446
  TESTEXPR(s.type, c.type);
6447
  TESTEXPR(s.data, c.data);
6448
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 4, 1, STYPE1_NOP, 0));
6449
 
6450
  /* Check the acknowledge of the retransmission. */
6451
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0);
6452
  s = RIO_portGetSymbol(&stack);
6453
  TESTEXPR(s.type, c.type);
6454
  TESTEXPR(s.data, c.data);
6455
 
6456
  /* Get the packet and acknowledge it. */
6457
  packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d);
6458
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0);
6459
  s = RIO_portGetSymbol(&stack);
6460
  TESTEXPR(s.type, c.type);
6461
  TESTEXPR(s.data, c.data);
6462
  for(i = 0; i < packetLength; i++)
6463
  {
6464
    s = RIO_portGetSymbol(&stack);
6465
    d.type = RIO_SYMBOL_TYPE_DATA;
6466
    d.data = packet[i];
6467
    TESTEXPR(s.type, d.type);
6468
    TESTEXPR(s.data, d.data);
6469
  }
6470
  c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0);
6471
  s = RIO_portGetSymbol(&stack);
6472
  TESTEXPR(s.type, c.type);
6473
  TESTEXPR(s.data, c.data);
6474
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 4, 1, STYPE1_NOP, 0));
6475
 
6476
  /******************************************************************************/
6477
  TESTEND;
6478
  /******************************************************************************/
6479
  PrintS("----------------------------------------------------------------------");
6480
  PrintS("Step 8:");
6481
  PrintS("Action: Read all inbound packets from the reception queue.");
6482
  PrintS("Result: The buffer status should be updated.");
6483
  PrintS("----------------------------------------------------------------------");
6484
  /******************************************************************************/
6485
  TESTSTART("TG_riostack-TC2-Step8");
6486
  /******************************************************************************/
6487
 
6488
  for(j = 0; j < 8; j++)
6489
  {
6490
    RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
6491
    TESTEXPR(tid, j+2);
6492
    RIO_packetRemove(&stack);
6493
 
6494
    for(i = 0; i < 255; i++)
6495
    {
6496
      s = RIO_portGetSymbol(&stack);
6497
      TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
6498
    }
6499
    s = RIO_portGetSymbol(&stack);
6500
    c = CreateControlSymbol(STYPE0_STATUS, 10, j+1, STYPE1_NOP, 0);
6501
    TESTEXPR(s.type, c.type);
6502
    TESTEXPR(s.data, c.data);
6503
  }
6504
 
6505
  /******************************************************************************/
6506
  TESTEND;
6507
  /******************************************************************************/
6508
  PrintS("----------------------------------------------------------------------");
6509
  PrintS("Step 9:");
6510
  PrintS("Action: Send a restart-from-retry to make the receiver leave the ");
6511
  PrintS("        input-retry-stopped state.");
6512
  PrintS("Result: New packets should be received again.");
6513
  PrintS("----------------------------------------------------------------------");
6514
  /******************************************************************************/
6515
  TESTSTART("TG_riostack-TC2-Step9");
6516
  /******************************************************************************/
6517
 
6518
  /* Send restart-from-retry. */
6519
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_RESTART_FROM_RETRY, 0));
6520
 
6521
 
6522
  /******************************************************************************/
6523
  TESTEND;
6524
  /******************************************************************************/
6525
  PrintS("----------------------------------------------------------------------");
6526
  PrintS("TG_riostack-TC3");
6527
  PrintS("Description: Test receiver error handling.");
6528
  PrintS("Requirement: XXXXX");
6529
  PrintS("----------------------------------------------------------------------");
6530
  PrintS("Step 1:");
6531
  PrintS("Action: Send invalid ack id in packet.");
6532
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6533
  PrintS("        should indicate an ackId error.");
6534
  PrintS("----------------------------------------------------------------------");
6535
  /******************************************************************************/
6536
  TESTSTART("TG_riostack-TC3-Step1");
6537
  /******************************************************************************/
6538
 
6539
  /* Send packet with invalid ackId, same as sent previously. */
6540
  packetLength = createDoorbell(packet, 9, 0, 0, 10, 0);
6541
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
6542
  for(i = 0; i < packetLength; i++)
6543
  {
6544
    d.type = RIO_SYMBOL_TYPE_DATA;
6545
    d.data = packet[i];
6546
    RIO_portAddSymbol(&stack, d);
6547
  }
6548
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
6549
 
6550
  /* Check that the packet is not accepted with cause error in ackId. */
6551
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 1, STYPE1_NOP, 0);
6552
  s = RIO_portGetSymbol(&stack);
6553
  TESTEXPR(s.type, c.type);
6554
  TESTEXPR(s.data, c.data);
6555
 
6556
  /* Send a link-request. */
6557
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6558
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6559
 
6560
  /* Check that a link-response is returned. */
6561
  /* Note that the status of the input-port will be reported as ok since a
6562
     link-request has been received. */
6563
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6564
  s = RIO_portGetSymbol(&stack);
6565
  TESTEXPR(s.type, c.type);
6566
  TESTEXPR(s.data, c.data);
6567
 
6568
  /* Check that a status is transmitted directly after the link-response. */
6569
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6570
  s = RIO_portGetSymbol(&stack);
6571
  TESTEXPR(s.type, c.type);
6572
  TESTEXPR(s.data, c.data);
6573
 
6574
  /******************************************************************************/
6575
  TESTEND;
6576
  /******************************************************************************/
6577
  PrintS("----------------------------------------------------------------------");
6578
  PrintS("Step 2:");
6579
  PrintS("Action: Send packet with invalid CRC.");
6580
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6581
  PrintS("        should indicate a CRC error.");
6582
  PrintS("----------------------------------------------------------------------");
6583
  /******************************************************************************/
6584
  TESTSTART("TG_riostack-TC3-Step2");
6585
  /******************************************************************************/
6586
 
6587
  /* Send packet with invalid crc. */
6588
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
6589
  packet[0] ^= 0x00000001;
6590
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
6591
  for(i = 0; i < packetLength; i++)
6592
  {
6593
    d.type = RIO_SYMBOL_TYPE_DATA;
6594
    d.data = packet[i];
6595
    RIO_portAddSymbol(&stack, d);
6596
  }
6597
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
6598
 
6599
  /* Check that the packet is not accepted with cause error in ackId. */
6600
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0);
6601
  s = RIO_portGetSymbol(&stack);
6602
  TESTEXPR(s.type, c.type);
6603
  TESTEXPR(s.data, c.data);
6604
 
6605
  /* Send a link-request. */
6606
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6607
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6608
 
6609
  /* Check that a link-response is returned. */
6610
  /* Note that the status of the input-port will be reported as ok since a
6611
     link-request has been received. */
6612
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6613
  s = RIO_portGetSymbol(&stack);
6614
  TESTEXPR(s.type, c.type);
6615
  TESTEXPR(s.data, c.data);
6616
 
6617
  /* Check that a status is transmitted directly after the link-response. */
6618
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6619
  s = RIO_portGetSymbol(&stack);
6620
  TESTEXPR(s.type, c.type);
6621
  TESTEXPR(s.data, c.data);
6622
 
6623
  /******************************************************************************/
6624
  TESTEND;
6625
  /******************************************************************************/
6626
  PrintS("----------------------------------------------------------------------");
6627
  PrintS("Step 3:");
6628
  PrintS("Action: Send a packet that is too short.");
6629
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6630
  PrintS("        should indicate a packet error.");
6631
  PrintS("----------------------------------------------------------------------");
6632
  /******************************************************************************/
6633
  TESTSTART("TG_riostack-TC3-Step3");
6634
  /******************************************************************************/
6635
 
6636
  /* Send packet with valid ackid and crc but too short. */
6637
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
6638
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
6639
  d.type = RIO_SYMBOL_TYPE_DATA;
6640
  d.data = packet[0];
6641
  RIO_portAddSymbol(&stack, d);
6642
  d.type = RIO_SYMBOL_TYPE_DATA;
6643
  d.data = ((uint32_t) Crc32(packet[0] & 0x07ffffff, 0xffff)) << 16;
6644
  RIO_portAddSymbol(&stack, d);
6645
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
6646
 
6647
  /* Check that the packet is not accepted with cause error in ackId. */
6648
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
6649
  s = RIO_portGetSymbol(&stack);
6650
  TESTEXPR(s.type, c.type);
6651
  TESTEXPR(s.data, c.data);
6652
 
6653
  /* Send a link-request. */
6654
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6655
                                    STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6656
 
6657
  /* Check that a link-response is returned. */
6658
  /* Note that the status of the input-port will be reported as ok since a
6659
     link-request has been received. */
6660
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6661
  s = RIO_portGetSymbol(&stack);
6662
  TESTEXPR(s.type, c.type);
6663
  TESTEXPR(s.data, c.data);
6664
 
6665
  /* Check that a status is transmitted directly after the link-response. */
6666
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6667
  s = RIO_portGetSymbol(&stack);
6668
  TESTEXPR(s.type, c.type);
6669
  TESTEXPR(s.data, c.data);
6670
 
6671
  /******************************************************************************/
6672
  TESTEND;
6673
  /******************************************************************************/
6674
  PrintS("----------------------------------------------------------------------");
6675
  PrintS("Step 4:");
6676
  PrintS("Action: Send a packet that is too long.");
6677
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6678
  PrintS("        should indicate a packet error.");
6679
  PrintS("----------------------------------------------------------------------");
6680
  /******************************************************************************/
6681
  TESTSTART("TG_riostack-TC3-Step4");
6682
  /******************************************************************************/
6683
 
6684
  /* Send packet with too many data symbols and without a end-of-packet. */
6685
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
6686
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0));
6687
  for(i = 0; i < 70; i++)
6688
  {
6689
    d.type = RIO_SYMBOL_TYPE_DATA;
6690
    d.data = packet[i];
6691
    RIO_portAddSymbol(&stack, d);
6692
  }
6693
 
6694
  /* Check that the packet is not accepted with cause error in ackId. */
6695
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
6696
  s = RIO_portGetSymbol(&stack);
6697
  TESTEXPR(s.type, c.type);
6698
  TESTEXPR(s.data, c.data);
6699
 
6700
  /* Send a link-request. */
6701
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6702
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6703
 
6704
  /* Check that a link-response is returned. */
6705
  /* Note that the status of the input-port will be reported as ok since a
6706
     link-request has been received. */
6707
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6708
  s = RIO_portGetSymbol(&stack);
6709
  TESTEXPR(s.type, c.type);
6710
  TESTEXPR(s.data, c.data);
6711
 
6712
  /* Check that a status is transmitted directly after the link-response. */
6713
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6714
  s = RIO_portGetSymbol(&stack);
6715
  TESTEXPR(s.type, c.type);
6716
  TESTEXPR(s.data, c.data);
6717
 
6718
  /******************************************************************************/
6719
  TESTEND;
6720
  /******************************************************************************/
6721
  PrintS("----------------------------------------------------------------------");
6722
  PrintS("Step 5:");
6723
  PrintS("Action: Send a data symbol without starting a packet.");
6724
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6725
  PrintS("        should indicate a packet error.");
6726
  PrintS("----------------------------------------------------------------------");
6727
  /******************************************************************************/
6728
  TESTSTART("TG_riostack-TC3-Step5");
6729
  /******************************************************************************/
6730
 
6731
  /* Send a data symbol. */
6732
  packetLength = createDoorbell(packet, 10, 0, 0, 10, 0);
6733
  d.type = RIO_SYMBOL_TYPE_DATA;
6734
  d.data = packet[0];
6735
  RIO_portAddSymbol(&stack, d);
6736
 
6737
  /* Check that the packet is not accepted with cause error in ackId. */
6738
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
6739
  s = RIO_portGetSymbol(&stack);
6740
  TESTEXPR(s.type, c.type);
6741
  TESTEXPR(s.data, c.data);
6742
 
6743
  /* Send a link-request. */
6744
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6745
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6746
 
6747
  /* Check that a link-response is returned. */
6748
  /* Note that the status of the input-port will be reported as ok since a
6749
     link-request has been received. */
6750
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6751
  s = RIO_portGetSymbol(&stack);
6752
  TESTEXPR(s.type, c.type);
6753
  TESTEXPR(s.data, c.data);
6754
 
6755
  /* Check that a status is transmitted directly after the link-response. */
6756
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6757
  s = RIO_portGetSymbol(&stack);
6758
  TESTEXPR(s.type, c.type);
6759
  TESTEXPR(s.data, c.data);
6760
 
6761
  /******************************************************************************/
6762
  TESTEND;
6763
  /******************************************************************************/
6764
  PrintS("----------------------------------------------------------------------");
6765
  PrintS("Step 6:");
6766
  PrintS("Action: Send end-of-packet without matching start.");
6767
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6768
  PrintS("        should indicate a packet error.");
6769
  PrintS("----------------------------------------------------------------------");
6770
  /******************************************************************************/
6771
  TESTSTART("TG_riostack-TC3-Step6");
6772
  /******************************************************************************/
6773
 
6774
  /* Send end-of-packet. */
6775
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0));
6776
 
6777
  /* Check that the packet is not accepted with cause error in ackId. */
6778
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0);
6779
  s = RIO_portGetSymbol(&stack);
6780
  TESTEXPR(s.type, c.type);
6781
  TESTEXPR(s.data, c.data);
6782
 
6783
  /* Send a link-request. */
6784
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6785
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6786
 
6787
  /* Check that a link-response is returned. */
6788
  /* Note that the status of the input-port will be reported as ok since a
6789
     link-request has been received. */
6790
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6791
  s = RIO_portGetSymbol(&stack);
6792
  TESTEXPR(s.type, c.type);
6793
  TESTEXPR(s.data, c.data);
6794
 
6795
  /* Check that a status is transmitted directly after the link-response. */
6796
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6797
  s = RIO_portGetSymbol(&stack);
6798
  TESTEXPR(s.type, c.type);
6799
  TESTEXPR(s.data, c.data);
6800
 
6801
  /******************************************************************************/
6802
  TESTEND;
6803
  /******************************************************************************/
6804
  PrintS("----------------------------------------------------------------------");
6805
  PrintS("Step 7:");
6806
  PrintS("Action: Send a symbol indicating a codec error.");
6807
  PrintS("Result: Input-error-stopped state should be entered and link-response ");
6808
  PrintS("        should indicate a symbol error.");
6809
  PrintS("----------------------------------------------------------------------");
6810
  /******************************************************************************/
6811
  TESTSTART("TG_riostack-TC3-Step7");
6812
  /******************************************************************************/
6813
 
6814
  /* Send error-symbol. */
6815
  s.type = RIO_SYMBOL_TYPE_ERROR;
6816
  RIO_portAddSymbol(&stack, s);
6817
 
6818
  /* Check that the packet is not accepted with cause error in ackId. */
6819
  c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 5, STYPE1_NOP, 0);
6820
  s = RIO_portGetSymbol(&stack);
6821
  TESTEXPR(s.type, c.type);
6822
  TESTEXPR(s.data, c.data);
6823
 
6824
  /* Send a link-request. */
6825
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1,
6826
                                            STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS));
6827
 
6828
  /* Check that a link-response is returned. */
6829
  /* Note that the status of the input-port will be reported as ok since a
6830
     link-request has been received. */
6831
  c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0);
6832
  s = RIO_portGetSymbol(&stack);
6833
  TESTEXPR(s.type, c.type);
6834
  TESTEXPR(s.data, c.data);
6835
 
6836
  /* Check that a status is transmitted directly after the link-response. */
6837
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0);
6838
  s = RIO_portGetSymbol(&stack);
6839
  TESTEXPR(s.type, c.type);
6840
  TESTEXPR(s.data, c.data);
6841
 
6842
  /******************************************************************************/
6843
  TESTEND;
6844
  /******************************************************************************/
6845
  PrintS("----------------------------------------------------------------------");
6846
  PrintS("TG_riostack-TC4");
6847
  PrintS("Description: Test transmitter error handling.");
6848
  PrintS("Requirement: XXXXX");
6849
  PrintS("----------------------------------------------------------------------");
6850
  PrintS("Step 1:");
6851
  PrintS("Action: Send acknowledge for a frame that has not been transmitted and ");
6852
  PrintS("        without any frame being expected.");
6853
  PrintS("Result: The transmitter should enter output-error-stopped and send ");
6854
  PrintS("        link-request.");
6855
  PrintS("----------------------------------------------------------------------");
6856
  /******************************************************************************/
6857
  TESTSTART("TG_riostack-TC4-Step1");
6858
  /******************************************************************************/
6859
 
6860
  /* Packet acknowledge for unsent frame. */
6861
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
6862
 
6863
  /* Check that a link-request is received as the transmitter enters
6864
     output-error-stopped state. */
6865
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
6866
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
6867
  s = RIO_portGetSymbol(&stack);
6868
  TESTEXPR(s.type, c.type);
6869
  TESTEXPR(s.data, c.data);
6870
 
6871
  /* Send link-response with expected ackId. */
6872
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 5, 16, STYPE1_NOP, 0));
6873
 
6874
  /* Send a status directly afterwards. */
6875
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_NOP, 0));
6876
 
6877
  /* Check that packets are relayed after this. */
6878
  RIO_sendDoorbell(&stack, 0, 5, 2);
6879
  packetLength = createDoorbell(packet, 5, 0, 0xffff, 5, 2);
6880
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
6881
  s = RIO_portGetSymbol(&stack);
6882
  TESTEXPR(s.type, c.type);
6883
  TESTEXPR(s.data, c.data);
6884
  for(i = 0; i < packetLength; i++)
6885
  {
6886
    s = RIO_portGetSymbol(&stack);
6887
    d.type = RIO_SYMBOL_TYPE_DATA;
6888
    d.data = packet[i];
6889
    TESTEXPR(s.type, d.type);
6890
    TESTEXPR(s.data, d.data);
6891
  }
6892
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
6893
  s = RIO_portGetSymbol(&stack);
6894
  TESTEXPR(s.type, c.type);
6895
  TESTEXPR(s.data, c.data);
6896
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
6897
 
6898
  /******************************************************************************/
6899
  TESTEND;
6900
  /******************************************************************************/
6901
  PrintS("----------------------------------------------------------------------");
6902
  PrintS("Step 2:");
6903
  PrintS("Action: Send a packet and send acknowledge for a previous frame. Then send ");
6904
  PrintS("        a link-response indicating that the packet was received (accepted ");
6905
  PrintS("        but reply corrupted).");
6906
  PrintS("Result: The transmitter should enter output-error-stopped state and send ");
6907
  PrintS("        link-request and proceed with the next packet.");
6908
  PrintS("----------------------------------------------------------------------");
6909
  /******************************************************************************/
6910
  TESTSTART("TG_riostack-TC4-Step2");
6911
  /******************************************************************************/
6912
 
6913
  /* Send a packet. */
6914
  RIO_sendDoorbell(&stack, 0, 6, 2);
6915
  packetLength = createDoorbell(packet, 6, 0, 0xffff, 6, 2);
6916
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
6917
  s = RIO_portGetSymbol(&stack);
6918
  TESTEXPR(s.type, c.type);
6919
  TESTEXPR(s.data, c.data);
6920
  for(i = 0; i < packetLength; i++)
6921
  {
6922
    s = RIO_portGetSymbol(&stack);
6923
    d.type = RIO_SYMBOL_TYPE_DATA;
6924
    d.data = packet[i];
6925
    TESTEXPR(s.type, d.type);
6926
    TESTEXPR(s.data, d.data);
6927
  }
6928
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
6929
  s = RIO_portGetSymbol(&stack);
6930
  TESTEXPR(s.type, c.type);
6931
  TESTEXPR(s.data, c.data);
6932
 
6933
  /* Send acknowledge for another packet. */
6934
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0));
6935
 
6936
  /* Check that a link-request is received as the transmitter enters
6937
     output-error-stopped state. */
6938
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
6939
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
6940
  s = RIO_portGetSymbol(&stack);
6941
  TESTEXPR(s.type, c.type);
6942
  TESTEXPR(s.data, c.data);
6943
 
6944
  /* Send link-response with expected ackId. */
6945
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0));
6946
 
6947
  /* Send a status directly afterwards. */
6948
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0));
6949
 
6950
  /******************************************************************************/
6951
  TESTEND;
6952
  /******************************************************************************/
6953
  PrintS("----------------------------------------------------------------------");
6954
  PrintS("Step 3:");
6955
  PrintS("Action: Send a packet and let the packet-accepted time out. Then send a ");
6956
  PrintS("        link-response indicating that the packet was not received.");
6957
  PrintS("Result: The transmitter should enter output-error-stopped state, send a");
6958
  PrintS("        link-request and then resend the packet.");
6959
  PrintS("----------------------------------------------------------------------");
6960
  /******************************************************************************/
6961
  TESTSTART("TG_riostack-TC4-Step3");
6962
  /******************************************************************************/
6963
 
6964
  /* Set the time at frame transmission. */
6965
  RIO_portSetTime(&stack, 2);
6966
 
6967
  /* Send an output packet. */
6968
  RIO_sendDoorbell(&stack, 0, 7, 2);
6969
 
6970
  /* Receive the transmitted packet. */
6971
  packetLength = createDoorbell(packet, 7, 0, 0xffff, 7, 2);
6972
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
6973
  s = RIO_portGetSymbol(&stack);
6974
  TESTEXPR(s.type, c.type);
6975
  TESTEXPR(s.data, c.data);
6976
  for(i = 0; i < packetLength; i++)
6977
  {
6978
    s = RIO_portGetSymbol(&stack);
6979
    d.type = RIO_SYMBOL_TYPE_DATA;
6980
    d.data = packet[i];
6981
    TESTEXPR(s.type, d.type);
6982
    TESTEXPR(s.data, d.data);
6983
  }
6984
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
6985
  s = RIO_portGetSymbol(&stack);
6986
  TESTEXPR(s.type, c.type);
6987
  TESTEXPR(s.data, c.data);
6988
 
6989
  /* Indicate that time has passed to trigger a timeout. */
6990
  RIO_portSetTime(&stack, 3);
6991
 
6992
  /* Check that a link-request is received as the transmitter enters
6993
     output-error-stopped state. */
6994
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
6995
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
6996
  s = RIO_portGetSymbol(&stack);
6997
  TESTEXPR(s.type, c.type);
6998
  TESTEXPR(s.data, c.data);
6999
 
7000
  /* Send link-response with expected ackId. */
7001
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0));
7002
 
7003
  /* Send a status directly afterwards. */
7004
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0));
7005
 
7006
  /* Receive retransmitted packet. */
7007
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7008
  s = RIO_portGetSymbol(&stack);
7009
  TESTEXPR(s.type, c.type);
7010
  TESTEXPR(s.data, c.data);
7011
  for(i = 0; i < packetLength; i++)
7012
  {
7013
    s = RIO_portGetSymbol(&stack);
7014
    d.type = RIO_SYMBOL_TYPE_DATA;
7015
    d.data = packet[i];
7016
    TESTEXPR(s.type, d.type);
7017
    TESTEXPR(s.data, d.data);
7018
  }
7019
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
7020
  s = RIO_portGetSymbol(&stack);
7021
  TESTEXPR(s.type, c.type);
7022
  TESTEXPR(s.data, c.data);
7023
 
7024
  /* Send acknowledge for the retransmitted packet. */
7025
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 7, 1, STYPE1_NOP, 0));
7026
 
7027
  /******************************************************************************/
7028
  TESTEND;
7029
  /******************************************************************************/
7030
  PrintS("----------------------------------------------------------------------");
7031
  PrintS("Step 4:");
7032
  PrintS("Action: Send a packet and then indicate that the packet was not accepted. ");
7033
  PrintS("        Then send a link-response indicating that the packet was not received.");
7034
  PrintS("Result: The transmitter should enter output-error-stopped state, send a");
7035
  PrintS("        link-request and then resend the packet.");
7036
  PrintS("----------------------------------------------------------------------");
7037
  /******************************************************************************/
7038
  TESTSTART("TG_riostack-TC4-Step4");
7039
  /******************************************************************************/
7040
 
7041
  /* Send an output packet. */
7042
  RIO_sendDoorbell(&stack, 0, 8, 3);
7043
 
7044
  /* Receive the transmitted packet. */
7045
  packetLength = createDoorbell(packet, 8, 0, 0xffff, 8, 3);
7046
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7047
  s = RIO_portGetSymbol(&stack);
7048
  TESTEXPR(s.type, c.type);
7049
  TESTEXPR(s.data, c.data);
7050
  for(i = 0; i < packetLength; i++)
7051
  {
7052
    s = RIO_portGetSymbol(&stack);
7053
    d.type = RIO_SYMBOL_TYPE_DATA;
7054
    d.data = packet[i];
7055
    TESTEXPR(s.type, d.type);
7056
    TESTEXPR(s.data, d.data);
7057
  }
7058
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
7059
  s = RIO_portGetSymbol(&stack);
7060
  TESTEXPR(s.type, c.type);
7061
  TESTEXPR(s.data, c.data);
7062
 
7063
  /* Send packet-not-accepted indicating CRC error. */
7064
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0));
7065
 
7066
  /* Check that a link-request is received as the transmitter enters
7067
     output-error-stopped state. */
7068
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
7069
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
7070
  s = RIO_portGetSymbol(&stack);
7071
  TESTEXPR(s.type, c.type);
7072
  TESTEXPR(s.data, c.data);
7073
 
7074
  /* Send link-response with expected ackId. */
7075
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 8, 16, STYPE1_NOP, 0));
7076
 
7077
  /* Send a status directly afterwards. */
7078
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 8, 1, STYPE1_NOP, 0));
7079
 
7080
  /* Receive retransmitted packet. */
7081
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7082
  s = RIO_portGetSymbol(&stack);
7083
  TESTEXPR(s.type, c.type);
7084
  TESTEXPR(s.data, c.data);
7085
  for(i = 0; i < packetLength; i++)
7086
  {
7087
    s = RIO_portGetSymbol(&stack);
7088
    d.type = RIO_SYMBOL_TYPE_DATA;
7089
    d.data = packet[i];
7090
    TESTEXPR(s.type, d.type);
7091
    TESTEXPR(s.data, d.data);
7092
  }
7093
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
7094
  s = RIO_portGetSymbol(&stack);
7095
  TESTEXPR(s.type, c.type);
7096
  TESTEXPR(s.data, c.data);
7097
 
7098
  /* Send acknowledge for the retransmitted packet. */
7099
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 8, 1, STYPE1_NOP, 0));
7100
 
7101
  /******************************************************************************/
7102
  TESTEND;
7103
  /******************************************************************************/
7104
  PrintS("----------------------------------------------------------------------");
7105
  PrintS("Step 5:");
7106
  PrintS("Action: Send a packet-retry for an unexpected packet. Then send a");
7107
  PrintS("        link-response indicating the expected ackId and a normal packet.");
7108
  PrintS("Result: The transmitter should enter output-error-stopped state, send a");
7109
  PrintS("        link-request and then the normal packet.");
7110
  PrintS("----------------------------------------------------------------------");
7111
  /******************************************************************************/
7112
  TESTSTART("TG_riostack-TC4-Step5");
7113
  /******************************************************************************/
7114
 
7115
  /* Send packet-retry indicating that a packet should be retransmitted. */
7116
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 8, 1, STYPE1_NOP, 0));
7117
 
7118
  /* Check that a link-request is received as the transmitter enters
7119
     output-error-stopped state. */
7120
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8,
7121
                          STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS);
7122
  s = RIO_portGetSymbol(&stack);
7123
  TESTEXPR(s.type, c.type);
7124
  TESTEXPR(s.data, c.data);
7125
 
7126
  /* Send link-response with expected ackId. */
7127
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 9, 16, STYPE1_NOP, 0));
7128
 
7129
  /* Send a status directly afterwards. */
7130
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0));
7131
 
7132
  /* Send an output packet. */
7133
  RIO_sendDoorbell(&stack, 0, 9, 4);
7134
 
7135
  /* Receive retransmitted packet. */
7136
  packetLength = createDoorbell(packet, 9, 0, 0xffff, 9, 4);
7137
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7138
  s = RIO_portGetSymbol(&stack);
7139
  TESTEXPR(s.type, c.type);
7140
  TESTEXPR(s.data, c.data);
7141
  for(i = 0; i < packetLength; i++)
7142
  {
7143
    s = RIO_portGetSymbol(&stack);
7144
    d.type = RIO_SYMBOL_TYPE_DATA;
7145
    d.data = packet[i];
7146
    TESTEXPR(s.type, d.type);
7147
    TESTEXPR(s.data, d.data);
7148
  }
7149
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
7150
  s = RIO_portGetSymbol(&stack);
7151
  TESTEXPR(s.type, c.type);
7152
  TESTEXPR(s.data, c.data);
7153
 
7154
  /* Send acknowledge for the retransmitted packet. */
7155
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 1, STYPE1_NOP, 0));
7156
 
7157
  /******************************************************************************/
7158
  TESTEND;
7159
 /******************************************************************************/
7160
  PrintS("----------------------------------------------------------------------");
7161
  PrintS("Step 6:");
7162
  PrintS("Action: Fill outbound queue with packets, then check retransmission when ");
7163
  PrintS("        packet-retry is encountered. ");
7164
  PrintS("Result: Packets should be retried until packet-accepted is received.");
7165
  PrintS("----------------------------------------------------------------------");
7166
  /******************************************************************************/
7167
  TESTSTART("TG_riostack-TC4-Step6");
7168
  /******************************************************************************/
7169
 
7170
  TESTCOND(RIO_sendAvailable(&stack, 0));
7171
  RIO_sendDoorbell(&stack, 0, 20, 0xbabe);
7172
 
7173
  TESTCOND(RIO_sendAvailable(&stack, 0));
7174
  RIO_sendDoorbell(&stack, 0, 21, 0xbabe);
7175
 
7176
  TESTCOND(RIO_sendAvailable(&stack, 0));
7177
  RIO_sendDoorbell(&stack, 0, 22, 0xbabe);
7178
 
7179
  TESTCOND(RIO_sendAvailable(&stack, 0));
7180
  RIO_sendDoorbell(&stack, 0, 23, 0xbabe);
7181
 
7182
  TESTCOND(RIO_sendAvailable(&stack, 0));
7183
  RIO_sendDoorbell(&stack, 0, 24, 0xbabe);
7184
 
7185
  TESTCOND(RIO_sendAvailable(&stack, 0));
7186
  RIO_sendDoorbell(&stack, 0, 25, 0xbabe);
7187
 
7188
  TESTCOND(RIO_sendAvailable(&stack, 0));
7189
  RIO_sendDoorbell(&stack, 0, 26, 0xbabe);
7190
 
7191
  TESTCOND(RIO_sendAvailable(&stack, 0));
7192
  RIO_sendDoorbell(&stack, 0, 27, 0xbabe);
7193
 
7194
  TESTCOND(!RIO_sendAvailable(&stack, 0));
7195
 
7196
  /* Receive transmitted packet. */
7197
  packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe);
7198
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7199
  s = RIO_portGetSymbol(&stack);
7200
  TESTEXPR(s.type, c.type);
7201
  TESTEXPR(s.data, c.data);
7202
  for(i = 0; i < packetLength; i++)
7203
  {
7204
    s = RIO_portGetSymbol(&stack);
7205
    d.type = RIO_SYMBOL_TYPE_DATA;
7206
    d.data = packet[i];
7207
    TESTEXPR(s.type, d.type);
7208
    TESTEXPR(s.data, d.data);
7209
  }
7210
  packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe);
7211
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7212
  s = RIO_portGetSymbol(&stack);
7213
  TESTEXPR(s.type, c.type);
7214
  TESTEXPR(s.data, c.data);
7215
  for(i = 0; i < packetLength; i++)
7216
  {
7217
    s = RIO_portGetSymbol(&stack);
7218
    d.type = RIO_SYMBOL_TYPE_DATA;
7219
    d.data = packet[i];
7220
    TESTEXPR(s.type, d.type);
7221
    TESTEXPR(s.data, d.data);
7222
  }
7223
  packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe);
7224
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7225
  s = RIO_portGetSymbol(&stack);
7226
  TESTEXPR(s.type, c.type);
7227
  TESTEXPR(s.data, c.data);
7228
  for(i = 0; i < packetLength; i++)
7229
  {
7230
    s = RIO_portGetSymbol(&stack);
7231
    d.type = RIO_SYMBOL_TYPE_DATA;
7232
    d.data = packet[i];
7233
    TESTEXPR(s.type, d.type);
7234
    TESTEXPR(s.data, d.data);
7235
  }
7236
  packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe);
7237
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7238
  s = RIO_portGetSymbol(&stack);
7239
  TESTEXPR(s.type, c.type);
7240
  TESTEXPR(s.data, c.data);
7241
  for(i = 0; i < packetLength; i++)
7242
  {
7243
    s = RIO_portGetSymbol(&stack);
7244
    d.type = RIO_SYMBOL_TYPE_DATA;
7245
    d.data = packet[i];
7246
    TESTEXPR(s.type, d.type);
7247
    TESTEXPR(s.data, d.data);
7248
  }
7249
  packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe);
7250
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7251
  s = RIO_portGetSymbol(&stack);
7252
  TESTEXPR(s.type, c.type);
7253
  TESTEXPR(s.data, c.data);
7254
  for(i = 0; i < packetLength; i++)
7255
  {
7256
    s = RIO_portGetSymbol(&stack);
7257
    d.type = RIO_SYMBOL_TYPE_DATA;
7258
    d.data = packet[i];
7259
    TESTEXPR(s.type, d.type);
7260
    TESTEXPR(s.data, d.data);
7261
  }
7262
  packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe);
7263
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7264
  s = RIO_portGetSymbol(&stack);
7265
  TESTEXPR(s.type, c.type);
7266
  TESTEXPR(s.data, c.data);
7267
  for(i = 0; i < packetLength; i++)
7268
  {
7269
    s = RIO_portGetSymbol(&stack);
7270
    d.type = RIO_SYMBOL_TYPE_DATA;
7271
    d.data = packet[i];
7272
    TESTEXPR(s.type, d.type);
7273
    TESTEXPR(s.data, d.data);
7274
  }
7275
  packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe);
7276
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7277
  s = RIO_portGetSymbol(&stack);
7278
  TESTEXPR(s.type, c.type);
7279
  TESTEXPR(s.data, c.data);
7280
  for(i = 0; i < packetLength; i++)
7281
  {
7282
    s = RIO_portGetSymbol(&stack);
7283
    d.type = RIO_SYMBOL_TYPE_DATA;
7284
    d.data = packet[i];
7285
    TESTEXPR(s.type, d.type);
7286
    TESTEXPR(s.data, d.data);
7287
  }
7288
  packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe);
7289
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7290
  s = RIO_portGetSymbol(&stack);
7291
  TESTEXPR(s.type, c.type);
7292
  TESTEXPR(s.data, c.data);
7293
  for(i = 0; i < packetLength; i++)
7294
  {
7295
    s = RIO_portGetSymbol(&stack);
7296
    d.type = RIO_SYMBOL_TYPE_DATA;
7297
    d.data = packet[i];
7298
    TESTEXPR(s.type, d.type);
7299
    TESTEXPR(s.data, d.data);
7300
  }
7301
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
7302
  s = RIO_portGetSymbol(&stack);
7303
  TESTEXPR(s.type, c.type);
7304
  TESTEXPR(s.data, c.data);
7305
 
7306
  for(i = 0; i < 10; i++)
7307
  {
7308
    s = RIO_portGetSymbol(&stack);
7309
    TESTEXPR(s.type, RIO_SYMBOL_TYPE_IDLE);
7310
  }
7311
 
7312
  /* Request retransmission. */
7313
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 1, STYPE1_NOP, 0));
7314
 
7315
  /* Acknowledge retransmission. */
7316
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_RESTART_FROM_RETRY, 0);
7317
  s = RIO_portGetSymbol(&stack);
7318
  TESTEXPR(s.type, c.type);
7319
  TESTEXPR(s.data, c.data);
7320
 
7321
  /* Check retransmitted packets. */
7322
  packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe);
7323
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7324
  s = RIO_portGetSymbol(&stack);
7325
  TESTEXPR(s.type, c.type);
7326
  TESTEXPR(s.data, c.data);
7327
  for(i = 0; i < packetLength; i++)
7328
  {
7329
    s = RIO_portGetSymbol(&stack);
7330
    d.type = RIO_SYMBOL_TYPE_DATA;
7331
    d.data = packet[i];
7332
    TESTEXPR(s.type, d.type);
7333
    TESTEXPR(s.data, d.data);
7334
  }
7335
  packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe);
7336
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7337
  s = RIO_portGetSymbol(&stack);
7338
  TESTEXPR(s.type, c.type);
7339
  TESTEXPR(s.data, c.data);
7340
  for(i = 0; i < packetLength; i++)
7341
  {
7342
    s = RIO_portGetSymbol(&stack);
7343
    d.type = RIO_SYMBOL_TYPE_DATA;
7344
    d.data = packet[i];
7345
    TESTEXPR(s.type, d.type);
7346
    TESTEXPR(s.data, d.data);
7347
  }
7348
  packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe);
7349
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7350
  s = RIO_portGetSymbol(&stack);
7351
  TESTEXPR(s.type, c.type);
7352
  TESTEXPR(s.data, c.data);
7353
  for(i = 0; i < packetLength; i++)
7354
  {
7355
    s = RIO_portGetSymbol(&stack);
7356
    d.type = RIO_SYMBOL_TYPE_DATA;
7357
    d.data = packet[i];
7358
    TESTEXPR(s.type, d.type);
7359
    TESTEXPR(s.data, d.data);
7360
  }
7361
 
7362
  /* Acknowledge. */
7363
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 10, 1, STYPE1_NOP, 0));
7364
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 11, 1, STYPE1_NOP, 0));
7365
 
7366
  packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe);
7367
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7368
  s = RIO_portGetSymbol(&stack);
7369
  TESTEXPR(s.type, c.type);
7370
  TESTEXPR(s.data, c.data);
7371
  for(i = 0; i < packetLength; i++)
7372
  {
7373
    s = RIO_portGetSymbol(&stack);
7374
    d.type = RIO_SYMBOL_TYPE_DATA;
7375
    d.data = packet[i];
7376
    TESTEXPR(s.type, d.type);
7377
    TESTEXPR(s.data, d.data);
7378
  }
7379
  packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe);
7380
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7381
  s = RIO_portGetSymbol(&stack);
7382
  TESTEXPR(s.type, c.type);
7383
  TESTEXPR(s.data, c.data);
7384
  for(i = 0; i < packetLength; i++)
7385
  {
7386
    s = RIO_portGetSymbol(&stack);
7387
    d.type = RIO_SYMBOL_TYPE_DATA;
7388
    d.data = packet[i];
7389
    TESTEXPR(s.type, d.type);
7390
    TESTEXPR(s.data, d.data);
7391
  }
7392
 
7393
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 12, 1, STYPE1_NOP, 0));
7394
 
7395
  packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe);
7396
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7397
  s = RIO_portGetSymbol(&stack);
7398
  TESTEXPR(s.type, c.type);
7399
  TESTEXPR(s.data, c.data);
7400
  for(i = 0; i < packetLength; i++)
7401
  {
7402
    s = RIO_portGetSymbol(&stack);
7403
    d.type = RIO_SYMBOL_TYPE_DATA;
7404
    d.data = packet[i];
7405
    TESTEXPR(s.type, d.type);
7406
    TESTEXPR(s.data, d.data);
7407
  }
7408
 
7409
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 13, 1, STYPE1_NOP, 0));
7410
 
7411
  packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe);
7412
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7413
  s = RIO_portGetSymbol(&stack);
7414
  TESTEXPR(s.type, c.type);
7415
  TESTEXPR(s.data, c.data);
7416
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 14, 1, STYPE1_NOP, 0));
7417
  for(i = 0; i < packetLength; i++)
7418
  {
7419
    s = RIO_portGetSymbol(&stack);
7420
    d.type = RIO_SYMBOL_TYPE_DATA;
7421
    d.data = packet[i];
7422
    TESTEXPR(s.type, d.type);
7423
    TESTEXPR(s.data, d.data);
7424
  }
7425
  packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe);
7426
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0);
7427
  s = RIO_portGetSymbol(&stack);
7428
  TESTEXPR(s.type, c.type);
7429
  TESTEXPR(s.data, c.data);
7430
  for(i = 0; i < packetLength; i++)
7431
  {
7432
    s = RIO_portGetSymbol(&stack);
7433
    d.type = RIO_SYMBOL_TYPE_DATA;
7434
    d.data = packet[i];
7435
    TESTEXPR(s.type, d.type);
7436
    TESTEXPR(s.data, d.data);
7437
  }
7438
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 15, 1, STYPE1_NOP, 0));
7439
  c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0);
7440
  s = RIO_portGetSymbol(&stack);
7441
  TESTEXPR(s.type, c.type);
7442
  TESTEXPR(s.data, c.data);
7443
 
7444
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 16, 1, STYPE1_NOP, 0));
7445
  RIO_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 17, 1, STYPE1_NOP, 0));
7446
 
7447
 
7448
  /*************************************************************************
7449
   * Reset ackIds to be able to use the stack in loopback for the testcases
7450
   * below.
7451
   *************************************************************************/
7452
 
7453
  stack.rxAckId = 0;
7454
  stack.rxAckIdAcked = 0;
7455
  stack.txAckId = 0;
7456
  stack.txAckIdWindow = 0;
7457
 
7458
  /******************************************************************************/
7459
  TESTEND;
7460
  /******************************************************************************/
7461
  PrintS("----------------------------------------------------------------------");
7462
  PrintS("TG_riostack-TC5");
7463
  PrintS("Description: Test MAINTENANCE-READ-REQUEST, MAINTENANCE-READ-RESPONSE,");
7464
  PrintS("             MAINTENANCE-WRITE-REQUEST and MAINTENANCE-WRITE-RESPONSE packets.");
7465
  PrintS("Requirement: XXXXX");
7466
  PrintS("----------------------------------------------------------------------");
7467
  PrintS("Step 1:");
7468
  PrintS("Action: Send two read requests to read identity and address of stack.");
7469
  PrintS("Result: The identity and address defined at RIO_open should be returned.");
7470
  PrintS("----------------------------------------------------------------------");
7471
  /******************************************************************************/
7472
  TESTSTART("TG_riostack-TC5-Step1");
7473
  /******************************************************************************/
7474
 
7475
  /* Send two read requests. */
7476
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 10, 0, 0x00000000);
7477
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 11, 0, 0x00000060);
7478
 
7479
  TESTEXPR(RIO_outboundQueueLength(&stack), 2);
7480
 
7481
  while(RIO_inboundQueueLength(&stack) != 2)
7482
  {
7483
    s = RIO_portGetSymbol(&stack);
7484
    RIO_portAddSymbol(&stack, s);
7485
  }
7486
 
7487
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7488
  TESTEXPR(srcid, 0xffff);
7489
  TESTEXPR(tid, 10);
7490
  TESTEXPR(hop, 0xff);
7491
  TESTEXPR(data, 0x0000b03b);
7492
  RIO_packetRemove(&stack);
7493
 
7494
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7495
  TESTEXPR(srcid, 0xffff);
7496
  TESTEXPR(tid, 11);
7497
  TESTEXPR(hop, 0xff);
7498
  TESTEXPR(data, 0x0000ffff);
7499
  RIO_packetRemove(&stack);
7500
 
7501
  /******************************************************************************/
7502
  TESTEND;
7503
  /******************************************************************************/
7504
  PrintS("----------------------------------------------------------------------");
7505
  PrintS("Step 2:");
7506
  PrintS("Action: Send a write requests to write base device id of the stack.");
7507
  PrintS("Result: The identity and address defined at RIO_open should be returned.");
7508
  PrintS("----------------------------------------------------------------------");
7509
  /******************************************************************************/
7510
  TESTSTART("TG_riostack-TC5-Step2");
7511
  /******************************************************************************/
7512
 
7513
  /* Write base device id. */
7514
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 12, 0, 0x00000060, 0xdead);
7515
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
7516
  {
7517
    s = RIO_portGetSymbol(&stack);
7518
    RIO_portAddSymbol(&stack, s);
7519
  }
7520
 
7521
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
7522
  TESTEXPR(srcid, 0xdead);
7523
  TESTEXPR(tid, 12);
7524
  TESTEXPR(hop, 0xff);
7525
  RIO_packetRemove(&stack);
7526
 
7527
  /* Read back the written base device id. */
7528
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 14, 0, 0x00000060);
7529
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_READ_RESPONSE)
7530
  {
7531
    s = RIO_portGetSymbol(&stack);
7532
    RIO_portAddSymbol(&stack, s);
7533
  }
7534
 
7535
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7536
  TESTEXPR(srcid, 0xdead);
7537
  TESTEXPR(tid, 14);
7538
  TESTEXPR(hop, 0xff);
7539
  TESTEXPR(data, 0x0000dead);
7540
  RIO_packetRemove(&stack);
7541
 
7542
  /******************************************************************************/
7543
  TESTEND;
7544
  /******************************************************************************/
7545
  PrintS("----------------------------------------------------------------------");
7546
  PrintS("Step 3:");
7547
  PrintS("Action: Send a write requests to write to the implementation defined ");
7548
  PrintS("        configuration space of the stack.");
7549
  PrintS("Result: The same data should be returned.");
7550
  PrintS("----------------------------------------------------------------------");
7551
  /******************************************************************************/
7552
  TESTSTART("TG_riostack-TC5-Step3");
7553
  /******************************************************************************/
7554
 
7555
  /* Write to implementation defined space. */
7556
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 14, 0, 0x00010004, 0x01020304);
7557
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 15, 0, 0x00010008, 0xc0debabe);
7558
  RIO_sendMaintenanceWriteRequest(&stack, 0xffff, 16, 0, 0x0001000c, 0x05060708);
7559
 
7560
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
7561
  {
7562
    s = RIO_portGetSymbol(&stack);
7563
    RIO_portAddSymbol(&stack, s);
7564
  }
7565
 
7566
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
7567
  TESTEXPR(srcid, 0xdead);
7568
  TESTEXPR(tid, 14);
7569
  TESTEXPR(hop, 0xff);
7570
  RIO_packetRemove(&stack);
7571
 
7572
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
7573
  {
7574
    s = RIO_portGetSymbol(&stack);
7575
    RIO_portAddSymbol(&stack, s);
7576
  }
7577
 
7578
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
7579
  TESTEXPR(srcid, 0xdead);
7580
  TESTEXPR(tid, 15);
7581
  TESTEXPR(hop, 0xff);
7582
  RIO_packetRemove(&stack);
7583
 
7584
  while(RIO_eventPoll(&stack) != RIO_EVENT_MAINT_WRITE_RESPONSE)
7585
  {
7586
    s = RIO_portGetSymbol(&stack);
7587
    RIO_portAddSymbol(&stack, s);
7588
  }
7589
 
7590
  RIO_receiveMaintenanceWriteResponse(&stack, &srcid, &tid, &hop);
7591
  TESTEXPR(srcid, 0xdead);
7592
  TESTEXPR(tid, 16);
7593
  TESTEXPR(hop, 0xff);
7594
  RIO_packetRemove(&stack);
7595
 
7596
  /* Read from implementation defined space. */
7597
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 14, 0, 0x00010000);
7598
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 15, 0, 0x00010004);
7599
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 16, 0, 0x00010008);
7600
  RIO_sendMaintenanceReadRequest(&stack, 0xffff, 17, 0, 0x0001000c);
7601
 
7602
  while(RIO_inboundQueueLength(&stack) != 4)
7603
  {
7604
    s = RIO_portGetSymbol(&stack);
7605
    RIO_portAddSymbol(&stack, s);
7606
  }
7607
 
7608
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7609
  TESTEXPR(srcid, 0xdead);
7610
  TESTEXPR(tid, 14);
7611
  TESTEXPR(hop, 0xff);
7612
  TESTEXPR(data, 0x80000006);
7613
  RIO_packetRemove(&stack);
7614
 
7615
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7616
  TESTEXPR(srcid, 0xdead);
7617
  TESTEXPR(tid, 15);
7618
  TESTEXPR(hop, 0xff);
7619
  TESTEXPR(data, 0x00a100a2);
7620
  RIO_packetRemove(&stack);
7621
 
7622
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7623
  TESTEXPR(srcid, 0xdead);
7624
  TESTEXPR(tid, 16);
7625
  TESTEXPR(hop, 0xff);
7626
  TESTEXPR(data, 0xc0debabe);
7627
  RIO_packetRemove(&stack);
7628
 
7629
  RIO_receiveMaintenanceReadResponse(&stack, &srcid, &tid, &hop, &data);
7630
  TESTEXPR(srcid, 0xdead);
7631
  TESTEXPR(tid, 17);
7632
  TESTEXPR(hop, 0xff);
7633
  TESTEXPR(data, 0x00000000);
7634
  RIO_packetRemove(&stack);
7635
 
7636
  /******************************************************************************/
7637
  TESTEND;
7638
  /******************************************************************************/
7639
  PrintS("----------------------------------------------------------------------");
7640
  PrintS("TG_riostack-TC6");
7641
  PrintS("Description: Test NREAD packets.");
7642
  PrintS("Requirement: XXXXX");
7643
  PrintS("----------------------------------------------------------------------");
7644
  PrintS("Step 1:");
7645
  PrintS("Action: Send one byte using NREAD and receive it at the other side.");
7646
  PrintS("Result: The same NREAD should be received as has been sent.");
7647
  PrintS("----------------------------------------------------------------------");
7648
  /******************************************************************************/
7649
  TESTSTART("TG_riostack-TC6-Step1");
7650
  /******************************************************************************/
7651
 
7652
  for(j = 0; j < 8; j++)
7653
  {
7654
    RIO_sendNread(&stack, 0x0060, j, 0xaaaaaaaa+j, 1);
7655
 
7656
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
7657
    {
7658
      s = RIO_portGetSymbol(&stack);
7659
      RIO_portAddSymbol(&stack, s);
7660
    }
7661
 
7662
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
7663
 
7664
    TESTEXPR(tid, j);
7665
    TESTEXPR(srcid, 0xdead);
7666
    TESTEXPR(address, 0xaaaaaaaa+j);
7667
    TESTEXPR(length, 1);
7668
 
7669
    RIO_packetRemove(&stack);
7670
  }
7671
 
7672
  /******************************************************************************/
7673
  TESTEND;
7674
  /******************************************************************************/
7675
  PrintS("----------------------------------------------------------------------");
7676
  PrintS("Step 2:");
7677
  PrintS("Action: Send two bytes using NREAD and receive it at the other side.");
7678
  PrintS("Result: The same NREAD should be received as has been sent.");
7679
  PrintS("----------------------------------------------------------------------");
7680
  /******************************************************************************/
7681
  TESTSTART("TG_riostack-TC6-Step2");
7682
  /******************************************************************************/
7683
 
7684
  for(j = 0; j < 4; j++)
7685
  {
7686
    RIO_sendNread(&stack, 0x0060, j, 0x00000008+2*j, 2);
7687
 
7688
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
7689
    {
7690
      s = RIO_portGetSymbol(&stack);
7691
      RIO_portAddSymbol(&stack, s);
7692
    }
7693
 
7694
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
7695
 
7696
    TESTEXPR(tid, j);
7697
    TESTEXPR(srcid, 0xdead);
7698
    TESTEXPR(address, 0x00000008+2*j);
7699
    TESTEXPR(length, 2);
7700
 
7701
    RIO_packetRemove(&stack);
7702
  }
7703
 
7704
  /******************************************************************************/
7705
  TESTEND;
7706
  /******************************************************************************/
7707
  PrintS("----------------------------------------------------------------------");
7708
  PrintS("Step 3:");
7709
  PrintS("Action: Send three to seven bytes using NREAD and receive it at the other ");
7710
  PrintS("        side.");
7711
  PrintS("Result: The same NREAD should be received as has been sent.");
7712
  PrintS("----------------------------------------------------------------------");
7713
  /******************************************************************************/
7714
  TESTSTART("TG_riostack-TC6-Step3");
7715
  /******************************************************************************/
7716
 
7717
  for(k = 3; k < 8; k++)
7718
  {
7719
    for(j = 0; j < 2; j++)
7720
    {
7721
      RIO_sendNread(&stack, 0x0060, j, 0x00000008+(8-k)*j, k);
7722
 
7723
      while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
7724
      {
7725
        s = RIO_portGetSymbol(&stack);
7726
        RIO_portAddSymbol(&stack, s);
7727
      }
7728
 
7729
      RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
7730
 
7731
      TESTEXPR(tid, j);
7732
      TESTEXPR(srcid, 0xdead);
7733
      TESTEXPR(address, 0x00000008+(8-k)*j);
7734
      TESTEXPR(length, k);
7735
 
7736
      RIO_packetRemove(&stack);
7737
    }
7738
  }
7739
 
7740
  /******************************************************************************/
7741
  TESTEND;
7742
  /******************************************************************************/
7743
  PrintS("----------------------------------------------------------------------");
7744
  PrintS("Step 4:");
7745
  PrintS("Action: Send one and two double words using NREAD and receive it at the ");
7746
  PrintS("        other side.");
7747
  PrintS("Result: The same NREAD should be received as has been sent.");
7748
  PrintS("----------------------------------------------------------------------");
7749
  /******************************************************************************/
7750
  TESTSTART("TG_riostack-TC6-Step4");
7751
  /******************************************************************************/
7752
 
7753
  for(j = 0; j < 2; j++)
7754
  {
7755
    RIO_sendNread(&stack, 0x0060, j, 0x00000008+8*j, 8*j+8);
7756
 
7757
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
7758
    {
7759
      s = RIO_portGetSymbol(&stack);
7760
      RIO_portAddSymbol(&stack, s);
7761
    }
7762
 
7763
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
7764
 
7765
    TESTEXPR(tid, j);
7766
    TESTEXPR(srcid, 0xdead);
7767
    TESTEXPR(address, 0x00000008+8*j);
7768
    TESTEXPR(length, 8*j+8);
7769
 
7770
    RIO_packetRemove(&stack);
7771
  }
7772
 
7773
  /******************************************************************************/
7774
  TESTEND;
7775
  /******************************************************************************/
7776
  PrintS("----------------------------------------------------------------------");
7777
  PrintS("Step 5:");
7778
  PrintS("Action: Send multiple of four full double words using NREAD and receive it");
7779
  PrintS("at the other side.");
7780
  PrintS("Result: The same NREAD should be received as has been sent.");
7781
  PrintS("----------------------------------------------------------------------");
7782
  /******************************************************************************/
7783
  TESTSTART("TG_riostack-TC6-Step5");
7784
  /******************************************************************************/
7785
 
7786
  for(j = 0; j < 8; j++)
7787
  {
7788
    RIO_sendNread(&stack, 0x0060, j, 0x00000008+8*j, 32*j+32);
7789
 
7790
    while(RIO_eventPoll(&stack) != RIO_EVENT_NREAD)
7791
    {
7792
      s = RIO_portGetSymbol(&stack);
7793
      RIO_portAddSymbol(&stack, s);
7794
    }
7795
 
7796
    RIO_receiveNread(&stack, &srcid, &tid, &address, &length);
7797
 
7798
    TESTEXPR(tid, j);
7799
    TESTEXPR(srcid, 0xdead);
7800
    TESTEXPR(address, 0x00000008+8*j);
7801
    TESTEXPR(length, 32*j+32);
7802
 
7803
    RIO_packetRemove(&stack);
7804
  }
7805
 
7806
  /* REMARK: Add negative testcase where all unallowed address, size combinations
7807
     are sent...*/
7808
 
7809
  /******************************************************************************/
7810
  TESTEND;
7811
  /******************************************************************************/
7812
  PrintS("----------------------------------------------------------------------");
7813
  PrintS("TG_riostack-TC7");
7814
  PrintS("Description: Test NWRITER packets.");
7815
  PrintS("Requirement: XXXXX");
7816
  PrintS("----------------------------------------------------------------------");
7817
  PrintS("Step 1:");
7818
  PrintS("Action: Send one byte using NWRITER and receive it at the other side.");
7819
  PrintS("Result: The same NWRITER should be received as has been sent.");
7820
  PrintS("----------------------------------------------------------------------");
7821
  /******************************************************************************/
7822
  TESTSTART("TG_riostack-TC7-Step1");
7823
  /******************************************************************************/
7824
 
7825
  for(j = 0; j < 8; j++)
7826
  {
7827
    for(i = 0; i < 1; i++)
7828
    {
7829
      payload8[i] = i+j+1;
7830
      payload8Expected[i] = 0;
7831
    }
7832
 
7833
    RIO_sendNwrite(&stack, 0x0060, 0xaaaaaaaa+j, 1, payload8);
7834
 
7835
    while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE)
7836
    {
7837
      s = RIO_portGetSymbol(&stack);
7838
      RIO_portAddSymbol(&stack, s);
7839
    }
7840
 
7841
    length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
7842
 
7843
    TESTEXPR(length, 1);
7844
    TESTEXPR(srcid, 0xdead);
7845
    TESTEXPR(address, 0xaaaaaaaa+j);
7846
 
7847
    for(i = 0; i < 1; i++)
7848
    {
7849
      TESTEXPR(payload8Expected[i], i+j+1);
7850
    }
7851
 
7852
    RIO_packetRemove(&stack);
7853
  }
7854
 
7855
  /******************************************************************************/
7856
  TESTEND;
7857
  /******************************************************************************/
7858
  PrintS("----------------------------------------------------------------------");
7859
  PrintS("Step 2:");
7860
  PrintS("Action: Send two bytes using NWRITE and receive it at the other side.");
7861
  PrintS("Result: The same NWRITE should be received as has been sent.");
7862
  PrintS("----------------------------------------------------------------------");
7863
  /******************************************************************************/
7864
  TESTSTART("TG_riostack-TC7-Step2");
7865
  /******************************************************************************/
7866
 
7867
  for(j = 0; j < 4; j++)
7868
  {
7869
    for(i = 0; i < 2; i++)
7870
    {
7871
      payload8[i] = i+j;
7872
      payload8Expected[i] = 0;
7873
    }
7874
 
7875
    RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+2*j, 2, payload8);
7876
 
7877
    while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
7878
    {
7879
      s = RIO_portGetSymbol(&stack);
7880
      RIO_portAddSymbol(&stack, s);
7881
    }
7882
 
7883
    length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
7884
 
7885
    TESTEXPR(tid, j);
7886
    TESTEXPR(srcid, 0xdead);
7887
    TESTEXPR(address, 0x00000008+2*j);
7888
    TESTEXPR(length, 2);
7889
 
7890
    for(i = 0; i < 2; i++)
7891
    {
7892
      TESTEXPR(payload8Expected[i], i+j);
7893
    }
7894
 
7895
    RIO_packetRemove(&stack);
7896
  }
7897
 
7898
  /******************************************************************************/
7899
  TESTEND;
7900
  /******************************************************************************/
7901
  PrintS("----------------------------------------------------------------------");
7902
  PrintS("Step 3:");
7903
  PrintS("Action: Send three to seven bytes using NWRITE and receive it at the other ");
7904
  PrintS("        side.");
7905
  PrintS("Result: The same NWRITE should be received as has been sent.");
7906
  PrintS("----------------------------------------------------------------------");
7907
  /******************************************************************************/
7908
  TESTSTART("TG_riostack-TC7-Step3");
7909
  /******************************************************************************/
7910
 
7911
  for(k = 3; k < 8; k++)
7912
  {
7913
    for(j = 0; j < 2; j++)
7914
    {
7915
      for(i = 0; i < k; i++)
7916
      {
7917
        payload8[i] = i+j+1;
7918
        payload8Expected[i] = 0;
7919
      }
7920
 
7921
      RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+(8-k)*j, k, payload8);
7922
 
7923
      while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
7924
      {
7925
        s = RIO_portGetSymbol(&stack);
7926
        RIO_portAddSymbol(&stack, s);
7927
      }
7928
 
7929
      length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
7930
 
7931
      TESTEXPR(tid, j);
7932
      TESTEXPR(srcid, 0xdead);
7933
      TESTEXPR(address, 0x00000008+(8-k)*j);
7934
      TESTEXPR(length, k);
7935
 
7936
      for(i = 0; i < k; i++)
7937
      {
7938
        TESTEXPR(payload8Expected[i], i+j+1);
7939
      }
7940
 
7941
      RIO_packetRemove(&stack);
7942
    }
7943
  }
7944
 
7945
  /******************************************************************************/
7946
  TESTEND;
7947
  /******************************************************************************/
7948
  PrintS("----------------------------------------------------------------------");
7949
  PrintS("Step 4:");
7950
  PrintS("Action: Send full double words using NWRITE and receive it at the other side.");
7951
  PrintS("Result: The same NWRITE should be received as has been sent.");
7952
  PrintS("----------------------------------------------------------------------");
7953
  /******************************************************************************/
7954
  TESTSTART("TG_riostack-TC7-Step4");
7955
  /******************************************************************************/
7956
 
7957
  for(j = 1; j < 32; j++)
7958
  {
7959
    for(i = 0; i < 8*j; i++)
7960
    {
7961
      payload8[i] = i+j+1;
7962
      payload8Expected[i] = 0;
7963
    }
7964
 
7965
    RIO_sendNwriteR(&stack, 0x0060, j, 0x00000008+8*j, 8*j, payload8);
7966
 
7967
    while(RIO_eventPoll(&stack) != RIO_EVENT_NWRITE_R)
7968
    {
7969
      s = RIO_portGetSymbol(&stack);
7970
      RIO_portAddSymbol(&stack, s);
7971
    }
7972
 
7973
    length = RIO_receiveNwrite(&stack, &srcid, &tid, &address, sizeof(payload8Expected), payload8Expected);
7974
 
7975
    TESTEXPR(tid, j);
7976
    TESTEXPR(srcid, 0xdead);
7977
    TESTEXPR(address, 0x00000008+8*j);
7978
    TESTEXPR(length, 8*j);
7979
 
7980
    for(i = 0; i < 8*j; i++)
7981
    {
7982
      TESTEXPR(payload8Expected[i], (uint8_t) (i+j+1));
7983
    }
7984
 
7985
    RIO_packetRemove(&stack);
7986
  }
7987
 
7988
  /******************************************************************************/
7989
  TESTEND;
7990
  /******************************************************************************/
7991
  PrintS("----------------------------------------------------------------------");
7992
  PrintS("TG_riostack-TC8");
7993
  PrintS("Description: Test RESPONSE packets.");
7994
  PrintS("Requirement: XXXXX");
7995
  PrintS("----------------------------------------------------------------------");
7996
  PrintS("Step 1:");
7997
  PrintS("Action: Send one byte using RESPONSE_WITH_PAYLOAD and receive it at the ");
7998
  PrintS("        other side.");
7999
  PrintS("Result: The same RESPONSE_WITH_PAYLOAD should be received as has been sent.");
8000
  PrintS("----------------------------------------------------------------------");
8001
  /******************************************************************************/
8002
  TESTSTART("TG_riostack-TC8-Step1");
8003
  /******************************************************************************/
8004
 
8005
  for(j = 0; j < 8; j++)
8006
  {
8007
    for(i = 0; i < 1; i++)
8008
    {
8009
      payload8[i] = i+j+1;
8010
      payload8Expected[i] = 0;
8011
    }
8012
 
8013
    RIO_sendResponseDonePayload(&stack, 0x0060, j, 0x00000008+j, 1, payload8);
8014
 
8015
    while(RIO_eventPoll(&stack) != RIO_EVENT_RESPONSE_DONE_PAYLOAD)
8016
    {
8017
      s = RIO_portGetSymbol(&stack);
8018
      RIO_portAddSymbol(&stack, s);
8019
    }
8020
 
8021
    length = RIO_receiveResponseDonePayload(&stack, &srcid, &tid, 0x00000008+j, 1, payload8Expected);
8022
 
8023
    TESTEXPR(tid, j);
8024
    TESTEXPR(srcid, 0xdead);
8025
    TESTEXPR(length, 1);
8026
 
8027
    for(i = 0; i < 1; i++)
8028
    {
8029
      TESTEXPR(payload8Expected[i], i+j+1);
8030
    }
8031
 
8032
    RIO_packetRemove(&stack);
8033
  }
8034
 
8035
  /******************************************************************************/
8036
  TESTEND;
8037
  /******************************************************************************/
8038
  PrintS("----------------------------------------------------------------------");
8039
  PrintS("TG_riostack-TC9");
8040
  PrintS("Description: Test DOORBELL packet and its response.");
8041
  PrintS("Requirement: XXXXX");
8042
  PrintS("----------------------------------------------------------------------");
8043
  PrintS("Step 1:");
8044
  PrintS("Action: Send a doorbell.");
8045
  PrintS("Result: The received doorbell should have the same properties as the sent.");
8046
  PrintS("----------------------------------------------------------------------");
8047
  /******************************************************************************/
8048
  TESTSTART("TG_riostack-TC9-Step1");
8049
  /******************************************************************************/
8050
 
8051
  RIO_sendDoorbell(&stack, 0x0060, 16, 0xbabe);
8052
 
8053
  while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
8054
  {
8055
    s = RIO_portGetSymbol(&stack);
8056
    RIO_portAddSymbol(&stack, s);
8057
  }
8058
 
8059
  RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
8060
 
8061
  TESTEXPR(srcid, 0xdead);
8062
  TESTEXPR(tid, 16);
8063
  TESTEXPR(info, 0xbabe);
8064
  RIO_packetRemove(&stack);
8065
 
8066
  /******************************************************************************/
8067
  TESTEND;
8068
  /******************************************************************************/
8069
  PrintS("----------------------------------------------------------------------");
8070
  PrintS("Step 2:");
8071
  PrintS("Action: Send a response that is used for doorbells.");
8072
  PrintS("Result: The same data should be returned.");
8073
  PrintS("----------------------------------------------------------------------");
8074
  /******************************************************************************/
8075
  TESTSTART("TG_riostack-TC9-Step2");
8076
  /******************************************************************************/
8077
 
8078
  RIO_sendResponseDone(&stack, 0x0060, 16);
8079
 
8080
  while(RIO_eventPoll(&stack) != RIO_EVENT_RESPONSE_DONE)
8081
  {
8082
    s = RIO_portGetSymbol(&stack);
8083
    RIO_portAddSymbol(&stack, s);
8084
  }
8085
 
8086
  RIO_receiveResponseDone(&stack, &srcid, &tid);
8087
 
8088
  TESTEXPR(srcid, 0xdead);
8089
  TESTEXPR(tid, 16);
8090
  RIO_packetRemove(&stack);
8091
 
8092
  /******************************************************************************/
8093
  TESTEND;
8094
  /******************************************************************************/
8095
  PrintS("----------------------------------------------------------------------");
8096
  PrintS("TG_riostack-TC10");
8097
  PrintS("Description: Test MESSAGE packets.");
8098
  PrintS("Requirement: XXXXX");
8099
  PrintS("----------------------------------------------------------------------");
8100
  PrintS("Step 1:");
8101
  PrintS("Action: Send increasing number of byte using MESSAGE on all mailboxes");
8102
  PrintS("        and receive it at the other side.");
8103
  PrintS("Result: The same MESSAGE on the correct mailbox should be received as has");
8104
  PrintS("        been sent.");
8105
  PrintS("----------------------------------------------------------------------");
8106
  /******************************************************************************/
8107
  TESTSTART("TG_riostack-TC10-Step1");
8108
  /******************************************************************************/
8109
 
8110
  for(k = 0; k < 256; k++)
8111
  {
8112
    for(j = 1; j < 256; j++)
8113
    {
8114
      for(i = 0; i < j; i++)
8115
      {
8116
        payload8[i] = i+j+1;
8117
        payload8Expected[i] = 0;
8118
      }
8119
 
8120
      RIO_sendMessage(&stack, 0x0060, k, j, payload8);
8121
 
8122
      while(RIO_eventPoll(&stack) != RIO_EVENT_MESSAGE)
8123
      {
8124
        s = RIO_portGetSymbol(&stack);
8125
        RIO_portAddSymbol(&stack, s);
8126
      }
8127
 
8128
      length = RIO_receiveMessage(&stack, &srcid, &mailbox, sizeof(payload8Expected), payload8Expected);
8129
 
8130
      TESTEXPR(srcid, 0xdead);
8131
      TESTEXPR(mailbox, k);
8132
      TESTEXPR(length, (((j-1)/8)+1)*8);
8133
 
8134
      for(i = 0; i < j; i++)
8135
      {
8136
        TESTEXPR(payload8Expected[i], (uint8_t) (i+j+1));
8137
      }
8138
 
8139
      RIO_packetRemove(&stack);
8140
    }
8141
  }
8142
 
8143
  /******************************************************************************/
8144
  TESTEND;
8145
  /******************************************************************************/
8146
  PrintS("----------------------------------------------------------------------");
8147
  PrintS("Step 2:");
8148
  PrintS("Action: Send a MESSAGE-RESPONSE from all mailboxes.");
8149
  PrintS("Result: The same MESSAGE-RESPONSE should be received as has been sent.");
8150
  PrintS("----------------------------------------------------------------------");
8151
  /******************************************************************************/
8152
  TESTSTART("TG_riostack-TC10-Step2");
8153
  /******************************************************************************/
8154
 
8155
  for(i = 0; i < 256; i++)
8156
  {
8157
    RIO_sendMessageResponseDone(&stack, 0x0060, i);
8158
 
8159
    while(RIO_eventPoll(&stack) != RIO_EVENT_MESSAGE_RESPONSE_DONE)
8160
    {
8161
      s = RIO_portGetSymbol(&stack);
8162
      RIO_portAddSymbol(&stack, s);
8163
    }
8164
 
8165
    RIO_receiveMessageResponseDone(&stack, &srcid, &mailbox);
8166
 
8167
    TESTEXPR(srcid, 0xdead);
8168
    TESTEXPR(mailbox, i);
8169
    RIO_packetRemove(&stack);
8170
  }
8171
 
8172
  /******************************************************************************/
8173
  TESTEND;
8174
  /******************************************************************************/
8175
  PrintS("----------------------------------------------------------------------");
8176
  PrintS("TG_riostack-TC11");
8177
  PrintS("Description: Test reading and writing raw packets.");
8178
  PrintS("Requirement: XXXXX");
8179
  PrintS("----------------------------------------------------------------------");
8180
  PrintS("Step 1:");
8181
  PrintS("Action: Send a packet using normal functions then copy it using the ");
8182
  PrintS("        packetGet() and packetSet() functions. ");
8183
  PrintS("Result: The same packet should be received when copied.");
8184
  PrintS("----------------------------------------------------------------------");
8185
  /******************************************************************************/
8186
  TESTSTART("TG_riostack-TC11-Step1");
8187
  /******************************************************************************/
8188
 
8189
  RIO_sendDoorbell(&stack, 0x0060, 1, 0xca1e);
8190
 
8191
  while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
8192
  {
8193
    s = RIO_portGetSymbol(&stack);
8194
    RIO_portAddSymbol(&stack, s);
8195
  }
8196
 
8197
  RIO_receiveDoorbell(&stack, &srcid, &tid, &info);
8198
 
8199
  TESTEXPR(srcid, 0xdead);
8200
  TESTEXPR(tid, 1);
8201
  TESTEXPR(info, 0xca1e);
8202
 
8203
  packetLength = RIO_packetGet(&stack, sizeof(packet)/4, packet);
8204
  RIO_packetSet(&stack, packetLength, packet);
8205
 
8206
  while(RIO_eventPoll(&stack) != RIO_EVENT_DOORBELL)
8207
  {
8208
    s = RIO_portGetSymbol(&stack);
8209
    RIO_portAddSymbol(&stack, s);
8210
  }
8211
 
8212
  TESTEXPR(srcid, 0xdead);
8213
  TESTEXPR(tid, 1);
8214
  TESTEXPR(info, 0xca1e);
8215
  RIO_packetRemove(&stack);
8216
 
8217
  /******************************************************************************/
8218
  TESTEND;
8219
  /******************************************************************************/
8220
 
8221
  return 0;
8222
}
8223
#endif
8224
 
8225
/*************************** end of file **************************************/

powered by: WebSVN 2.1.0

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