GPLv2
[s3load.git] / libnexys.parport.c
1 /* libnexys.c
2  * Parallel port bit-banging driver for libnexys
3  * libnexys, a free driver for Digilent NEXYS2 boards
4  *
5  * Copyright (c) 2007-2008 Joshua Wise
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License.
10  *
11  * Commercial licenses are available by request.
12  */
13
14
15 #ifdef WIN32
16 #include "libnexys.win32.c"
17 #else
18 #define LIBNEXYS_INTERNAL
19 #ifndef PARPORT
20 #  define PARPORT
21 #endif
22 #include "libnexys.h"
23 #include <stdio.h>
24 #include <fcntl.h>
25 #include <linux/ioctl.h>
26 #include <linux/ppdev.h>
27 #include <string.h>
28
29 #define TDI     0
30 #define TCK     1
31 #define TMS     2
32 #define TDO     4
33
34
35 nexys2_t nexys2_init(void) {
36         int pfd = open("/dev/parport0", O_RDWR);
37         if (pfd < 0)
38         {
39                 perror("open /dev/parport0");
40                 return -1;
41         }
42         
43         if ((ioctl(pfd, PPEXCL) < 0) || (ioctl(pfd, PPCLAIM) < 0))
44         {
45                 perror("lock /dev/parport0");
46                 return -1;
47         }
48         
49         return pfd;
50 }
51
52 int nexys2_jtag_enable(int pfd)
53 {
54         return 0;
55 }
56
57 int nexys2_jtag_disable(int pfd)
58 {
59         return 0;
60 }
61
62 int nexys2_jtag_setbits(int pfd, int tms, int tdi, int tck)
63 {
64         unsigned char data;
65         int i;
66         
67         data = ((!!tms) << TMS) | ((!!tdi) << TDI) | ((!!tck) << TCK);
68         
69         if (ioctl(pfd, PPWDATA, &data) < 0)
70         {
71                 perror("nexys2_jtag_setbits: ioctl");
72                 return -1;
73         }
74         
75         return 0;
76 }
77
78 int _gettdo(int pfd)
79 {
80         unsigned char data;
81         
82         if (ioctl(pfd, PPRSTATUS, &data) < 0)
83         {
84                 perror("_gettdi: PPRSTATUS");
85                 return -1;
86         }
87         
88         data ^= 0x80;
89         data >>= TDO;
90         data &= 1;
91         
92         return data;
93 }
94
95 int nexys2_jtag_puttdi(int pfd, int tms, int nbits, unsigned char *bits, unsigned char *obits)
96 {
97         int i;
98         
99         if (obits)
100                 memset(obits, 0, (nbits / 8) + ((nbits % 8) != 0));
101         
102         for (i = 0; i < nbits; i++)
103         {
104                 int bit;
105                 
106                 bit = bits[i / 8] & (1 << (i % 8));
107                 nexys2_jtag_setbits(pfd, tms, bit, 1);
108                 nexys2_jtag_setbits(pfd, tms, bit, 0);
109                 if (obits)
110                         obits[i/8] |= _gettdo(pfd) << (i % 8);
111         }
112         return 0;
113 }
114
115 int nexys2_jtag_puttmstdi(int pfd, int nbits, unsigned char *bits, unsigned char *obits)
116 {
117         int i;
118         
119         if (obits)
120                 memset(obits, 0, (nbits / 8) + ((nbits % 8) != 0));
121         
122         for (i = 0; i < nbits; i++)
123         {
124                 int tdi, tms;
125                 
126                 tdi = bits[i / 4] & (1 << ((i % 4) * 2));
127                 tms = bits[i / 4] & (2 << ((i % 4) * 2));
128                 nexys2_jtag_setbits(pfd, tms, tdi, 0);
129                 nexys2_jtag_setbits(pfd, tms, tdi, 1);
130                 nexys2_jtag_setbits(pfd, tms, tdi, 0);
131                 if (obits)
132                         obits[i/8] |= _gettdo(pfd) << (i % 8);
133         }
134         return 0;
135 }
136
137 int nexys2_jtag_gettdo(int pfd, int tdi, int tms, int nbits, unsigned char *obits)
138 {
139         int i;
140         
141         if (obits)
142                 memset(obits, 0, (nbits / 8) + ((nbits % 8) != 0));
143         
144         for (i = 0; i < nbits; i++)
145         {
146                 nexys2_jtag_setbits(pfd, tms, tdi, 0);
147                 nexys2_jtag_setbits(pfd, tms, tdi, 1);
148                 nexys2_jtag_setbits(pfd, tms, tdi, 0);
149                 if (obits)
150                         obits[i/8] |= _gettdo(pfd) << (i % 8);
151         }
152         return 0;
153 }
154
155 #endif
156
157 #ifdef TEST_DRIVER
158
159 void poke_idcode(nexys2_t nexys)
160 {
161         unsigned char seq1[] = { 0xaa, 0x22};
162         unsigned char seq2[] = { 0xaa, 0x02};
163         unsigned int idcode = 0;
164         unsigned int woop = 0x12345678;
165         
166 //      while(1)
167         {
168                 while (nexys2_jtag_enable(nexys) < 0)
169                         ;
170                 if (nexys2_jtag_puttmstdi(nexys, 8, seq1, NULL) < 0)
171                         return;
172                 do
173                 {
174                         if (nexys2_jtag_gettdo(nexys, 0, 0, 32, &idcode) < 0)
175                                 return;
176                         printf("IDCODE: %08x\n", idcode);
177                 } while(idcode && (idcode != 0xFFFFFFFF));
178                 if (nexys2_jtag_puttmstdi(nexys, 8, seq2, NULL) < 0)
179                         return;
180                 if (nexys2_jtag_disable(nexys) < 0)
181                         return;
182         }
183 }
184
185 void main()
186 {
187         nexys2_t nexys;
188         nexys = nexys2_init();
189         if (!nexys)
190                 return;
191         poke_idcode(nexys);
192 }
193
194 #endif
195
This page took 0.028558 seconds and 4 git commands to generate.