10 #include <stdint.h> // uintX_t
15 #define min(a, b) ((a) > (b) ? (b) : (a))
17 /* Hardware specific */
20 #define BAR0_offset (0 * sysconf(_SC_PAGESIZE))
21 #define BAR2_offset (1 * sysconf(_SC_PAGESIZE))
22 #define BAR4_offset (2 * sysconf(_SC_PAGESIZE))
25 void* mf624_BAR0 = NULL;
26 void* mf624_BAR2 = NULL;
27 void* mf624_BAR4 = NULL;
32 void print_8bin(int nr)
35 for (i = 7; i >= 0; i--) {
36 printf("%d" , ((nr & (1 << i)) > 0));
42 static inline int16_t mf624_read16(uint16_t *ptr)
44 return (volatile uint16_t) *ptr;
46 static inline int32_t mf624_read32(uint32_t *ptr)
48 return (volatile uint32_t) *ptr;
51 static inline void mf624_write16(uint16_t val, uint16_t *ptr)
53 *(volatile uint16_t*) ptr = val;
56 static inline void mf624_write32(uint32_t val, uint32_t *ptr)
58 *(volatile uint32_t*) ptr = val;
61 void DIO_set(int16_t val)
63 mf624_write16(val, ((uint16_t*) mf624_BAR2) + (DOUT_reg/2));
68 return mf624_read16(((uint16_t*) mf624_BAR2) + (DOUT_reg/2)) & 0xF;
71 int open_device(char* path) {
72 status = open(path, O_RDWR);
81 void wait_for_interrupts(int device_fd)
83 read(device_fd, NULL, 1);
86 int disable_interrupts(int device_fd)
88 uint32_t control_value = 0;
90 status = write(device_fd, &control_value, sizeof(uint32_t));
99 int enable_interrupts(int device_fd)
101 uint32_t control_value = 1;
103 status = write(device_fd, &control_value, sizeof(uint32_t));
112 void list_available_mem_regions(char* device)
114 char path[] = "/sys/class/uio/";
115 char subdir[] = "/maps/";
116 char directory[BUFF_MID];
117 memset(directory, '\0', BUFF_MID);
122 strncat(directory, path, strlen(path));
123 strncat(directory, device, min(strlen(device), 8));
124 strncat(directory, subdir, strlen(subdir));
126 dip = opendir(directory);
132 while ((dit = readdir(dip)) != NULL) {
133 if (strcmp(dit->d_name, ".") && strcmp(dit->d_name, "..")) {
134 printf(" %s\n", dit->d_name);
138 status = closedir(dip);
140 perror("closedir()");
147 void list_available_io_ports(char *device)
149 char path[] = "/sys/class/uio/";
150 char subdir[] = "/portio/";
151 char directory[BUFF_MID];
152 memset(directory, '\0', BUFF_MID);
157 strncat(directory, path, strlen(path));
158 strncat(directory, device, min(strlen(device), 8));
159 strncat(directory, subdir, strlen(subdir));
161 status = access(directory, F_OK);
163 printf(" There are no IO port available\n");
167 dip = opendir(directory);
173 while ((dit = readdir(dip)) != NULL) {
174 if (strcmp(dit->d_name, ".") && strcmp(dit->d_name, "..")) {
175 printf(" %s\n", dit->d_name);
179 status = closedir(dip);
181 perror("closedir()");
188 void run_simple_tests(char* dev_name)
191 char buff[BUFF_SMALL];
192 memset(buff, '\0', BUFF_SMALL);
194 strncat(buff, "/dev/", 5);
195 strncat(buff, dev_name, min(strlen(dev_name), 8));
197 printf("Opening %s\n", buff);
199 device_fd = open_device(buff);
200 if (device_fd != -1) {
201 printf("Tring to enable interrupts\n");
202 status = enable_interrupts(device_fd);
204 printf(" Probably OK\n");
207 printf("Tring to disable interrupts\n");
208 status = disable_interrupts(device_fd);
210 printf(" Probably OK\n");
215 printf("Checking for available memory regions exported by the UIO driver\n");
216 list_available_mem_regions(dev_name);
218 printf("Checking for available IO ports exported by the UIO driver\n");
219 list_available_io_ports(dev_name);
222 void mmap_regions(int device_fd, char* uio_dev)
227 sprintf(path, "/sys/class/uio/%s/maps/map0/addr", uio_dev);
228 file = fopen(path, "rb");
229 fscanf(file, "%llx", &BAR0_phys_addr);
232 sprintf(path, "/sys/class/uio/%s/maps/map1/addr", uio_dev);
233 file = fopen(path, "rb");
234 fscanf(file, "%llx", &BAR2_phys_addr);
237 sprintf(path, "/sys/class/uio/%s/maps/map2/addr", uio_dev);
238 file = fopen(path, "rb");
239 fscanf(file, "%llx", &BAR4_phys_addr);
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) {
249 mf624_BAR0 += (BAR0_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
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) {
256 mf624_BAR2 += (BAR2_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
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) {
263 mf624_BAR4 += (BAR4_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
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);
270 printf("mf624_BAR0 = %x\n", mf624_BAR0);
271 printf("mf624_BAR2 = %x\n", mf624_BAR2);
272 printf("mf624_BAR4 = %x\n", mf624_BAR4);
277 int main(int argc, char* argv[])
280 char buff[BUFF_SMALL];
281 memset(buff, '\0', BUFF_SMALL);
284 printf("Usage: %s UIO_DEVICE\n UIO_DEVICE\tname of uio device in /dev\n", argv[0]);
288 strncat(buff, "/dev/", 5);
289 strncat(buff, argv[1], min(strlen(argv[1]), 8));
291 device_fd = open_device(buff);
292 mmap_regions(device_fd, argv[1]);
294 if (device_fd != -1) {
297 printf("Reading DIO = ");
298 print_8bin(DIO_read());
300 printf("Setting DIO to 0xff\n");
304 printf("Setting DIO to 0x00\n");