I am trying to communicate with an FPGA connected to External Memory Bus (EIM) on iMX6.
On T30 I used the Toradex Beta DMA driver which presents the external memory bus as a character device. I could read from a given address using ssize_t pread(int fd, void *buf, size_t count, off_t offset);
with fd
being the file descriptor of the character device node and offset
the relative address of the memory region exposed by the FPGA. E.g., to read 16bit from FPGA’s address 0x1FC:
pread( gmi, buf, 2, 0x1FC );
Now I try to read from the same FPGA on iMX6. I read that this is supported using mmap
(s. External memory bus (EIM) on iMX6). I found some sample code on Connect a ARM Microcontroller to a FPGA using its Extended Memory Interface (EMI).
Let’s say I want to read from FPGA’s address 0x01F8 and 0x01FC. The FPGA is on CS1.
This is my code:
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
__LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
#define MAP_SIZE 0x00001000
#define MAP_MASK 0x00000FFC
int main(int argc, char **argv)
{
int fd;
void *map_base, *virt_addr;
unsigned long read_result, writeval;
//off_t cs = 0x08000000; //CS0
off_t cs = 0x0a000000; //CS1
//off_t cs = 0x0c000000; //CS2
off_t read1 = 0x01F8;
off_t read2 = 0x01FC;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
printf("/dev/mem opened.\n");
fflush(stdout);
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
cs & ~MAP_MASK);
if (map_base == (void *) - 1) FATAL;
printf("Memory (%p) mapped at address %p.\n", cs, map_base);
fflush(stdout);
virt_addr = map_base + (read1 & MAP_MASK);
read_result = *((unsigned long *) virt_addr);
printf("Value at address 0x%X (%p): 0x%X\n", read1, virt_addr, read_result);
fflush(stdout);
virt_addr = map_base + (read2 & MAP_MASK);
read_result = *((unsigned long *) virt_addr);
printf("Value at address 0x%X (%p): 0x%X\n", read2, virt_addr, read_result);
fflush(stdout);
if (munmap(map_base, MAP_SIZE) == -1) FATAL;
close(fd);
return 0;
}
And this is the output:
/dev/mem opened.
Memory (0xa000000) mapped at address 0x76fd0000.
Value at address 0x1F8 (0x76fd01f8): 0x1CFFF
Value at address 0x1FC (0x76fd01fc): 0x1CFFF
However, I expected to get two different values. What do I miss? Do you have any working sample code?