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

Subversion Repositories pc_fpga_com

[/] [pc_fpga_com/] [trunk/] [PC_FPGA_PLATFPORM/] [SOFTWARE/] [fpga_com.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 NikosAl
/*
2
 * Copyright (C) 2011 Simon A. Berger
3
 *
4
 *  This program is free software; you may redistribute it and/or modify its
5
 *  under the terms of the GNU Lesser General Public License as published by the Free
6
 *  Software Foundation; either version 2 of the License, or (at your option)
7
 *  any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful, but
10
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11
 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 *  for more details.
13
 */
14
 
15
 
16
#include <stdio.h>
17
 
18
#include <unistd.h>
19
#include <stdlib.h>
20
#include <string.h>
21
#include <assert.h>
22
 
23
#include "fpga_com.h"
24
#include <sys/socket.h>
25
#include <netinet/in.h>
26
#include <arpa/inet.h>
27
 
28
const size_t MAX_MTU = 64 * 1024;
29
 
30
static void die_perror( const char *call ) {
31
    perror( call );
32
    exit(-1);
33
}
34
 
35
 
36
void fpga_con_init( fpga_con_t *con, const void *daddr, int lport, int dport ) {
37
 
38
 
39
 
40
    /*set up local socket address*/
41
    memset( &con->l_sockaddr, 0, sizeof( con->l_sockaddr ));
42
    con->l_sockaddr.sin_family = AF_INET;
43
    con->l_sockaddr.sin_addr.s_addr = INADDR_ANY;
44
    con->l_sockaddr.sin_port = htons(lport);
45
 
46
    /*setup dest socket address*/
47
    memset( &con->d_sockaddr, 0, sizeof( con->d_sockaddr ));
48
    con->d_sockaddr.sin_family = AF_INET;
49
    con->d_sockaddr.sin_addr.s_addr = inet_addr( daddr );
50
    con->d_sockaddr.sin_port = htons(dport);
51
 
52
/*    create my socket*/
53
    con->s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
54
    if( con->s < 0 ) {
55
        die_perror( "socket" );
56
    }
57
 
58
/*    bind it to local socket*/
59
    int r = bind( con->s, (struct sockaddr *)&con->l_sockaddr, sizeof(con->l_sockaddr));
60
    if( r < 0 ) {
61
        die_perror( "bind" );
62
    }
63
    con->mtu = 1500;
64
}
65
 
66
size_t fpga_con_get_mtu( fpga_con_t *con ) {
67
 
68
    return con->mtu;
69
}
70
 
71
void fpga_con_set_mtu( fpga_con_t *con, size_t mtu ) {
72
 
73
    if( mtu > MAX_MTU ) {
74
        printf( "fpga_con_set_mtu: mtu > MAX_MTU\n" );
75
        exit(-1);
76
    }
77
    con->mtu = mtu;
78
}
79
 
80
 
81
ssize_t fpga_con_send( fpga_con_t *con, const void *buf, size_t len ) {
82
 
83
 
84
    ssize_t rsend = sendto( con->s, buf, len, 0, (struct sockaddr*)&con->d_sockaddr, sizeof(con->d_sockaddr));
85
    if( rsend < 0 ) {
86
        die_perror( "sendto" );
87
    }
88
 
89
    return rsend;
90
}
91
 
92
 
93
/* send lut initialization packet sequence: rst, conf, empty*/
94
void fpga_con_send_init_packet( fpga_con_t *con ) {
95
    uint8_t buf[4];
96
 
97
    buf[0] = 255;
98
    fpga_con_send( con, buf, 1);
99
 
100
    buf[0] = 15;
101
    fpga_con_send( con, buf, 1);
102
 
103
    fpga_con_send( con, buf, 0);
104
}
105
 
106
/*blocking receive: this call will block until a packet is received*/
107
ssize_t fpga_con_block_recv( fpga_con_t *con, void *dbuf, size_t dsize ) {
108
 
109
    ssize_t rrecv = recv( con->s, dbuf, dsize, 0 );
110
 
111
    if( rrecv < 0 ) {
112
        die_perror( "recv" );
113
    }
114
 
115
    return rrecv;
116
}
117
 
118
 
119
static __inline size_t mymin( size_t a, size_t b ) {
120
    return a < b ? a : b;
121
}
122
 
123
//const static size_t MTU = 1500;
124
const static size_t PH_SIZE = 1;
125
 
126
 
127
// static __inline size_t pack( uint8_t *buf, uint8_t ht, size_t buf_size, void *src, size_t src_size ) {
128
//     assert( src_size + PH_SIZR <= buf_size );
129
//     
130
//     buf[0] = ht;
131
//     memcpy( buf + PH_SIZE, src, src_size );
132
//     
133
//     return src_size + PH_SIZE;
134
// }
135
 
136
// TODO; check how large the impact of doing the byte swappin on unaligned values really is
137
// there is no simple way around it (like in the receiving direction).
138
static __inline void swappy_16( void *dest, void *src, size_t n ) {
139
    uint16_t *idest = (uint16_t*)dest;
140
    uint16_t *isrc = (uint16_t*)src;
141
 
142
    for( size_t i = 0; i < n / 2; i++ ) {
143
        idest[i] = __bswap_16(isrc[i]);
144
    }
145
}
146
 
147
static __inline void swappy_32( void *dest, void *src, size_t n ) {
148
    uint32_t *idest = (uint32_t*)dest;
149
    uint32_t *isrc = (uint32_t*)src;
150
 
151
    for( size_t i = 0; i < n / 4; i++ ) {
152
        idest[i] = __bswap_32(isrc[i]);
153
    }
154
 
155
}
156
 
157
 
158
static __inline void swappy_64( void *dest, void *src, size_t n ) {
159
    uint64_t *idest = (uint64_t*)dest;
160
    uint64_t *isrc = (uint64_t*)src;
161
 
162
    for( size_t i = 0; i < n / 8; i++ ) {
163
        idest[i] = __bswap_64(isrc[i]);
164
    }
165
}
166
 
167
#define BS_NONE  (0)
168
#define BS_16  (1)
169
#define BS_32  (2)
170
#define BS_64  (3)
171
 
172
static __inline size_t pack_and_send( fpga_con_t *con, uint8_t *buf, size_t buf_size, uint8_t ht, void *src, size_t src_size, int swap ) {
173
    const size_t pack_size = src_size + PH_SIZE;
174
 
175
    assert( pack_size <= buf_size );
176
 
177
    buf[0] = ht;
178
 
179
    switch( swap ) {
180
    case BS_NONE:
181
        memcpy( buf + PH_SIZE, src, src_size );
182
        break;
183
 
184
    case BS_16:
185
        swappy_16( buf + PH_SIZE, src, src_size );
186
        break;
187
 
188
    case BS_32:
189
        swappy_32( buf + PH_SIZE, src, src_size );
190
        break;
191
 
192
 
193
    case BS_64:
194
        swappy_64( buf + PH_SIZE, src, src_size );
195
        break;
196
 
197
    default:
198
        assert(0);
199
    }
200
 
201
    fpga_con_send( con, buf, pack_size );
202
 
203
    return src_size + PH_SIZE;
204
}
205
 
206
 
207
 
208
 
209
int fpga_con_send_charv( fpga_con_t *con, char *buf, size_t n ) {
210
 
211
 
212
    const size_t blocksize = (con->mtu - PH_SIZE);
213
    uint8_t sb[MAX_MTU];
214
 
215
    size_t sent = 0;
216
    while( sent < n ) {
217
        const size_t to_copy = mymin( blocksize, n - sent );
218
 
219
        pack_and_send( con, sb, con->mtu, FPC_CODE_CHAR, (void*) &buf[sent], to_copy, BS_NONE );
220
        sent += to_copy;
221
    }
222
 
223
    return 1;
224
 
225
}
226
 
227
int fpga_con_send_shortv( fpga_con_t *con, int16_t *buf, size_t n ) {
228
 
229
 
230
    const size_t TSIZE = sizeof( short );
231
 
232
    const size_t blocksize = (con->mtu - PH_SIZE) / TSIZE;
233
    uint8_t sb[MAX_MTU];
234
 
235
    size_t sent = 0;
236
    while( sent < n ) {
237
        const size_t to_copy = mymin( blocksize, n - sent );
238
 
239
        //fpga_con_send( con, (void*) &buf[sent], to_copy * TSIZE );
240
        pack_and_send( con, sb, con->mtu, FPC_CODE_SHORT, (void*) &buf[sent], to_copy * TSIZE, BS_16 );
241
 
242
        sent += to_copy;
243
 
244
    }
245
    return 1;
246
 
247
}
248
int fpga_con_send_intv( fpga_con_t *con, int32_t *buf, size_t n ) {
249
 
250
 
251
    const size_t TSIZE = sizeof( int );
252
 
253
    const size_t blocksize = (con->mtu - PH_SIZE) / TSIZE;
254
 
255
    uint8_t sb[MAX_MTU];
256
 
257
    size_t sent = 0;
258
    while( sent < n ) {
259
        const size_t to_copy = mymin( blocksize, n - sent );
260
 
261
//         fpga_con_send( con, (void*) &buf[sent], to_copy * TSIZE );
262
        pack_and_send( con, sb, con->mtu, FPC_CODE_INT, (void*) &buf[sent], to_copy * TSIZE, BS_32 );
263
 
264
        sent += to_copy;
265
 
266
    }
267
 
268
    return 1;
269
}
270
 
271
 
272
int fpga_con_send_longv( fpga_con_t *con, int64_t *buf, size_t n ) {
273
 
274
 
275
    const size_t TSIZE = sizeof( int64_t );
276
 
277
    const size_t blocksize = (con->mtu - PH_SIZE) / TSIZE;
278
 
279
    uint8_t sb[MAX_MTU];
280
 
281
    size_t sent = 0;
282
    while( sent < n ) {
283
        const size_t to_copy = mymin( blocksize, n - sent );
284
 
285
//         fpga_con_send( con, (void*) &buf[sent], to_copy * TSIZE );
286
        pack_and_send( con, sb, con->mtu, FPC_CODE_LONG, (void*) &buf[sent], to_copy * TSIZE, BS_64 );
287
 
288
        sent += to_copy;
289
 
290
    }
291
 
292
    return 1;
293
}
294
 
295
int fpga_con_send_floatv( fpga_con_t *con, float *buf, size_t n ) {
296
    const size_t TSIZE = sizeof( int );
297
 
298
    const size_t blocksize = (con->mtu - PH_SIZE) / TSIZE;
299
 
300
    uint8_t sb[MAX_MTU];
301
 
302
    size_t sent = 0;
303
    while( sent < n ) {
304
        const size_t to_copy = mymin( blocksize, n - sent );
305
 
306
//         fpga_con_send( con, (void*) &buf[sent], to_copy * TSIZE );
307
        pack_and_send( con, sb, con->mtu, FPC_CODE_FLOAT, (void*) &buf[sent], to_copy * TSIZE, BS_32 );
308
 
309
        sent += to_copy;
310
 
311
    }
312
 
313
    return 1;
314
}
315
 
316
int fpga_con_send_doublev( fpga_con_t *con, double *buf, size_t n ) {
317
 
318
 
319
    const size_t TSIZE = sizeof( double );
320
 
321
    const size_t blocksize = (con->mtu - PH_SIZE) / TSIZE;
322
 
323
    uint8_t sb[MAX_MTU];
324
 
325
 
326
    size_t sent = 0;
327
    while( sent < n ) {
328
        const size_t to_copy = mymin( blocksize, n - sent );
329
 
330
//         fpga_con_send( con, (void*) &buf[sent], to_copy * TSIZE );
331
        pack_and_send( con, sb, con->mtu, FPC_CODE_DOUBLE, (void*) &buf[sent], to_copy * TSIZE, BS_64 );
332
        sent += to_copy;
333
    }
334
 
335
    return 1;
336
}
337
 
338
static void fpga_con_rpack( fpga_con_t *con, int code, int size ) {
339
    char buf[3] = { 120, 0, 0 };
340
    buf[0] += code;
341
 
342
 
343
    assert( size > 0 && size < 0xffff );
344
    unsigned short ssize = size;
345
 
346
    swappy_16( &buf[1], &ssize, 2);
347
 
348
    fpga_con_send(con, buf, 3);
349
}
350
 
351
void fpga_con_rpack_char( fpga_con_t *con, int size ) {
352
    fpga_con_rpack( con, FPC_CODE_CHAR, size );
353
}
354
void fpga_con_rpack_short( fpga_con_t *con, int size ) {
355
    fpga_con_rpack( con, FPC_CODE_SHORT, size );
356
}
357
void fpga_con_rpack_int( fpga_con_t *con, int size ) {
358
    fpga_con_rpack( con, FPC_CODE_INT, size);
359
}
360
void fpga_con_rpack_long( fpga_con_t *con, int size ) {
361
    fpga_con_rpack( con, FPC_CODE_LONG, size);
362
}
363
 
364
void fpga_con_rpack_float( fpga_con_t *con, int size ) {
365
    fpga_con_rpack( con, FPC_CODE_FLOAT, size );
366
}
367
void fpga_con_rpack_double( fpga_con_t *con, int size ) {
368
    fpga_con_rpack( con, FPC_CODE_DOUBLE, size );
369
}
370
 

powered by: WebSVN 2.1.0

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