Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 pj 1
/*
2
 * Project:
3
 *   Parallel Port S.Ha.R.K. Project
4
 *
5
 * Module:
6
 *   ppDrv.c
7
 *
8
 * Description:
9
 *   file contents description
10
 *
11
 * Coordinators:
12
 *   Giorgio Buttazzo    <giorgio@sssup.it>
13
 *   Paolo Gai           <pj@gandalf.sssup.it>
14
 *
15
 * Authors:
16
 *   Andrea Battistotti <btandrea@libero.it>
17
 *   Armando Leggio     <a_leggio@hotmail.com>
18
 *
19
 *
20
 * http://www.sssup.it
21
 * http://retis.sssup.it
22
 * http://shark.sssup.it
23
 *
24
 */
25
 
26
/**********************************************************************************************************
27
 * Module : ppDrv.c Author : Andrea Battistotti , Armando Leggio
28
 * Description: Tranfer Byte via LPT1 laplink cable...  2002 @ Pavia -
29
 * GNU Copyrights */
30
 
31
/*
32
 * Copyright (C) 2002 Andrea Battistotti , Armando Leggio
33
 *
34
 * This program is free software; you can redistribute it and/or modify
35
 * it under the terms of the GNU General Public License as published by
36
 * the Free Software Foundation; either version 2 of the License, or
37
 * (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
47
 *
48
 * CVS : $Id: ppdrv.c,v 1.1 2002-10-28 08:03:54 pj Exp $
49
 */
50
 
51
 
52
#include <drivers/parport.h>
53
 
54
 
55
/* internal */
56
BYTE RxBuf[PP_BUF_LEN];                         /* Received bytes buffer */
57
BYTE TxBuf[PP_BUF_LEN];                         /* To transmit bytes buffer */
58
 
59
unsigned int nextByteReadyToRx;   /* pointer to first byte to read by ppOneByteRx(BYTE *c) ... */
60
unsigned int nextByteReadyToTx;   /* when ppbTransmit had to send a byte, send this...*/
61
unsigned int nextByteFreeRx;      /* when polling complete reading a byte, will save it in this loc...*/
62
unsigned int nextByteFreeTx;      /* when ppbTransmit had to write a byte, write it here...*/
63
 
64
/* define inline macro */
65
/* these are for cicle buffer mamagement */
66
#define RxPointerGap            (nextByteFreeRx-nextByteReadyToRx)
67
#define bytesReadyToRx      ((RxPointerGap)>=0? (RxPointerGap):PP_BUF_LEN+(RxPointerGap))
68
#define TxPointerGap            (nextByteFreeTx-nextByteReadyToTx)
69
#define bytesReadyToTx      ((TxPointerGap)>=0? (TxPointerGap):PP_BUF_LEN+(TxPointerGap))
70
#define freeBytesInRxBuffer (PP_BUF_LEN-bytesReadyToRx)
71
#define freeBytesInTxBuffer (PP_BUF_LEN-bytesReadyToTx)
72
 
73
 
74
/* for pp sys msg */
75
char SysMsg[SYS_MSG_COLS+1][SYS_MSG_LINS+1];    /* space for sys msgs... */
76
char bufMsg[SYS_MSG_COLS+1];                                    /* to build msgs... */
77
 
78
unsigned int nextMsgToRead;
79
unsigned int nextMsgFreeToWrite;
80
 
81
/* define inline macro */
82
/* these are for cicle buffer mamagement */
83
#define msgPointerGap           (nextMsgFreeToWrite-nextMsgToRead)
84
#define msgReadyToRead      ((msgPointerGap)>=0? (msgPointerGap):SYS_MSG_LINS+(msgPointerGap))
85
#define freeMsgInBuffer     (SYS_MSG_LINS-msgReadyToRead)
86
 
87
 
88
 
89
 
90
/* status ... */
91
enum ppReadingAvailableStates
92
{
93
  ppNoAllowReading,      /* writing is on...*/ 
94
  ppNoReading,
95
  ppWaitingDR_Nibble1,
96
  ppWaitingRTS_Nibble2,
97
  ppWaitingDR_Nibble2,
98
};
99
 
100
enum ppWritingAvailableStates
101
{
102
  ppNoAllowWriting,      /* reading is on...*/
103
  ppNoWriting,
104
  ppWaitingOTS_Nibble1,
105
  ppWaitingER_Nibble1,
106
  ppWaitingOTS_Nibble2,
107
  ppWaitingER_Nibble2
108
};
109
 
110
 
111
int ppStatusReading;
112
int ppStatusWriting;
113
BYTE ppReceivingByte;
114
BYTE ppTransmittingByte;
115
 
116
 
117
#if PP_STATS == 1
118
/* for internal statistic ...if activate...*/
119
long statReading[ppWaitingDR_Nibble2+1];
120
long statWriting[ppWaitingER_Nibble2+1];
121
#endif
122
 
123
 
124
 
125
/*********************************************/
126
/* sys msg managment */
127
/*********************************************/
128
 
129
int ppReadSysMsg(char * buf)
130
{
131
  if (!msgReadyToRead)                                  /* there is nothing to read...*/
132
    {
133
      return (PP_NOSYSMSG_EXC);
134
    }
135
  else
136
    {int i=0;
137
    while (i<SYS_MSG_COLS && SysMsg[nextMsgToRead][i])   /* !='\0'...*/
138
      *buf++=SysMsg[nextMsgToRead][i++];                        /* read char */
139
 
140
    *buf='\0'; 
141
    nextMsgToRead=++nextMsgToRead%SYS_MSG_LINS;         /* circular buffer increment */
142
    return (PP_SYSMSG_OK);
143
    }
144
}
145
 
146
 
147
 
148
int ppWriteSysMsg(char * buf, ...)
149
{
150
  char * pbufMsg=bufMsg;
151
  va_list args;
152
  bufMsg[0]='\0';
153
  va_start(args, buf);
154
  vsprintf(bufMsg,buf,args);    /* Not garatee msg len... */  
155
  va_end(args);
156
 
157
 
158
  if (freeMsgInBuffer < 1)
159
    {
160
      return (PP_NOFREEMSG_EXC);
161
    }
162
  else
163
    {int i=0;
164
    while ((i<SYS_MSG_COLS) && (*pbufMsg) )   /* !='\0'...*/        
165
      SysMsg[nextMsgFreeToWrite][i++]=*pbufMsg++;
166
 
167
    SysMsg[nextMsgFreeToWrite][i-1]='\n';
168
    SysMsg[nextMsgFreeToWrite][i]='\0';
169
    nextMsgFreeToWrite=++nextMsgFreeToWrite%SYS_MSG_LINS; /* circular buffer pointer increment */
170
    return (PP_SYSMSG_OK);
171
    }
172
}
173
 
174
 
175
/******************************************/
176
/*   Inizialization: this is NRT task...  */
177
/******************************************/
178
 
179
void ppInitDrv(void (*pf)(char *))
180
{
181
  /* set to zero all pointer & buffer & status... */
182
 
183
 
184
  while(ppNRTOpenComm()!=TRUE)   // not real-time....
185
    {
186
      if (pf!=NULL) (*pf)("Waiting Open Communcation...\n");
187
      ppSendER();
188
    }
189
  if (pf!=NULL) (*pf)("Open Communcation OK!\n");
190
}
191
 
192
 
193
/******************************************/
194
/* TX RX funtions... */
195
/******************************************/
196
 
197
int ppRxOneByte(BYTE *c)
198
{                  
199
  if (!bytesReadyToRx)                                  /* there is nothing to read...*/
200
    {
201
      return (PP_COMM_NOREADYBYTES_EXC);
202
    }
203
  else
204
    {
205
      *c=RxBuf[nextByteReadyToRx];                              /* read byte */
206
      nextByteReadyToRx=++nextByteReadyToRx%PP_BUF_LEN;         /* circular buffer increment */
207
      return (PP_COMM_OK);
208
    }
209
}
210
 
211
 
212
int ppTxOneByte(BYTE c)
213
{
214
  if (freeBytesInTxBuffer < 1)
215
    {
216
      return (PP_COMM_NOFREEBYTES_EXC);
217
    }
218
  else
219
    {
220
      TxBuf[nextByteFreeTx]=c;
221
      nextByteFreeTx=++nextByteFreeTx%PP_BUF_LEN; /* circular buffer pointer increment */
222
 
223
      return (PP_COMM_OK);
224
    }
225
}
226
 
227
int ppTxBytes(BYTE * c, unsigned int  nbyte)
228
{
229
  if (freeBytesInTxBuffer<nbyte)                                        /* if there are less than nbyte return nothing...*/
230
    {
231
      return (PP_COMM_NOFREEBYTES_EXC);
232
    }
233
  else
234
    { unsigned int i;
235
    for (i=0;i<nbyte;i++)
236
      {
237
        TxBuf[nextByteFreeTx]=*c++;
238
        nextByteFreeTx=++nextByteFreeTx%PP_BUF_LEN; /* circular buffer pointer increment */
239
      }
240
 
241
    return (PP_COMM_OK);
242
    }
243
}
244
 
245
 
246
 
247
int ppRxBytes(BYTE * c, unsigned int nbyte)
248
{
249
 
250
  if (bytesReadyToRx<nbyte)           /* if there are less than nbyte return nothing...*/
251
    {
252
      return (PP_COMM_NOREADYBYTES_EXC);
253
    }
254
  else
255
    { unsigned int i;
256
 
257
    for (i=0;i<nbyte;i++)
258
      {
259
        *c++=RxBuf[nextByteReadyToRx];                          /* read byte */
260
 
261
#if PP_DEBUG == 1
262
        ppWriteSysMsg("Received value: %i %i of %i \n",RxBuf[nextByteReadyToRx],i,nbyte);
263
#endif
264
 
265
        nextByteReadyToRx=++nextByteReadyToRx%PP_BUF_LEN;       /* circular buffer increment */
266
      }
267
 
268
    return (PP_COMM_OK);
269
    }
270
}
271
 
272
 
273
 
274
 
275
/* polling server ... */
276
TASK ppPollingSvr(void *arg)
277
{
278
  BYTE port;
279
  nextByteReadyToRx=0;
280
  nextByteReadyToTx=0;          
281
  nextByteFreeRx=0;  
282
  nextByteFreeTx=0;
283
 
284
  nextMsgToRead=0;
285
  nextMsgFreeToWrite=0;
286
 
287
 
288
  ppStatusReading=ppNoReading;
289
  ppStatusWriting=ppNoWriting;
290
 
291
  ppWriteSysMsg("Polling Server started...\n");
292
 
293
  task_endcycle();
294
 
295
  while (1)
296
    {
297
 
298
      /* case ppReading: read ... */
299
      switch (ppStatusReading)
300
        {
301
        case ppNoAllowReading: break;
302
 
303
        case ppNoReading:
304
 
305
          ppStatusWriting=ppNoWriting;
306
 
307
          if(!ppIsRTS())   break;
308
          ppSendOTS();     /* Set Ok To Send - the other one can send... */
309
 
310
#if PP_DEBUG == 1
311
          ppWriteSysMsg(" %i : Received RTS...\n", ppStatusReading);
312
#endif
313
 
314
          ppStatusWriting=ppNoAllowWriting;
315
          ppStatusReading=ppWaitingDR_Nibble1;
316
 
317
        case ppWaitingDR_Nibble1:
318
 
319
#if PP_STATS == 1                              /* for internal statistic ...*/
320
          statReading[ppStatusReading]++;
321
#endif
322
 
323
 
324
 
325
#if PP_DEBUG == 1 
326
          ppWriteSysMsg("Send OTS\n");
327
          ppWriteSysMsg("Waiting DR Nibble1\n");
328
#endif
329
 
330
          if(!ppIsDR()) break;                /* data no ready: read it next period...*/
331
          port = inp(RX_PORT);                       /* read  nibble    */
332
          ppSendER();                                                              /* send a End Read */
333
 
334
          ppReceivingByte = (port >> 3);             /* read LSN */
335
          ppStatusReading=ppWaitingRTS_Nibble2;
336
 
337
        case ppWaitingRTS_Nibble2:
338
#if PP_STATS == 1                                       /* for internal statistic ...*/
339
          statReading[ppStatusReading]++;
340
#endif
341
 
342
#if PP_DEBUG == 1
343
 
344
          ppWriteSysMsg("Received DR Nibble1\n");
345
          ppWriteSysMsg("Send ER Nibble1\n");
346
          ppWriteSysMsg("Waiting RTS Nibble2\n");
347
#endif
348
 
349
          if(!ppIsRTS()) break;           /* */
350
          ppSendOTS();                       /* Ok To Send - the other one can send... */
351
 
352
          ppStatusReading=ppWaitingDR_Nibble2;
353
 
354
        case ppWaitingDR_Nibble2:
355
#if PP_STATS == 1                                       /* for internal statistic ...*/
356
          statReading[ppStatusReading]++;
357
#endif
358
#if PP_DEBUG == 1
359
          ppWriteSysMsg("Received RTS Nibble2\n");
360
          ppWriteSysMsg("Send OTS Nibble2\n");
361
          ppWriteSysMsg("Waiting DR Nibble2\n");
362
#endif
363
 
364
          if(!ppIsDR()) break;
365
          port = inp(RX_PORT);                 /* read nibble    */
366
          ppSendER();                          /* send a End Read */
367
 
368
 
369
#if PP_DEBUG == 1
370
          ppWriteSysMsg("Received DR Nibble2\n");
371
          ppWriteSysMsg("Read Nibble2\n");
372
          ppWriteSysMsg("Send ER Nibble2\n");
373
#endif
374
 
375
 
376
 
377
          ppReceivingByte = (ppReceivingByte & ~MSN);               /* set to zero c MSN */
378
          ppReceivingByte = (ppReceivingByte | ((port >> 3) << 4)); /* read MSN */
379
 
380
 
381
                                /* here is possible insert some ctrl ... */
382
 
383
 
384
                                /* byte is ok, so now make it available to ppRxOneByte() */
385
 
386
          RxBuf[nextByteFreeRx]=ppReceivingByte;
387
          nextByteFreeRx=++nextByteFreeRx%PP_BUF_LEN; /* circular buffer pointer increment */
388
 
389
#if PP_STATS == 1
390
          ppWriteSysMsg("Trasmission :\n");
391
          ppWriteSysMsg("W_DR_1  : %d\n",statReading[ppWaitingDR_Nibble1]);
392
          ppWriteSysMsg("W_RTS_2 : %d\n",statReading[ppWaitingRTS_Nibble2]);
393
          ppWriteSysMsg("W_DR_2  : %d\n",statReading[ppWaitingDR_Nibble2]);
394
          ppWriteSysMsg("Received byte : %i\n",ppReceivingByte);
395
          statReading[ppWaitingDR_Nibble1]=0;
396
          statReading[ppWaitingRTS_Nibble2]=0;
397
          statReading[ppWaitingDR_Nibble2]=0;
398
#endif
399
          /* end reading so reset status... */
400
 
401
          ppStatusReading=ppNoReading;
402
          //ppStatusWriting=ppNoWriting;
403
          break;                                                               
404
        }
405
 
406
 
407
      /* case Writing: can only if this cycle not is reading... */
408
      switch (ppStatusWriting)
409
        {
410
 
411
        case ppNoAllowWriting: break;
412
 
413
        case ppNoWriting:
414
 
415
          ppStatusReading=ppNoReading;
416
 
417
          if(!bytesReadyToTx)
418
            {
419
              break;
420
#if PP_DEBUG == 1
421
              ppWriteSysMsg("Writin break\n");
422
#endif
423
            }
424
          else  
425
            {
426
#if PP_DEBUG == 1
427
              ppWriteSysMsg("NO Writin break\n");
428
              ppWriteSysMsg("TX Gap: %i \n",TxPointerGap);
429
              ppWriteSysMsg("nextByteFreeTx: %i\n",nextByteFreeTx);
430
              ppWriteSysMsg("nextByteReadyToTx: %i\n",nextByteReadyToTx);
431
#endif
432
            }
433
 
434
          ppSendRTS();                                 /* Set On RequestToSend bit */
435
 
436
          ppTransmittingByte=TxBuf[nextByteReadyToTx];
437
 
438
#if PP_DEBUG == 1
439
          ppWriteSysMsg("pllsvr: ppTransmittingByte : %i %c \n",ppTransmittingByte,ppTransmittingByte);
440
#endif
441
 
442
 
443
          port = inp(TX_PORT) & (~TX_DATA);            /* set to zero trasmission bits */
444
          port = port | (ppTransmittingByte & LSN);    /* set  bits 0..3 with LSN   */
445
 
446
          ppStatusWriting=ppWaitingOTS_Nibble1;
447
          ppStatusReading=ppNoAllowWriting;
448
 
449
        case ppWaitingOTS_Nibble1:
450
#if PP_STATS == 1                          
451
          statWriting[ppStatusWriting]++;
452
#endif
453
 
454
#if PP_DEBUG == 1                               
455
          ppWriteSysMsg(" Send RTS Nibble1\n");
456
          ppWriteSysMsg(" Waiting OTS Nibble1\n");
457
#endif
458
          if(!ppIsOTS()) break;
459
          outp(TX_PORT,port);                   /* send nibble 1   */
460
          ppSendDR();                                 /* set on Data Ready bit  */
461
 
462
 
463
          ppStatusWriting=ppWaitingER_Nibble1;
464
 
465
 
466
        case ppWaitingER_Nibble1:
467
#if PP_STATS == 1        
468
          statWriting[ppStatusWriting]++;
469
#endif
470
 
471
#if PP_DEBUG == 1
472
          ppWriteSysMsg(" Send Nibble1\n");
473
          ppWriteSysMsg(" Send DR Nibble1\n");
474
          ppWriteSysMsg(" Waiting ER Nibble1\n");
475
#endif
476
 
477
          if(!ppIsER()) break;
478
 
479
          ppSendRTS();                                 /* send trasmission request */
480
 
481
          port = inp(TX_PORT) & (~TX_DATA);            /* set to zero bit trasmission bits */
482
          port = port | (ppTransmittingByte >> 4);     /* set  bits 0..3 with MSN   */
483
 
484
          ppStatusWriting=ppWaitingOTS_Nibble2;
485
 
486
        case ppWaitingOTS_Nibble2:
487
 
488
#if PP_STATS == 1
489
          statWriting[ppStatusWriting]++;
490
#endif
491
 
492
#if PP_DEBUG == 1
493
          ppWriteSysMsg(" Received ER Nibble1\n");
494
          ppWriteSysMsg(" Send RTS Nibble2\n");
495
          ppWriteSysMsg(" Waiting OTS Nibble2\n");
496
#endif
497
 
498
 
499
          if(!ppIsOTS()) break;
500
          outp(TX_PORT,port);                           /* send nibble 2          */
501
          ppSendDR();                                   /* set on Data Ready bit  */
502
 
503
          ppStatusWriting=ppWaitingER_Nibble2;
504
 
505
        case ppWaitingER_Nibble2:
506
#if PP_STATS == 1                               
507
          statWriting[ppStatusWriting]++;
508
#endif
509
 
510
#if PP_DEBUG == 1
511
          ppWriteSysMsg(" Received OTS Nibble2\n");
512
          ppWriteSysMsg(" Write Nibble2\n");
513
          ppWriteSysMsg(" Send DR Nibble2\n");
514
          ppWriteSysMsg(" Waiting ER Nibble2\n");
515
#endif
516
 
517
          if(!ppIsER()) break;
518
 
519
                                /* byte is ok, so move pointer to next byte to be send... */
520
          nextByteReadyToTx=++nextByteReadyToTx%PP_BUF_LEN; /* circular buffer pointer increment */
521
 
522
#if PP_STATS == 1 
523
          ppWriteSysMsg("Reception :\n");
524
          ppWriteSysMsg("W_OTS_1  : %ld\n",statWriting[ppWaitingOTS_Nibble1]);
525
          ppWriteSysMsg("W_ER_2 : %ld\n",statWriting[ppWaitingER_Nibble2]);
526
          ppWriteSysMsg("W_OTS_2  : %ld\n",statWriting[ppWaitingOTS_Nibble2]);
527
          statWriting[ppWaitingOTS_Nibble1]=0;
528
          statWriting[ppWaitingER_Nibble2]=0;
529
          statWriting[ppWaitingOTS_Nibble2]=0;
530
#endif
531
 
532
          /* end writing. so reset status... */
533
          ppStatusReading=ppNoReading;
534
          ppStatusWriting=ppNoWriting;
535
        }                      
536
 
537
      task_endcycle();
538
    }                                                
539
  return (0);
540
}
541
 
542
 
543