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

Subversion Repositories rio

[/] [rio/] [trunk/] [sw/] [codec/] [riocodecuart.c] - Blame information for rev 25

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 code that can serialize and deserialize rio symbols onto
10
 * and from an 8-bit UART transmission channel.
11
 *
12
 * To Do:
13
 * -
14
 *
15
 * Author(s):
16
 * - Magnus Rosenius, magro732@opencores.org
17
 *
18
 *******************************************************************************
19
 *
20
 * Copyright (C) 2013 Authors and OPENCORES.ORG
21
 *
22
 * This source file may be used and distributed without
23
 * restriction provided that this copyright statement is not
24
 * removed from the file and that any derivative work contains
25
 * the original copyright notice and the associated disclaimer.
26
 *
27
 * This source file is free software; you can redistribute it
28
 * and/or modify it under the terms of the GNU Lesser General
29
 * Public License as published by the Free Software Foundation;
30
 * either version 2.1 of the License, or (at your option) any
31
 * later version.
32
 *
33
 * This source is distributed in the hope that it will be
34
 * useful, but WITHOUT ANY WARRANTY; without even the implied
35
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
36
 * PURPOSE. See the GNU Lesser General Public License for more
37
 * details.
38
 *
39
 * You should have received a copy of the GNU Lesser General
40
 * Public License along with this source; if not, download it
41
 * from http://www.opencores.org/lgpl.shtml
42
 *
43
 *******************************************************************************/
44
 
45
#include <stdint.h>
46
 
47
typedef enum
48
{
49
  RIO_SYMBOL_TYPE_IDLE, RIO_SYMBOL_TYPE_CONTROL,
50
  RIO_SYMBOL_TYPE_DATA, RIO_SYMBOL_TYPE_ERROR
51
} RioSymbolType;
52
 
53
typedef struct
54
{
55
  RioSymbolType type;
56
  uint32_t data;
57
} RioSymbol;
58
 
59
typedef struct
60
{
61
 
62
} RioStack_t;
63
 
64
void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s );
65
RioSymbol RIO_portGetSymbol( RioStack_t *stack );
66
 
67
 
68
void receiveByte(RioStack_t *stack, uint8_t incoming)
69
{
70
  static RioSymbol rxSymbol;
71
  static uint8_t flagFound = 0;
72
  static uint8_t symbolCounter = 0;
73
 
74
 
75
  if(incoming != 0x7e)
76
  {
77
    if(incoming != 0x7d)
78
    {
79
      if(flagFound)
80
      {
81
        incoming ^= 0x20;
82
      }
83
      else
84
      {
85
        /* Dont do anything. */
86
      }
87
 
88
      switch(symbolCounter)
89
      {
90
        case 0:
91
          rxSymbol.type = RIO_SYMBOL_TYPE_ERROR;
92
          rxSymbol.data = incoming;
93
          symbolCounter++;
94
          break;
95
        case 1:
96
          rxSymbol.type = RIO_SYMBOL_TYPE_ERROR;
97
          rxSymbol.data <<= 8;
98
          rxSymbol.data |= incoming;
99
          symbolCounter++;
100
          break;
101
        case 2:
102
          rxSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
103
          rxSymbol.data <<= 8;
104
          rxSymbol.data |= incoming;
105
          symbolCounter++;
106
          break;
107
        case 3:
108
          rxSymbol.type = RIO_SYMBOL_TYPE_DATA;
109
          rxSymbol.data <<= 8;
110
          rxSymbol.data |= incoming;
111
 
112
          RIO_portAddSymbol(stack, rxSymbol);
113
 
114
          rxSymbol.data = 0x00000000;
115
          symbolCounter = 0;
116
          break;
117
      }
118
 
119
      flagFound = 0;
120
    }
121
    else
122
    {
123
      flagFound = 1;
124
    }
125
  }
126
  else
127
  {
128
    if(symbolCounter == 0)
129
    {
130
      rxSymbol.type = RIO_SYMBOL_TYPE_IDLE;
131
      RIO_portAddSymbol(stack, rxSymbol);
132
    }
133
    else
134
    {
135
      RIO_portAddSymbol(stack, rxSymbol);
136
    }
137
 
138
    symbolCounter = 0;
139
  }
140
}
141
 
142
uint8_t transmitByte(RioStack_t *stack)
143
{
144
  uint8_t returnValue;
145
  static uint8_t symbolCounter = 3;
146
  static uint8_t stuffing = 0;
147
  static RioSymbol txSymbol;
148
  uint8_t outbound;
149
 
150
 
151
  /* Check if the previous symbol has been sent. */
152
  if((symbolCounter == 3) && (stuffing == 0))
153
  {
154
    /* Symbol sent. */
155
 
156
    /* Get a new symbol. */
157
    txSymbol = RIO_portGetSymbol(stack);
158
    if(txSymbol.type == RIO_SYMBOL_TYPE_CONTROL)
159
    {
160
      txSymbol.data <<= 8;
161
    }
162
  }
163
  else
164
  {
165
    /* Symbol not sent. */
166
    /* Continue to send the old symbol. */
167
  }
168
 
169
  /* Check if a flag should be sent. */
170
  if ((txSymbol.type == RIO_SYMBOL_TYPE_IDLE) ||
171
      ((stuffing == 0) && (symbolCounter == 0) && (txSymbol.type == RIO_SYMBOL_TYPE_CONTROL)))
172
  {
173
    /* A flag needs to be sent. */
174
    /* An idle symbol should be sent as a flag and a control symbol should always be
175
       terminated by a flag. */
176
    returnValue = 0x7e;
177
    symbolCounter = 3;
178
    stuffing = 0;
179
  }
180
  else
181
  {
182
    /* A flag does not need to be sent. */
183
 
184
    /* Get the current byte in the symbol. */
185
    outbound = txSymbol.data >> (8*symbolCounter);
186
 
187
    /* Check if stuffing is active. */
188
    if(!stuffing)
189
    {
190
      /* No stuffing active. */
191
 
192
      /* Check if the current byte needs to be stuffed. */
193
      if((outbound != 0x7e) && (outbound != 0x7d))
194
      {
195
        /* The current byte does not need to be stuffed. */
196
        returnValue = outbound;
197
        symbolCounter = (symbolCounter - 1) & 0x3;
198
      }
199
      else
200
      {
201
        /* The current byte needs to be stuffed. */
202
        returnValue = 0x7d;
203
        stuffing = 1;
204
      }
205
    }
206
    else
207
    {
208
      /* Stuffing is active. */
209
      /* An escape sequence has been sent, transmit the original data but change it to not being a flag. */
210
      returnValue = outbound ^ 0x20;
211
      stuffing = 0;
212
      symbolCounter = (symbolCounter - 1) & 0x3;
213
    }
214
  }
215
 
216
  return returnValue;
217
}
218
 
219
 
220
 
221
/*******************************************************************************
222
 * Module test code.
223
 *******************************************************************************/
224
 
225
#define TESTEXPR(got, expected)                                         \
226
  if ((got)!=(expected))                                                \
227
  {                                                                     \
228
    printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n",    \
229
           __LINE__, #got, (got), (got), (expected), (expected));       \
230
    exit(1);                                                            \
231
  }
232
static RioSymbol txSymbol;
233
static uint8_t txNewSymbol;
234
static RioSymbol rxSymbol;
235
static uint8_t rxNewSymbol;
236
void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s )
237
{
238
  rxNewSymbol = 1;
239
  rxSymbol = s;
240
}
241
RioSymbol RIO_portGetSymbol( RioStack_t *stack )
242
{
243
  if(txNewSymbol)
244
  {
245
    txNewSymbol = 0;
246
    return txSymbol;
247
  }
248
  else
249
  {
250
    RioSymbol s;
251
    s.type = RIO_SYMBOL_TYPE_ERROR;
252
    return s;
253
  }
254
}
255
int main(int argc, char *argv[])
256
{
257
  RioStack_t *stack;
258
 
259
  /***************************************************************
260
   * Test receiver.
261
   ***************************************************************/
262
 
263
  /* Receive a flag. */
264
  rxNewSymbol = 0;
265
  receiveByte(stack, 0x7e);
266
  TESTEXPR(rxNewSymbol, 1);
267
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_IDLE);
268
 
269
  /* Receive not a flag followed by flag. */
270
  rxNewSymbol = 0;
271
  receiveByte(stack, 0xaa);
272
  receiveByte(stack, 0x7e);
273
  TESTEXPR(rxNewSymbol, 1);
274
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_ERROR);
275
 
276
  /* Receive not a flag twice followed by flag. */
277
  rxNewSymbol = 0;
278
  receiveByte(stack, 0xaa);
279
  receiveByte(stack, 0x55);
280
  receiveByte(stack, 0x7e);
281
  TESTEXPR(rxNewSymbol, 1);
282
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_ERROR);
283
 
284
  /* Receive a control symbol followed by flag. */
285
  rxNewSymbol = 0;
286
  receiveByte(stack, 0x11);
287
  receiveByte(stack, 0x22);
288
  receiveByte(stack, 0x33);
289
  receiveByte(stack, 0x7e);
290
  TESTEXPR(rxNewSymbol, 1);
291
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
292
  TESTEXPR(rxSymbol.data, 0x00112233);
293
 
294
  /* Receive a data symbol. */
295
  rxNewSymbol = 0;
296
  receiveByte(stack, 0x44);
297
  receiveByte(stack, 0x55);
298
  receiveByte(stack, 0x66);
299
  receiveByte(stack, 0x77);
300
  TESTEXPR(rxNewSymbol, 1);
301
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
302
  TESTEXPR(rxSymbol.data, 0x44556677);
303
 
304
  /* Receive a back-to-back data symbol. */
305
  rxNewSymbol = 0;
306
  receiveByte(stack, 0x88);
307
  receiveByte(stack, 0x99);
308
  receiveByte(stack, 0xaa);
309
  receiveByte(stack, 0xbb);
310
  TESTEXPR(rxNewSymbol, 1);
311
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
312
  TESTEXPR(rxSymbol.data, 0x8899aabb);
313
 
314
  /* Receive a back-to-back control symbol. */
315
  rxNewSymbol = 0;
316
  receiveByte(stack, 0xcc);
317
  receiveByte(stack, 0xdd);
318
  receiveByte(stack, 0xee);
319
  receiveByte(stack, 0x7e);
320
  TESTEXPR(rxNewSymbol, 1);
321
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
322
  TESTEXPR(rxSymbol.data, 0x00ccddee);
323
 
324
  /* Test control symbol with one stuffed byte. */
325
  rxNewSymbol = 0;
326
  receiveByte(stack, 0x7d);
327
  receiveByte(stack, 0x5e);
328
  receiveByte(stack, 0xff);
329
  receiveByte(stack, 0x01);
330
  receiveByte(stack, 0x7e);
331
  TESTEXPR(rxNewSymbol, 1);
332
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
333
  TESTEXPR(rxSymbol.data, 0x007eff01);
334
 
335
  /* Test control symbol with two stuffed bytes. */
336
  rxNewSymbol = 0;
337
  receiveByte(stack, 0x7d);
338
  receiveByte(stack, 0x5e);
339
  receiveByte(stack, 0xff);
340
  receiveByte(stack, 0x7d);
341
  receiveByte(stack, 0x5d);
342
  receiveByte(stack, 0x7e);
343
  TESTEXPR(rxNewSymbol, 1);
344
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
345
  TESTEXPR(rxSymbol.data, 0x007eff7d);
346
 
347
  /* Test control symbol with three stuffed bytes. */
348
  rxNewSymbol = 0;
349
  receiveByte(stack, 0x7d);
350
  receiveByte(stack, 0x5d);
351
  receiveByte(stack, 0x7d);
352
  receiveByte(stack, 0x5e);
353
  receiveByte(stack, 0x7d);
354
  receiveByte(stack, 0x5d);
355
  receiveByte(stack, 0x7e);
356
  TESTEXPR(rxNewSymbol, 1);
357
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
358
  TESTEXPR(rxSymbol.data, 0x007d7e7d);
359
 
360
  /* Test data symbol with one stuffed byte. */
361
  rxNewSymbol = 0;
362
  receiveByte(stack, 0x7d);
363
  receiveByte(stack, 0x5e);
364
  receiveByte(stack, 0x00);
365
  receiveByte(stack, 0x01);
366
  receiveByte(stack, 0x02);
367
  TESTEXPR(rxNewSymbol, 1);
368
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
369
  TESTEXPR(rxSymbol.data, 0x7e000102);
370
 
371
  /* Test data symbol with two stuffed bytes. */
372
  rxNewSymbol = 0;
373
  receiveByte(stack, 0x7d);
374
  receiveByte(stack, 0x5e);
375
  receiveByte(stack, 0x7d);
376
  receiveByte(stack, 0x5d);
377
  receiveByte(stack, 0x03);
378
  receiveByte(stack, 0x04);
379
  TESTEXPR(rxNewSymbol, 1);
380
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
381
  TESTEXPR(rxSymbol.data, 0x7e7d0304);
382
 
383
  /* Test data symbol with three stuffed bytes. */
384
  rxNewSymbol = 0;
385
  receiveByte(stack, 0x7d);
386
  receiveByte(stack, 0x5e);
387
  receiveByte(stack, 0x7d);
388
  receiveByte(stack, 0x5d);
389
  receiveByte(stack, 0x7d);
390
  receiveByte(stack, 0x5e);
391
  receiveByte(stack, 0x05);
392
  TESTEXPR(rxNewSymbol, 1);
393
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
394
  TESTEXPR(rxSymbol.data, 0x7e7d7e05);
395
 
396
  /* Test data symbol with four stuffed bytes. */
397
  rxNewSymbol = 0;
398
  receiveByte(stack, 0x7d);
399
  receiveByte(stack, 0x5e);
400
  receiveByte(stack, 0x7d);
401
  receiveByte(stack, 0x5d);
402
  receiveByte(stack, 0x7d);
403
  receiveByte(stack, 0x5e);
404
  receiveByte(stack, 0x7d);
405
  receiveByte(stack, 0x5d);
406
  TESTEXPR(rxNewSymbol, 1);
407
  TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
408
  TESTEXPR(rxSymbol.data, 0x7e7d7e7d);
409
 
410
  /***************************************************************
411
   * Test transmitter.
412
   ***************************************************************/
413
 
414
  /* Test transmission of idle symbol. */
415
  txNewSymbol = 1;
416
  txSymbol.type = RIO_SYMBOL_TYPE_IDLE;
417
  TESTEXPR(transmitByte(stack), 0x7e);
418
 
419
  /* Test transmission of control symbol. */
420
  txNewSymbol = 1;
421
  txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
422
  txSymbol.data = 0x00112233;
423
  TESTEXPR(transmitByte(stack), 0x11);
424
  TESTEXPR(transmitByte(stack), 0x22);
425
  TESTEXPR(transmitByte(stack), 0x33);
426
  TESTEXPR(transmitByte(stack), 0x7e);
427
 
428
  /* Test transmission of data symbol. */
429
  txNewSymbol = 1;
430
  txSymbol.type = RIO_SYMBOL_TYPE_DATA;
431
  txSymbol.data = 0x44556677;
432
  TESTEXPR(transmitByte(stack), 0x44);
433
  TESTEXPR(transmitByte(stack), 0x55);
434
  TESTEXPR(transmitByte(stack), 0x66);
435
  TESTEXPR(transmitByte(stack), 0x77);
436
 
437
  /* Test transmission of back-to-back data symbol. */
438
  txNewSymbol = 1;
439
  txSymbol.type = RIO_SYMBOL_TYPE_DATA;
440
  txSymbol.data = 0x8899aabb;
441
  TESTEXPR(transmitByte(stack), 0x88);
442
  TESTEXPR(transmitByte(stack), 0x99);
443
  TESTEXPR(transmitByte(stack), 0xaa);
444
  TESTEXPR(transmitByte(stack), 0xbb);
445
 
446
  /* Test transmission of back-to-back control symbol. */
447
  txNewSymbol = 1;
448
  txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
449
  txSymbol.data = 0xffccddee;
450
  TESTEXPR(transmitByte(stack), 0xcc);
451
  TESTEXPR(transmitByte(stack), 0xdd);
452
  TESTEXPR(transmitByte(stack), 0xee);
453
  TESTEXPR(transmitByte(stack), 0x7e);
454
 
455
  /* Test transmission of back-to-back control symbol. */
456
  txNewSymbol = 1;
457
  txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
458
  txSymbol.data = 0xff010203;
459
  TESTEXPR(transmitByte(stack), 0x01);
460
  TESTEXPR(transmitByte(stack), 0x02);
461
  TESTEXPR(transmitByte(stack), 0x03);
462
  TESTEXPR(transmitByte(stack), 0x7e);
463
 
464
  /* Test transmission of control symbol with one stuffed byte. */
465
  txNewSymbol = 1;
466
  txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
467
  txSymbol.data = 0xff7e0102;
468
  TESTEXPR(transmitByte(stack), 0x7d);
469
  TESTEXPR(transmitByte(stack), 0x5e);
470
  TESTEXPR(transmitByte(stack), 0x01);
471
  TESTEXPR(transmitByte(stack), 0x02);
472
  TESTEXPR(transmitByte(stack), 0x7e);
473
 
474
  /* Test transmission of stuffed control symbol with two stuffed bytes. */
475
  txNewSymbol = 1;
476
  txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
477
  txSymbol.data = 0xff7e7d01;
478
  TESTEXPR(transmitByte(stack), 0x7d);
479
  TESTEXPR(transmitByte(stack), 0x5e);
480
  TESTEXPR(transmitByte(stack), 0x7d);
481
  TESTEXPR(transmitByte(stack), 0x5d);
482
  TESTEXPR(transmitByte(stack), 0x01);
483
  TESTEXPR(transmitByte(stack), 0x7e);
484
 
485
  /* Test transmission of stuffed control symbol with three stuffed bytes. */
486
  txNewSymbol = 1;
487
  txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
488
  txSymbol.data = 0xff7e7d7e;
489
  TESTEXPR(transmitByte(stack), 0x7d);
490
  TESTEXPR(transmitByte(stack), 0x5e);
491
  TESTEXPR(transmitByte(stack), 0x7d);
492
  TESTEXPR(transmitByte(stack), 0x5d);
493
  TESTEXPR(transmitByte(stack), 0x7d);
494
  TESTEXPR(transmitByte(stack), 0x5e);
495
  TESTEXPR(transmitByte(stack), 0x7e);
496
 
497
  /* Test transmission of data symbol with one stuffed byte. */
498
  txNewSymbol = 1;
499
  txSymbol.type = RIO_SYMBOL_TYPE_DATA;
500
  txSymbol.data = 0x7e010203;
501
  TESTEXPR(transmitByte(stack), 0x7d);
502
  TESTEXPR(transmitByte(stack), 0x5e);
503
  TESTEXPR(transmitByte(stack), 0x01);
504
  TESTEXPR(transmitByte(stack), 0x02);
505
  TESTEXPR(transmitByte(stack), 0x03);
506
 
507
  /* Test transmission of data symbol with two stuffed byte. */
508
  txNewSymbol = 1;
509
  txSymbol.type = RIO_SYMBOL_TYPE_DATA;
510
  txSymbol.data = 0x7e7d0102;
511
  TESTEXPR(transmitByte(stack), 0x7d);
512
  TESTEXPR(transmitByte(stack), 0x5e);
513
  TESTEXPR(transmitByte(stack), 0x7d);
514
  TESTEXPR(transmitByte(stack), 0x5d);
515
  TESTEXPR(transmitByte(stack), 0x01);
516
  TESTEXPR(transmitByte(stack), 0x02);
517
 
518
  /* Test transmission of data symbol with three stuffed byte. */
519
  txNewSymbol = 1;
520
  txSymbol.type = RIO_SYMBOL_TYPE_DATA;
521
  txSymbol.data = 0x7e7d7e01;
522
  TESTEXPR(transmitByte(stack), 0x7d);
523
  TESTEXPR(transmitByte(stack), 0x5e);
524
  TESTEXPR(transmitByte(stack), 0x7d);
525
  TESTEXPR(transmitByte(stack), 0x5d);
526
  TESTEXPR(transmitByte(stack), 0x7d);
527
  TESTEXPR(transmitByte(stack), 0x5e);
528
  TESTEXPR(transmitByte(stack), 0x01);
529
 
530
  /* Test transmission of data symbol with four stuffed byte. */
531
  txNewSymbol = 1;
532
  txSymbol.type = RIO_SYMBOL_TYPE_DATA;
533
  txSymbol.data = 0x7e7d7e7d;
534
  TESTEXPR(transmitByte(stack), 0x7d);
535
  TESTEXPR(transmitByte(stack), 0x5e);
536
  TESTEXPR(transmitByte(stack), 0x7d);
537
  TESTEXPR(transmitByte(stack), 0x5d);
538
  TESTEXPR(transmitByte(stack), 0x7d);
539
  TESTEXPR(transmitByte(stack), 0x5e);
540
  TESTEXPR(transmitByte(stack), 0x7d);
541
  TESTEXPR(transmitByte(stack), 0x5d);
542
 
543
  /***************************************************************
544
   * Test complete.
545
   ***************************************************************/
546
 
547
  printf("Test complete.\n");
548
}

powered by: WebSVN 2.1.0

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