up io error count if not exiting
[tridge/junkcode.git] / scrolly.c
1 /* scrolly_drv.c - kernel module driver for the scrolling LED display */
2
3 /* Copyright 1998 */
4
5 /* by David Austin */
6
7 /* includes */
8
9 #include "scrolly.h"
10
11 /* defines */
12
13 #define LPT 0x278 /* the address of the parallel port */
14 #define STACK_SIZE 4096
15 #define PRIORITY 1
16 #define bash_port(data)   outb(~((char) (data)), LPT)
17
18 /* parts of the parallel port we use */
19
20 #define SRCLK 0x01
21 #define LOAD  0x02
22 #define SRDTA 0x04
23 #define RESET 0x08
24
25 /* globals */
26
27 RT_TASK mytask;
28 static int row_count = 0; /* the number of the next row to be output */
29
30 /*****************************************************************************/
31
32 void output_row(unsigned char *rp) {
33   static char i;
34   static unsigned char mask;
35   
36   mask = 0x80 >> row_count;
37
38   for (i = ROW_LENGTH - 1; i >= 0; i--) {
39     if ((rp[i] & mask) > 0)
40       { /* clock a 1 through */
41         bash_port(SRDTA);
42         bash_port(SRDTA + SRCLK);
43       }
44     else 
45       { /* clock a 0 through*/
46         bash_port(0x00);
47         bash_port(SRCLK);
48       }
49   }
50
51   /* If we just sent the first row then do a reset+load */
52   if (row_count == 0)
53     {
54       bash_port(RESET);
55       bash_port(RESET + LOAD);
56       bash_port(0x00);
57     }
58   else 
59     {    
60       bash_port(LOAD);
61       bash_port(0x00);
62     }
63
64
65   /* Update row_count */
66   row_count++;
67   if (row_count == NUM_ROWS)
68     row_count = 0;
69 }
70
71 /*****************************************************************************/
72
73 void drv_loop(int dummy)
74 {
75   unsigned char row[ROW_LENGTH];
76   int i;
77
78   /* Empty the buffer */
79   for (i = 0; i < ROW_LENGTH; i++)
80     row[i] = 0x00;
81
82   /* Start the refresh */
83   while (1)
84     {
85       /* Check for row data */
86       if (row_count == 0)
87         rtf_get(1, row, sizeof(row));
88       
89       /* Do the refresh */
90       output_row(row);
91
92       /* Suspend until re-started by the rt-kernel */
93       rt_task_wait();
94     }
95 }
96
97 /*****************************************************************************/
98
99 int init_module(void)
100 {
101   rtf_create(1, ROW_LENGTH * 100); /* FIFO for row data */
102
103   outb(0x80, (LPT + 3)); /* set all pins as outputs */
104
105   row_count = 0;
106
107   rt_task_init(&mytask, drv_loop, 0, STACK_SIZE, PRIORITY);
108
109   rt_task_make_periodic(&mytask, rt_get_time(), 
110                         (RT_TICKS_PER_SEC * 1.5) / 1000);
111
112   return 0;
113 }
114
115 /*****************************************************************************/
116
117 void cleanup_module(void)
118 {
119   rt_task_delete(&mytask);
120 }
121
122