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

Subversion Repositories yac

[/] [yac/] [trunk/] [test_sys/] [sw/] [pc/] [main.c] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 feddischso
/***************************************************************************
2
*                                                                          *
3
*  File           : main.c                                                 *
4
*  Project        : YAC (Yet Another CORDIC Core)                          *
5
*  Creation       : Jun. 2015                                              *
6
*  Limitations    :                                                        *
7
*  Platform       : Linux                                                  *
8
*  Target         : Linux-Os                                               *
9
*                                                                          *
10
*  Author(s):     : Christian Haettich                                     *
11
*  Email          : feddischson@opencores.org                              *
12
*                                                                          *
13
*                                                                          *
14
**                                                                        **
15
*                                                                          *
16
*  Description                                                             *
17
*        C implementation for a test system: PC part.                      *
18
*        This implementation sends messages via serial line.               *
19
*        Each message contains a calculation request, and each answer      *
20
*        contains the calculation result                                   *
21
*        All messages have the same size, starting with a synchronization  *
22
*        byte and a header byte.                                           *
23
*                                                                          *
24
*                                                                          *
25
****************************************************************************
26
*                                                                          *
27
*                     Copyright Notice                                     *
28
*                                                                          *
29
*    This file is part of YAC - Yet Another CORDIC Core                    *
30
*    Copyright (c) 2015, Author(s), All rights reserved.                   *
31
*                                                                          *
32
*    YAC is free software; you can redistribute it and/or                  *
33
*    modify it under the terms of the GNU Lesser General Public            *
34
*    License as published by the Free Software Foundation; either          *
35
*    version 3.0 of the License, or (at your option) any later version.    *
36
*                                                                          *
37
*    YAC is distributed in the hope that it will be useful,                *
38
*    but WITHOUT ANY WARRANTY; without even the implied warranty of        *
39
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
40
*    Lesser General Public License for more details.                       *
41
*                                                                          *
42
*    You should have received a copy of the GNU Lesser General Public      *
43
*    License along with this library. If not, download it from             *
44
*    http://www.gnu.org/licenses/lgpl                                      *
45
*                                                                          *
46
***************************************************************************/
47
 
48
#include <errno.h>
49
#include <termios.h>
50
#include <unistd.h>
51
#include <stdio.h>
52
#include <string.h>
53
#include <stdlib.h>
54
#include <sys/types.h>
55
#include <sys/stat.h>
56
#include <fcntl.h>
57
#include <endian.h>
58
#include <math.h>
59
 
60
#include "msg.h"
61
#include "yac.h"
62
#include "crc.h"
63
 
64
 
65
/**
66
 * Some error numbers used by this little tool
67
 */
68
#define ERR_NONE      0   /* no error               */
69
#define ERR_CRC       1   /* CRC error              */
70
#define ERR_TIMEOUT   2   /* Timeout error          */
71
#define ERR_CALC      3   /* Calculation error      */
72
#define ERR_SYNC      4   /* Synchronization error  */
73
#define ERR_SERIAL    5   /* Serial comm. error     */
74
 
75
#if 0
76
 #define VERBOSE 
77
#endif
78
 
79
 
80
/*
81
 * implemented in cordic_iterative.c
82
 */
83
extern
84
void cordic_int( long long int   x_i,
85
                 long long int   y_i,
86
                 long long int   a_i,
87
                 long long int * x_o,
88
                 long long int * y_o,
89
                 long long int * a_o,
90
                 int           * it_o,
91
                 int        mode,
92
                 int        XY_WIDTH,
93
                 int        A_WIDTH,
94
                 int        GUARD_BITS,
95
                 int        RM_GAIN );
96
 
97
 
98
/*
99
 * global message buffers
100
 */
101
static Msg global_out_buf;
102
static Msg global_in_buf;
103
 
104
 
105
/*
106
 * local functions
107
 */
108
uint8_t do_test           ( int fd, int x, int y, int z, int mode );
109
uint8_t do_sync           ( int fd );
110
uint8_t run_random_test   ( int fd, uint32_t n_test );
111
int     init_serial_port  ( char* portname, int baud, int timeout );
112
void    print_usage_and_exit( void );
113
 
114
 
115
 
116
 
117
int main( int argc, char* argv[] )
118
{
119
  int       i;
120
  char*     portname ;
121
  int       baud;
122
  int       serial_fd;
123
  int       n_tests;
124
 
125
  if( argc != 4 )
126
    print_usage_and_exit( );
127
 
128
  if( 1 != sscanf( argv[3], "%d", &n_tests ) )
129
    print_usage_and_exit( );
130
  if( 1 != sscanf( argv[2], "%d", &baud ) )
131
    print_usage_and_exit( );
132
  portname = argv[1];
133
 
134
 
135
 
136
  memset( global_out_buf.bytes, 0, sizeof( Msg ) );
137
  global_out_buf.fields.sync = SYNC_BYTE;
138
 
139
 
140
  serial_fd = init_serial_port( portname, baud, 10 );
141
  if( -1 == serial_fd )
142
    return -1;
143
 
144
  if( ERR_NONE != do_sync( serial_fd ) )
145
    fprintf( stderr, "Error: failed to sync\n" );
146
 
147
  run_random_test( serial_fd, n_tests );
148
 
149
  return 0;
150
}
151
 
152
/*
153
 * Prints some usage message
154
 */
155
void print_usage_and_exit( void )
156
{
157
  printf( "Usage: TODO <port> <baud> <n-tests>\n" );
158
  exit( -1 );
159
}
160
 
161
 
162
 
163
/**
164
 * Initializes the serial port
165
 */
166
int init_serial_port( char* portname, int baud, int timeout )
167
{
168
 
169
  struct termios tty;
170
  int serial_fd = open ( portname, O_RDWR | O_NOCTTY | O_SYNC );
171
  if( serial_fd == -1 )
172
  {
173
    fprintf( stderr, "Error: Failed to open serial port %s\n", portname );
174
    return -1;
175
  }
176
 
177
  memset (&tty, 0, sizeof( tty ) );
178
  if (tcgetattr ( serial_fd, &tty ) != 0)
179
  {
180
    fprintf( stderr, "Error %d from tcgetattr", errno );
181
    return -1;
182
  }
183
 
184
  cfsetospeed (&tty, baud);
185
  cfsetispeed (&tty, baud);
186
 
187
  tty.c_cflag     = (tty.c_cflag & ~CSIZE) | CS8;
188
  tty.c_iflag    &= ~IGNBRK;
189
  tty.c_lflag     = 0;
190
 
191
  tty.c_oflag     = 0;
192
  tty.c_cc[VMIN]  = 0;                       /* non blocking */
193
  tty.c_cc[VTIME] = 1;
194
 
195
  tty.c_iflag    &= ~(IXON | IXOFF | IXANY); /* shut off xon/xoff ctrl */
196
  tty.c_cflag    |= (CLOCAL | CREAD);
197
  tty.c_cflag    &= ~(PARENB | PARODD);
198
  tty.c_cflag    |= 0;                       /* parity */
199
  tty.c_cflag    &= ~CSTOPB;
200
  tty.c_cflag    &= ~CRTSCTS;
201
 
202
  if (tcsetattr ( serial_fd, TCSANOW, &tty ) != 0)
203
  {
204
    fprintf( stderr, "Error %d from tcsetattr", errno);
205
    return -1;
206
  }
207
 
208
  return serial_fd;
209
}
210
 
211
 
212
/**
213
 * Function to send and receive one message.
214
 *
215
 */
216
uint8_t snd_rcv( int fd, Msg out_buf, Msg * in_buf, int fail_cnt )
217
{
218
  int w_bytes, r_bytes;
219
  uint8_t *ptr;
220
  uint8_t crc_in;
221
  out_buf.fields.payload[ 0 ] = htobe32( out_buf.fields.payload[ 0 ] );
222
  out_buf.fields.payload[ 1 ] = htobe32( out_buf.fields.payload[ 1 ] );
223
  out_buf.fields.payload[ 2 ] = htobe32( out_buf.fields.payload[ 2 ] );
224
 
225
  out_buf.fields.crc = crc( out_buf.bytes, sizeof( Msg )-1 );
226
 
227
  w_bytes = write( fd, out_buf.bytes, sizeof( Msg ) );
228
 
229
  if( w_bytes != sizeof( Msg ) )
230
    return ERR_SERIAL;
231
 
232
  ptr = &in_buf->bytes[ 0 ];
233
  while( w_bytes )
234
  {
235
    r_bytes = read( fd, ptr, w_bytes );
236
    ptr     += r_bytes;
237
    w_bytes -= r_bytes;
238
 
239
    if( --fail_cnt == 0 )
240
    {
241
      #if 0
242
      printf( "timeout\n" );
243
      #endif
244
      return ERR_TIMEOUT;
245
    }
246
  }
247
  crc_in = crc( in_buf->bytes, sizeof( Msg )-1 );
248
  in_buf->fields.payload[ 0 ] = be32toh( in_buf->fields.payload[ 0 ] );
249
  in_buf->fields.payload[ 1 ] = be32toh( in_buf->fields.payload[ 1 ] );
250
  in_buf->fields.payload[ 2 ] = be32toh( in_buf->fields.payload[ 2 ] );
251
  if( crc_in != in_buf->fields.crc )
252
  {
253
    #if 0
254
    printf( "crc error (%x <-> %x )\n", crc_in, in_buf->fields.crc );
255
    #endif
256
    return ERR_CRC;
257
  }
258
 
259
  if( in_buf->fields.sync == out_buf.fields.sync )
260
    return ERR_NONE;
261
  else
262
    return ERR_SYNC;
263
}
264
 
265
/**
266
 * Send and receive a synchronization message
267
 * ( empty NOP message )
268
 */
269
uint8_t do_sync( int fd )
270
{
271
  uint8_t res;
272
 
273
  global_out_buf.fields.header = CMD_NOP;
274
  res = snd_rcv( fd, global_out_buf, &global_in_buf, 40 );
275
  if( res != ERR_NONE )
276
    return res;
277
 
278
 
279
  if( global_in_buf.fields.sync   == global_out_buf.fields.sync &&
280
      global_in_buf.fields.header == global_out_buf.fields.header )
281
    return ERR_NONE;
282
  else
283
    return ERR_SYNC;
284
}
285
 
286
 
287
 
288
 
289
 
290
/**
291
 * Function to run n_test tests
292
 *
293
 */
294
uint8_t run_random_test( int fd, uint32_t n_test )
295
{
296
 
297
  uint8_t  res;
298
  uint32_t test_cnt = 0;
299
  uint32_t calc_cnt = 0;
300
  uint32_t crc_cnt  = 0;
301
  uint32_t othr_cnt = 0;
302
 
303
  srand( 1234 );
304
  uint32_t i;
305
  for( i=0; i < n_test; i++, test_cnt++ )
306
  {
307
    int32_t y = ( rand() % ( (int32_t) pow( 2, YAC_XY_WIDTH ) ) ) - pow( 2, YAC_XY_WIDTH-1 );
308
    int32_t x = ( rand() % ( (int32_t) pow( 2, YAC_XY_WIDTH ) ) ) - pow( 2, YAC_XY_WIDTH-1 );
309
 
310
    res = do_test( fd, x, y, 0,  YAC_FLAG_VEC_ROT | YAC_MODE_CIR   );
311
 
312
    if( ERR_NONE != res )
313
    {
314
      if( res == ERR_CALC )
315
        calc_cnt++;
316
      else if( res == ERR_CRC )
317
        crc_cnt++;
318
      else
319
        othr_cnt++;
320
 
321
    }
322
  }
323
 
324
  printf(" %d of %d tests failed, (crc-errors: %d, other errors: %d )\n",
325
        calc_cnt,
326
        test_cnt,
327
        crc_cnt,
328
        othr_cnt );
329
 
330
  return ERR_NONE;
331
}
332
 
333
 
334
/**
335
 * Run one single test
336
 *
337
 */
338
uint8_t do_test( int fd, int x, int y, int z, int mode )
339
{
340
  long long int xo;
341
  long long int yo;
342
  long long int zo;
343
  uint8_t res;
344
  int it;
345
 
346
  /* local calculation */
347
  cordic_int(
348
    x, y, z, &xo, &yo, &zo, &it, mode,
349
      YAC_XY_WIDTH,
350
      YAC_A_WIDTH,
351
      2,
352
      YAC_RM_GAIN
353
      );
354
 
355
 
356
  /* remote calculation */
357
  global_out_buf.fields.header = CMD_CALC;
358
  global_out_buf.fields.payload[ 0 ] = x;
359
  global_out_buf.fields.payload[ 1 ] = y;
360
  global_out_buf.fields.payload[ 2 ] = z;
361
  global_out_buf.fields.mode         = mode;
362
  res = snd_rcv( fd, global_out_buf, &global_in_buf, 10 );
363
  if( ERR_NONE != res  )
364
    return res;
365
 
366
  # if defined (VERBOSE)
367
  printf("( %d <-> %d ) \n", global_in_buf.fields.payload[0], (int)xo );
368
  printf("( %d <-> %d ) \n", global_in_buf.fields.payload[1], (int)yo );
369
  printf("( %d <-> %d ) \n", global_in_buf.fields.payload[2], (int)zo );
370
  #endif
371
 
372
  /* result comparions */
373
  if ( (xo == global_in_buf.fields.payload[0]) &&
374
       (yo == global_in_buf.fields.payload[1]) &&
375
       (zo == global_in_buf.fields.payload[2])  )
376
    return ERR_NONE;
377
  else
378
    return ERR_CALC;
379
 
380
}
381
 
382
 

powered by: WebSVN 2.1.0

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