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 static inline int16_t mf624_read16(uint16_t *ptr)
36 static inline int32_t mf624_read32(uint32_t *ptr)
41 static inline void mf624_write16(uint16_t val, uint16_t *ptr)
43 *(volatile uint16_t*) ptr = val;
46 static inline void mf624_write32(uint32_t val, uint32_t *ptr)
48 *(volatile uint32_t*) ptr = val;
51 void DIO_set(int16_t val)
53 mf624_write16(val, ((uint16_t*) mf624_BAR2) + (DOUT_reg/2));
57 int open_device(char* path) {
58 status = open(path, O_RDWR);
67 void wait_for_interrupts(int device_fd)
69 read(device_fd, NULL, 1);
72 int disable_interrupts(int device_fd)
74 uint32_t control_value = 0;
76 status = write(device_fd, &control_value, sizeof(uint32_t));
85 int enable_interrupts(int device_fd)
87 uint32_t control_value = 1;
89 status = write(device_fd, &control_value, sizeof(uint32_t));
98 void list_available_mem_regions(char* device)
100 char path[] = "/sys/class/uio/";
101 char subdir[] = "/maps/";
102 char directory[BUFF_MID];
103 memset(directory, '\0', BUFF_MID);
108 strncat(directory, path, strlen(path));
109 strncat(directory, device, min(strlen(device), 8));
110 strncat(directory, subdir, strlen(subdir));
112 dip = opendir(directory);
118 while ((dit = readdir(dip)) != NULL) {
119 if (strcmp(dit->d_name, ".") && strcmp(dit->d_name, "..")) {
120 printf(" %s\n", dit->d_name);
124 status = closedir(dip);
126 perror("closedir()");
133 void list_available_io_ports(char *device)
135 char path[] = "/sys/class/uio/";
136 char subdir[] = "/portio/";
137 char directory[BUFF_MID];
138 memset(directory, '\0', BUFF_MID);
143 strncat(directory, path, strlen(path));
144 strncat(directory, device, min(strlen(device), 8));
145 strncat(directory, subdir, strlen(subdir));
147 status = access(directory, F_OK);
149 printf(" There are no IO port available\n");
153 dip = opendir(directory);
159 while ((dit = readdir(dip)) != NULL) {
160 if (strcmp(dit->d_name, ".") && strcmp(dit->d_name, "..")) {
161 printf(" %s\n", dit->d_name);
165 status = closedir(dip);
167 perror("closedir()");
174 void run_simple_tests(char* dev_name)
177 char buff[BUFF_SMALL];
178 memset(buff, '\0', BUFF_SMALL);
180 strncat(buff, "/dev/", 5);
181 strncat(buff, dev_name, min(strlen(dev_name), 8));
183 printf("Opening %s\n", buff);
185 device_fd = open_device(buff);
186 if (device_fd != -1) {
187 printf("Tring to enable interrupts\n");
188 status = enable_interrupts(device_fd);
190 printf(" Probably OK\n");
193 printf("Tring to disable interrupts\n");
194 status = disable_interrupts(device_fd);
196 printf(" Probably OK\n");
201 printf("Checking for available memory regions exported by the UIO driver\n");
202 list_available_mem_regions(dev_name);
204 printf("Checking for available IO ports exported by the UIO driver\n");
205 list_available_io_ports(dev_name);
208 void mmap_regions(int device_fd)
210 char buff[BUFF_SMALL];
213 file = fopen("/sys/class/uio/uio0/maps/map0/addr", "rb");
214 fscanf(file, "%llx", &BAR0_phys_addr);
217 file = fopen("/sys/class/uio/uio0/maps/map1/addr", "rb");
218 fscanf(file, "%llx", &BAR2_phys_addr);
221 file = fopen("/sys/class/uio/uio0/maps/map2/addr", "rb");
222 fscanf(file, "%llx", &BAR4_phys_addr);
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) {
232 mf624_BAR0 += (BAR0_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
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) {
239 mf624_BAR2 += (BAR2_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
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) {
246 mf624_BAR4 += (BAR4_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
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);
253 printf("mf624_BAR0 = %x\n", mf624_BAR0);
254 printf("mf624_BAR2 = %x\n", mf624_BAR2);
255 printf("mf624_BAR4 = %x\n", mf624_BAR4);
260 int main(int argc, char* argv[])
263 char buff[BUFF_SMALL];
264 memset(buff, '\0', BUFF_SMALL);
267 printf("Usage: %s UIO_DEVICE\n UIO_DEVICE\tname of uio device in /dev\n", argv[0]);
271 strncat(buff, "/dev/", 5);
272 strncat(buff, argv[1], min(strlen(argv[1]), 8));
274 device_fd = open_device(buff);
275 mmap_regions(device_fd);
277 if (device_fd != -1) {
280 printf("Setting DIO to 0xff\n");
284 printf("Setting DIO to 0x00\n");