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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [software/] [spw/] [spwapi.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
/*****************************************************************************/
2
/*   This file is a part of the GRLIB VHDL IP LIBRARY */
3
/*   Copyright (C) 2004 GAISLER RESEARCH */
4
 
5
/*   This program is free software; you can redistribute it and/or modify */
6
/*   it under the terms of the GNU General Public License as published by */
7
/*   the Free Software Foundation; either version 2 of the License, or */
8
/*   (at your option) any later version. */
9
 
10
/*   See the file COPYING for the full details of the license. */
11
/*****************************************************************************/
12
 
13
#include "spwapi.h"
14
#include <stdlib.h>
15
 
16
static char *almalloc(int sz)
17
{
18
  char *tmp;
19
  tmp = calloc(1,2*sz);
20
  tmp = (char *) (((int)tmp+sz) & ~(sz -1));
21
  return(tmp);
22
}
23
 
24
static inline int loadmem(int addr)
25
{
26
  int tmp;
27
  asm(" lda [%1]1, %0 "
28
      : "=r"(tmp)
29
      : "r"(addr)
30
    );
31
  return tmp;
32
}
33
 
34
/* static void storemem(int addr, int data)  */
35
/* { */
36
/*         asm("sta %0, [%1]1 " */
37
/*             :  */
38
/*             : "r"(data), "r"(addr)  */
39
/*            ); */
40
/* } */
41
 
42
int spw_setparam(int nodeaddr, int clkdiv, int destkey,
43
                 int timetxen, int timerxen, int spwadr,
44
                 int khz, struct spwvars *spw)
45
{
46
  if ((nodeaddr < 0) || (nodeaddr > 255)) {
47
    return 1;
48
  }
49
  if ((clkdiv < 0) || (clkdiv > 255)) {
50
    return 1;
51
  }
52
  if ((destkey < 0) || (destkey > 255)) {
53
    return 1;
54
  }
55
  if ((timetxen < 0) || (timetxen > 1)) {
56
    return 1;
57
  }
58
  if ((timerxen < 0) || (timerxen > 1)) {
59
    return 1;
60
  }
61
  spw->timetxen = timetxen;
62
  spw->timerxen = timerxen;
63
  spw->destkey = destkey;
64
  spw->nodeaddr = nodeaddr;
65
  spw->clkdiv = clkdiv;
66
  spw->khz = khz;
67
  spw->regs = (struct spwregs *) spwadr;
68
  return 0;
69
}
70
 
71
int spw_setparam_dma(int dmachan, int addr, int mask, int nospill, int rxmaxlen, struct spwvars *spw)
72
{
73
  if ((addr < 0) || (addr > 255)) {
74
    return 1;
75
  }
76
  if ((mask < 0) || (mask > 255)) {
77
    return 1;
78
  }
79
  if ((rxmaxlen < 0) || (rxmaxlen > 33554432)) {
80
    return 1;
81
  }
82
  if ((nospill < 0) || (nospill > 1)) {
83
    return 1;
84
  }
85
  spw->dma[dmachan].nospill = nospill;
86
  spw->dma[dmachan].addr = addr;
87
  spw->dma[dmachan].mask = mask;
88
  spw->dma[dmachan].rxmaxlen = rxmaxlen;
89
  return 0;
90
}
91
 
92
 
93
int spw_init(struct spwvars *spw)
94
{
95
  int i;
96
  int j;
97
  int tmp;
98
  /*determine grspw version by checking if timer and disconnect register exists */
99
  spw->regs->timer = 0xFFFFFF;
100
  tmp = loadmem((int)&(spw->regs->timer));
101
  spw->ver = 0;
102
  if (!tmp)
103
          spw->ver = 1;
104
  tmp = loadmem((int)&(spw->regs->ctrl));
105
  spw->rmap = (tmp >> 31) & 1;
106
  spw->rxunaligned = (tmp >> 30) & 1;
107
  spw->rmapcrc = (tmp >> 29) & 1;
108
  spw->dmachan = ((tmp >> 27) & 3) + 1;
109
  spw->regs->nodeaddr = spw->nodeaddr; /*set node address*/
110
  spw->regs->clkdiv = spw->clkdiv | (spw->clkdivs << 8); /* set clock divisor */
111
 
112
  for(i = 0; i < spw->dmachan; i++) {
113
          spw->regs->dma[i].rxmaxlen = spw->dma[i].rxmaxlen; /*set rx maxlength*/
114
          if (loadmem((int)&(spw->regs->dma[i].rxmaxlen)) != spw->dma[i].rxmaxlen) {
115
                  return 1;
116
          }
117
  }
118
  if (spw->khz)
119
          spw->regs->timer = ((spw->khz*64)/10000) | ((((spw->khz*850)/1000000)-3) << 12);
120
  if (spw->rmap == 1) {
121
    spw->regs->destkey = spw->destkey;
122
  }
123
  for(i = 0; i < spw->dmachan; i++) {
124
          spw->regs->dma[i].ctrl = 0xFFFE01E0; /*clear status, set ctrl for dma chan*/
125
          if (loadmem((int)&(spw->regs->dma[i].ctrl)) != 0) {
126
                  return 2;
127
          }
128
          /*set tx descriptor pointer*/
129
          if ((spw->dma[i].txd = (struct txdescriptor *)almalloc(1024)) == NULL) {
130
                  return 3;
131
          }
132
          spw->dma[i].txpnt = 0;
133
          spw->dma[i].txchkpnt = 0;
134
          spw->regs->dma[i].txdesc = (int) spw->dma[i].txd;
135
          /*set rx descriptor pointer*/
136
          if (( spw->dma[i].rxd = (struct rxdescriptor *)almalloc(1024)) == NULL) {
137
                  return 4;
138
          }
139
          spw->dma[i].rxpnt = 0;
140
          spw->dma[i].rxchkpnt = 0;
141
          spw->regs->dma[i].rxdesc = (int) spw->dma[i].rxd;
142
  }
143
  spw->regs->status = 0xFFF; /*clear status*/
144
  spw->regs->ctrl = 0x2 | (spw->timetxen << 10) | (spw->timerxen << 11); /*set ctrl*/
145
  for(i = 0; i < spw->dmachan; i++) {
146
          spw->regs->dma[i].ctrl = loadmem((int)&(spw->regs->dma[i].ctrl)) | (spw->dma[i].nospill << 12);
147
  }
148
  return 0;
149
}
150
 
151
int wait_running(struct spwvars *spw)
152
{
153
        int i;
154
        int j;
155
 
156
        j = 0;
157
        while (((loadmem((int)&(spw->regs->status)) >> 21) & 7) != 5) {
158
                if (j > 1000) {
159
                        return 1;
160
                }
161
                for(i = 0; i < 1000; i++) {}
162
                j++;
163
        }
164
        return 0;
165
}
166
 
167
int set_txdesc(int dmachan, int pnt, struct spwvars *spw)
168
{
169
        spw->regs->dma[dmachan].txdesc = pnt;
170
        spw->dma[dmachan].txpnt = 0;
171
        spw->dma[dmachan].txchkpnt = 0;
172
        if (loadmem((int)&(spw->regs->dma[dmachan].txdesc)) != pnt) {
173
                return 1;
174
        }
175
        return 0;
176
}
177
 
178
int set_rxdesc(int dmachan, int pnt, struct spwvars *spw)
179
{
180
        spw->regs->dma[dmachan].rxdesc = pnt;
181
        spw->dma[dmachan].rxpnt = 0;
182
        spw->dma[dmachan].rxchkpnt = 0;
183
        if (loadmem((int)&(spw->regs->dma[dmachan].rxdesc)) != pnt) {
184
                return 1;
185
        }
186
        return 0;
187
}
188
 
189
void spw_disable(struct spwvars *spw)
190
{
191
        spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) | 1;
192
}
193
 
194
void spw_enable(struct spwvars *spw)
195
{
196
        spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) & 0x20F7E;
197
}
198
 
199
void spw_start(struct spwvars *spw)
200
{
201
        spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) | (1 << 1);
202
}
203
 
204
void spw_stop(struct spwvars *spw)
205
{
206
        spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) & 0x20F7D;
207
}
208
 
209
int spw_setclockdiv(struct spwvars *spw)
210
{
211
        if ( (spw->clkdiv < 0) || (spw->clkdiv > 255) ) {
212
                return 1;
213
        } else {
214
                spw->regs->clkdiv = spw->clkdiv;
215
                return 0;
216
        }
217
}
218
 
219
int spw_set_nodeadr(struct spwvars *spw)
220
{
221
        if ( (spw->nodeaddr < 0) || (spw->nodeaddr > 255) ||
222
             (spw->mask < 0) || (spw->mask > 255) ) {
223
                return 1;
224
        } else {
225
                spw->regs->nodeaddr = (spw->nodeaddr & 0xFF) | ((spw->mask & 0xFF) << 8);
226
                return 0;
227
        }
228
}
229
 
230
int spw_set_chanadr(int dmachan, struct spwvars *spw)
231
{
232
        if ( (spw->dma[dmachan].addr < 0) || (spw->dma[dmachan].addr > 255) ||
233
             (spw->dma[dmachan].mask < 0) || (spw->dma[dmachan].mask > 255) ) {
234
                return 1;
235
        } else {
236
                spw->regs->dma[dmachan].addr = (spw->dma[dmachan].addr & 0xFF) | ((spw->dma[dmachan].mask & 0xFF) << 8);
237
                return 0;
238
        }
239
}
240
 
241
int spw_set_rxmaxlength(int dmachan, struct spwvars *spw)
242
{
243
        if ((spw->dma[dmachan].rxmaxlen < 4) || (spw->dma[dmachan].rxmaxlen > 33554431)) {
244
                return 1;
245
        } else {
246
                spw->regs->dma[dmachan].rxmaxlen = spw->dma[dmachan].rxmaxlen;
247
                return 0;
248
        }
249
}
250
 
251
int spw_tx(int dmachan, int hcrc, int dcrc, int skipcrcsize, int hsize, char *hbuf, int dsize, char *dbuf, struct spwvars *spw)
252
{
253
  if ((dsize < 0) || (dsize > 16777215)) {
254
    return 6;
255
  }
256
  if ((hsize < 0) || (hsize > 255)) {
257
    return 5;
258
  }
259
  if ((dbuf == NULL) || (hbuf == NULL)) {
260
    return 4;
261
  }
262
  if ( (((hcrc == 1) || (dcrc == 1)) && ((spw->rmapcrc | spw->rmap) == 0)) || (hcrc < 0) || (hcrc > 1) || (dcrc < 0) || (dcrc > 1)) {
263
    return 3;
264
  }
265
  if ((skipcrcsize < 0) || (skipcrcsize > 15) ) {
266
    return 2;
267
  }
268
  if ((loadmem((int)&(spw->dma[dmachan].txd[spw->dma[dmachan].txpnt].ctrl)) >> 12) & 1) {
269
    return 1;
270
  }
271
  spw->dma[dmachan].txd[spw->dma[dmachan].txpnt].haddr = (int)hbuf;
272
  spw->dma[dmachan].txd[spw->dma[dmachan].txpnt].dlen = dsize;
273
  spw->dma[dmachan].txd[spw->dma[dmachan].txpnt].daddr = (int)dbuf;
274
  if (spw->dma[dmachan].txpnt == 63) {
275
    spw->dma[dmachan].txd[spw->dma[dmachan].txpnt].ctrl = 0x3000 | hsize | (hcrc << 16) | (dcrc << 17) | (skipcrcsize << 8);
276
    spw->dma[dmachan].txpnt = 0;
277
  } else {
278
    spw->dma[dmachan].txd[spw->dma[dmachan].txpnt].ctrl = 0x1000 | hsize | (hcrc << 16) | (dcrc << 17) | (skipcrcsize << 8);
279
    spw->dma[dmachan].txpnt++;
280
  }
281
  spw->regs->dma[dmachan].ctrl = loadmem((int)&(spw->regs->dma[dmachan].ctrl)) & 0xFAAA | 1;
282
 
283
  return 0;
284
}
285
 
286
int spw_rx(int dmachan, char *buf, struct spwvars *spw)
287
{
288
  if (((loadmem((int)&(spw->dma[dmachan].rxd[spw->dma[dmachan].rxpnt].ctrl)) >> 25) & 1)) {
289
    return 1;
290
  }
291
  spw->dma[dmachan].rxd[spw->dma[dmachan].rxpnt].daddr = (int)buf;
292
  if (spw->dma[dmachan].rxpnt == 127) {
293
    spw->dma[dmachan].rxd[spw->dma[dmachan].rxpnt].ctrl = 0x6000000;
294
    spw->dma[dmachan].rxpnt = 0;
295
  } else {
296
    spw->dma[dmachan].rxd[spw->dma[dmachan].rxpnt].ctrl = 0x2000000;
297
    spw->dma[dmachan].rxpnt++;
298
  }
299
  spw->regs->dma[dmachan].ctrl = loadmem((int)&(spw->regs->dma[dmachan].ctrl)) & 0xF955 | 2 | (1 << 11);
300
  return 0;
301
}
302
 
303
int spw_checkrx(int dmachan, int *size, struct rxstatus *rxs, struct spwvars *spw)
304
{
305
  int tmp;
306
  tmp = loadmem((int)&(spw->dma[dmachan].rxd[spw->dma[dmachan].rxchkpnt].ctrl));
307
  if (!((tmp >> 25) & 1)) {
308
    *size = tmp & 0x1FFFFFF;
309
    rxs->truncated = (tmp >> 31) & 1;
310
    rxs->dcrcerr = (tmp >> 30) & 1;
311
    rxs->hcrcerr = (tmp >> 29) & 1;
312
    rxs->eep = (tmp >> 28) & 1;
313
    if (spw->dma[dmachan].rxchkpnt == 127) {
314
      spw->dma[dmachan].rxchkpnt = 0;
315
    } else {
316
      spw->dma[dmachan].rxchkpnt++;
317
    }
318
    return 1;
319
  } else {
320
    return 0;
321
  }
322
}
323
 
324
int spw_checktx(int dmachan, struct spwvars *spw)
325
{
326
  int tmp;
327
  tmp = loadmem((int)&(spw->dma[dmachan].txd[spw->dma[dmachan].txchkpnt].ctrl));
328
  if (!((tmp >> 12) & 1)) {
329
    if (spw->dma[dmachan].txchkpnt == 63) {
330
      spw->dma[dmachan].txchkpnt = 0;
331
    } else {
332
      spw->dma[dmachan].txchkpnt++;
333
    }
334
    if ((tmp >> 15) & 1) {
335
      return 2;
336
    } else {
337
      return 1;
338
    }
339
  } else {
340
    return 0;
341
  }
342
}
343
 
344
void send_time(struct spwvars *spw)
345
{
346
  int i;
347
  while( ((loadmem((int)&(spw->regs->ctrl)) >> 4) & 1)) {
348
    for(i = 0; i < 16; i++) {}
349
  }
350
  spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) | (1 << 4);
351
}
352
 
353
int check_time(struct spwvars *spw)
354
{
355
  int tmp = loadmem((int)&(spw->regs->status)) & 1;
356
  if (tmp) {
357
    spw->regs->status = loadmem((int)&(spw->regs->status)) | 1;
358
  }
359
  return tmp;
360
}
361
 
362
int get_time(struct spwvars *spw)
363
{
364
  return (loadmem((int)&(spw->regs->timereg)) & 0x3F );
365
}
366
 
367
void spw_reset(struct spwvars *spw)
368
{
369
  spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) | (1 << 6);
370
}
371
 
372
void spw_rmapen(struct spwvars *spw)
373
{
374
  spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) | (1 << 16);
375
}
376
 
377
void spw_rmapdis(struct spwvars *spw)
378
{
379
  spw->regs->ctrl = loadmem((int)&(spw->regs->ctrl)) & 0xEFFFF;
380
}
381
 
382
int spw_setdestkey(struct spwvars *spw)
383
{
384
  if ((spw->destkey < 0) || (spw->destkey > 255)) {
385
    return 1;
386
  }
387
  spw->regs->destkey = spw->destkey;
388
  return 0;
389
}
390
 
391
void spw_setsepaddr(int dmachan, struct spwvars *spw)
392
{
393
        spw->regs->dma[dmachan].ctrl = loadmem((int)&(spw->regs->dma[dmachan].ctrl)) | (1 << 13);
394
}
395
 
396
void spw_disablesepaddr(int dmachan, struct spwvars *spw)
397
{
398
        spw->regs->dma[dmachan].ctrl = loadmem((int)&(spw->regs->dma[dmachan].ctrl)) & 0xFFFFDFFF;
399
}
400
 
401
 
402
void spw_enablerx(int dmachan, struct spwvars *spw)
403
{
404
        spw->regs->dma[dmachan].ctrl = loadmem((int)&(spw->regs->dma[dmachan].ctrl)) | 0x2;
405
}
406
 
407
 
408
void spw_disablerx(int dmachan, struct spwvars *spw)
409
{
410
        spw->regs->dma[dmachan].ctrl = loadmem((int)&(spw->regs->dma[dmachan].ctrl)) & 0xFFFFFFFD;
411
}
412
 

powered by: WebSVN 2.1.0

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