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