FPGA registers access from Linux userspace

From ArmadeusWiki
Revision as of 10:12, 19 November 2008 by FabienM (Talk | contribs)

Jump to: navigation, search


fpgaregs

compile

To access FPGA registers a tool named fpgaregs is available under target/linux/module/fpga/dev_tools/ directory. To compile it for apf9328, use the command above :

arm-linux-gcc -mcpu=arm920t fpgaregs.c -o fpgaregs

use

fpgaregs can be used to read and write 16 or 32 bits registers.

read 16 bits

fpgaregs w <address>

Where <address> is an address relative to fpga mapping in hexadecimal value.

write 16 bits

fpgaregs w <address> <value>

Where <value> is hexadecimal value to write.

read 32 bits

fpgaregs l <address>

write 32 bits

fpgaregs l <address> <value>

the mmap problem

To access fpga register, fpgaregs use the mmap() system call :

ptr_fpga = mmap (0, 8192, PROT_READ|PROT_WRITE, MAP_SHARED, ffpga, FPGA_ADDRESS);

Thanks to this function, fpga registers are accessible directly on memory with pointer ptr_fpga. To read and write in 16bits or in 32 bits we will cast the pointer value in unsigned short or unsigned int :

16bits write

        *(unsigned short*)(ptr_fpga+(address)) = (unsigned short)value;

read

          value = *(unsigned short*)(ptr_fpga+(address));

32 bits write

        *(unsigned short*)(ptr_fpga+(address)) = (unsigned short)value;

read

          value = *(unsigned int*)(ptr_fpga+(address));

The problem

By default, if the exact ARM920t name is not given, gcc will try to generate compatible read/write for all arm model when it access register in 16bits. Because not all ARM9 has 16bits read/write capabilities.

But the interface between i.MX and fpga on apf9328 has no 8bits read/write capabilities, then each 8 bits access is recognized by fpga as 16bits access. On each 16bits access, i.MX will then do two 16bits access instead of 1.

To avoid this painful problem don't forget the -mcpu=arm920t option when compile fpgaregs for apf9328.