]> rtime.felk.cvut.cz Git - mf6xx.git/blob - src/uio/mf624/userspace/test_application/main.c
Merge branch 'master' of rtime.felk.cvut.cz:mf6xx
[mf6xx.git] / src / uio / mf624 / userspace / test_application / main.c
1 #include <stdio.h>
2 #include <errno.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <dirent.h>
8 #include <sys/types.h>
9 #include <sys/mman.h>
10 #include <stdint.h> // uintX_t
11 #include <unistd.h>
12
13 #define BUFF_SMALL      32
14 #define BUFF_MID        256
15 #define min(a, b)       ((a) > (b) ? (b) : (a))
16
17 /* Hardware specific */
18 #define DOUT_reg        0x10
19
20 #define BAR0_offset     (0 * sysconf(_SC_PAGESIZE))
21 #define BAR2_offset     (1 * sysconf(_SC_PAGESIZE))
22 #define BAR4_offset     (2 * sysconf(_SC_PAGESIZE))
23
24 int status;
25 void* mf624_BAR0 = NULL;
26 void* mf624_BAR2 = NULL;
27 void* mf624_BAR4 = NULL;
28 int BAR0_phys_addr;
29 int BAR2_phys_addr;
30 int BAR4_phys_addr;
31
32 void print_8bin(int nr)
33 {
34         int i;
35         for (i = 7; i >= 0; i--) {
36                 printf("%d" , ((nr & (1 << i)) > 0));
37         }
38
39         printf("\n");
40 }
41
42 static inline int16_t mf624_read16(uint16_t *ptr)
43 {
44         return (volatile uint16_t) *ptr;
45 }
46 static inline int32_t mf624_read32(uint32_t *ptr)
47 {
48         return (volatile uint32_t) *ptr;
49 }
50
51 static inline void mf624_write16(uint16_t val, uint16_t *ptr)
52 {
53         *(volatile uint16_t*) ptr = val;
54 }
55
56 static inline void mf624_write32(uint32_t val, uint32_t *ptr)
57 {
58         *(volatile uint32_t*) ptr = val;
59 }
60
61 void DIO_set(int16_t val)
62 {
63         mf624_write16(val, ((uint16_t*) mf624_BAR2) + (DOUT_reg/2)); 
64 }
65
66 uint16_t DIO_read()
67 {
68         return mf624_read16(((uint16_t*) mf624_BAR2) + (DOUT_reg/2)) & 0xF; 
69 }
70
71 int open_device(char* path) {
72         status = open(path, O_RDWR);
73         if (status == -1) {
74                 perror("open()");
75                 return -1;
76         }
77
78         return status;
79 }
80
81 void wait_for_interrupts(int device_fd)
82 {
83         read(device_fd, NULL, 1);
84 }
85
86 int disable_interrupts(int device_fd)
87 {
88         uint32_t control_value = 0;
89
90         status = write(device_fd, &control_value, sizeof(uint32_t));
91         if (status == -1) {
92                 perror("write()");
93                 return -1;
94         }
95
96         return status;
97 }
98
99 int enable_interrupts(int device_fd)
100 {
101         uint32_t control_value = 1;
102
103         status = write(device_fd, &control_value, sizeof(uint32_t));
104         if (status == -1) {
105                 perror("write()");
106                 return -1;
107         }
108
109         return status;
110 }
111
112 void list_available_mem_regions(char* device)
113 {
114         char path[] = "/sys/class/uio/";
115         char subdir[] = "/maps/";
116         char directory[BUFF_MID];
117         memset(directory, '\0', BUFF_MID);
118
119         DIR *dip;
120         struct dirent *dit;
121
122         strncat(directory, path, strlen(path));
123         strncat(directory, device, min(strlen(device), 8));
124         strncat(directory, subdir, strlen(subdir));
125
126         dip = opendir(directory);
127         if (dip == NULL) {
128                 perror("opendir");
129                 return;
130         }
131
132         while ((dit = readdir(dip)) != NULL) {
133                 if (strcmp(dit->d_name, ".") && strcmp(dit->d_name, "..")) {
134                         printf(" %s\n", dit->d_name);
135                 }
136         }
137
138         status = closedir(dip);
139         if (status == -1) {
140                 perror("closedir()");
141                 return;
142         }
143         
144 }
145
146
147 void list_available_io_ports(char *device)
148 {
149         char path[] = "/sys/class/uio/";
150         char subdir[] = "/portio/";
151         char directory[BUFF_MID];
152         memset(directory, '\0', BUFF_MID);
153
154         DIR *dip;
155         struct dirent *dit;
156
157         strncat(directory, path, strlen(path));
158         strncat(directory, device, min(strlen(device), 8));
159         strncat(directory, subdir, strlen(subdir));
160
161         status = access(directory, F_OK);
162         if (status == -1) {
163                 printf(" There are no IO port available\n");
164                 return;
165         }
166
167         dip = opendir(directory);
168         if (dip == NULL) {
169                 perror("opendir");
170                 return;
171         }
172
173         while ((dit = readdir(dip)) != NULL) {
174                 if (strcmp(dit->d_name, ".") && strcmp(dit->d_name, "..")) {
175                         printf(" %s\n", dit->d_name);
176                 }
177         }
178
179         status = closedir(dip);
180         if (status == -1) {
181                 perror("closedir()");
182                 return;
183         }
184
185 }
186
187
188 void run_simple_tests(char* dev_name)
189 {
190         int device_fd;
191         char buff[BUFF_SMALL];
192         memset(buff, '\0', BUFF_SMALL);
193
194         strncat(buff, "/dev/", 5);
195         strncat(buff, dev_name, min(strlen(dev_name), 8));
196
197         printf("Opening %s\n", buff);
198
199         device_fd = open_device(buff);
200         if (device_fd != -1) {
201                 printf("Tring to enable interrupts\n");
202                 status = enable_interrupts(device_fd);
203                 if (status != -1) {
204                         printf(" Probably OK\n");
205                 }
206                 
207                 printf("Tring to disable interrupts\n");
208                 status = disable_interrupts(device_fd);
209                 if (status != -1) {
210                         printf(" Probably OK\n");
211                 }
212         }
213
214
215         printf("Checking for available memory regions exported by the UIO driver\n");
216         list_available_mem_regions(dev_name);
217
218         printf("Checking for available IO ports exported by the UIO driver\n");
219         list_available_io_ports(dev_name);
220 }
221
222 void mmap_regions(int device_fd, char* uio_dev)
223 {
224         char path[BUFF_MID];
225         FILE *file;
226
227         sprintf(path, "/sys/class/uio/%s/maps/map0/addr", uio_dev);
228         file = fopen(path, "rb");
229         fscanf(file, "%llx", &BAR0_phys_addr);
230         fclose(file);
231
232         sprintf(path, "/sys/class/uio/%s/maps/map1/addr", uio_dev);
233         file = fopen(path, "rb");
234         fscanf(file, "%llx", &BAR2_phys_addr);
235         fclose(file);
236
237         sprintf(path, "/sys/class/uio/%s/maps/map2/addr", uio_dev);
238         file = fopen(path, "rb");
239         fscanf(file, "%llx", &BAR4_phys_addr);
240         fclose(file);
241
242
243         //FIXME size of memory must be in multiples of memory pages
244         // size = (size + PAGE_SIZE -1) / PAGE_SIZE * PAGE_SIZE; ?
245         mf624_BAR0 = mmap(0, 1 * sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, BAR0_offset);
246         if (mf624_BAR2 == MAP_FAILED) {
247                 perror("mmap()");
248         }
249         mf624_BAR0 += (BAR0_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
250
251
252         mf624_BAR2 = mmap(0, 1 * sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, BAR2_offset);
253         if (mf624_BAR2 == MAP_FAILED) {
254                 perror("mmap()");
255         }
256         mf624_BAR2 += (BAR2_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
257
258
259         mf624_BAR4 = mmap(0, 1 * sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, BAR4_offset);
260         if (mf624_BAR2 == MAP_FAILED) {
261                 perror("mmap()");
262         }
263         mf624_BAR4 += (BAR4_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
264
265         /*
266         printf("BAR0_phys_addr = %x\n", BAR0_phys_addr);
267         printf("BAR2_phys_addr = %x\n", BAR2_phys_addr);
268         printf("BAR4_phys_addr = %x\n", BAR4_phys_addr);
269
270         printf("mf624_BAR0 = %x\n", mf624_BAR0);
271         printf("mf624_BAR2 = %x\n", mf624_BAR2);
272         printf("mf624_BAR4 = %x\n", mf624_BAR4);
273         */
274 }
275
276
277 int main(int argc, char* argv[])
278 {
279         int device_fd;
280         char buff[BUFF_SMALL];
281         memset(buff, '\0', BUFF_SMALL);
282
283         if (argc < 2) {
284                 printf("Usage: %s UIO_DEVICE\n   UIO_DEVICE\tname of uio device in /dev\n", argv[0]);
285                 return 1;
286         }       
287
288         strncat(buff, "/dev/", 5);
289         strncat(buff, argv[1], min(strlen(argv[1]), 8));
290
291         device_fd = open_device(buff);
292         mmap_regions(device_fd, argv[1]);
293
294         if (device_fd != -1) {
295
296                 while (1){
297                         printf("Reading DIO = ");
298                         print_8bin(DIO_read());
299                         
300                         printf("Setting DIO to 0xff\n");
301                         DIO_set(0xff);
302                         sleep(1);
303
304                         printf("Setting DIO to 0x00\n");
305                         DIO_set(0x00);
306                         sleep(1);
307                 }
308         }
309
310
311         return 0;
312 }