Reading and writing from/to VME device
Didier Kryn
kryn at in2p3.fr
Tue Mar 27 19:09:41 EST 2007
Hi Konstantin,
I am new to this board, and, by chance I am just starting this week
my first test wit the VME on this board (I have however more than 20
years of VME experience). Your whole logic is mainly OK. My driver uses
slightly different device names but it seems very similar and the API
uses the same structures. I just noticed three things which bother me:
1) You declare outWinCfg and use later in the code outWinCfgADC. I
guess the compiler will complain, unless I missed something. I guess
this is not the file you actually compiled.
2) Why do you specify MAP_SHARED in the mmap() call ? I sort of
understood that the philosophy of this driver was all against sharing.
Maybe it works, but I wouldn't try it the first time.
3) I think it is an error to declare your data pointer as a u_char
*. If you configure your interface for D16, you must perform D16 access.
For example, you might do the following:
unsigned short *rdPtr;
...
rdPtr = (unsigned short *)mmap(...);
for(i=0;i<0x50;i++){
printf("# Read at VME address %x = %x\n", i*sizeof(*rdPtr),
rdPtr[i] );
}
I like using sizeof() instead of 2 because it remains valid if you
convert your code for D32.
If you want to perform D8 access, you should configure your window
accordingly. Beware that there are 2 kinds of D8 transfers, which make
them more complicated and, for that reason mostly abandonned. IIRC, the
VITA standard for CR/CSR defines 1byte data words at even addresses so
as to transfer them as D16. Therefore you should transfer them as short
and then mask the high order byte. I don't know what the high order byte
will be in case of successfull transfer. If it is 0, then it is fine,
because, since a bus error would set all bits to 1, you can check
immediately the sucess of the transfer.
Hope this helps.
Didier
Konstantin Boyanov a écrit :
> Hi list,
>
> I'm using the MVME6100 board with the Motorola driver for linux v3.5
> (kernel 2.6.15). I try to access the CSR registers of an ADC board, in
> order to configure it as to be able to access its memory, on the VME
> bus using one of the outbound windows defined by the driver. As I am
> new to the whole VME stuff, I'm getting into trouble to find out when
> I'm actually reading something on the VME, i.e. which addresses respond.
> I'm trying the following schema (source code @ EOM):
>
> 1. open() and ioctl() one of the /dev/vme_m* devices, which I assume
> is corresponding to an outbound window (at least I try to configure it
> as one),
> 2. then mmap() a memory area to hold the contents of the /dev/vme_m*
> device file
> 3. and finally doing incrementation of the pointer returned by mmap()
> and dereferencing it in the hope that I'll read something, which in
> most cases is 0xFF
>
> In fact my code is very similar to test code that comes with the
> driver and also with a sample code I found in this thread
> ->http://ozlabs.org/pipermail/linuxppc-dev/1999-May/001906.html
> <http://ozlabs.org/pipermail/linuxppc-dev/1999-May/001906.html>
> I've tried to do a read() on the opened /dev/vme_m* device but I only
> succeed in reading 0 bytes, and when I try to read in chunks from the
> VME bus i get errno 22 on reads like read(fd, buffer, 1024) for example.
>
> I don't know if my strategy is correct in the first place but that's
> what I came up with.
> When I try to run one of the test applications that came with the
> driver (the "testout" one) I get an errno = 29 (Illegal seek?! ) on
> the read() operations.
> So my question is whether I make the right steps in reading an address
> on the VME bus. I know I'm missing something, so I'll be glad to get
> some directions as to how to be sure whether I'm reading something
> from the VME bus and where I'm able to write.
>
> Best regards,
> Konstantin
> ________________________________
>
> #include <stdio.h>
> #include <string.h>
> #include <errno.h>
> #include <sys/ioctl.h>
> #include <unistd.h>
> #include "vmedrv.h"
>
> int main(int argc, char* argv[])
> {
> vmeOutWindowCfg_t outWinCfg;
> vmeOutWindowCfg_t outWinGet;
>
> int fdOut, status, i, j;
> unsigned int n;
> u_char *rdPtr, *getPtr;
>
> if(getMyVmeInfo()){
> printf("getMyVmeInfo failed.\n");
> exit (1);
> }
>
> fdOut = open("/dev/vme_m0", O_RDWR);
> perror("open");
> if(fdOut < 0){
> printf("Opening /dev/vme_m0 failed. Errno = %d\n", errno);
> }
>
> memset(&outWinCfgADC, 0, sizeof(vmeOutWindowCfg_t));
> perror("memset");
>
> outWinCfgADC.windowNbr = 0;
> outWinCfgADC.windowEnable = 1;
> outWinCfgADC.wrPostEnable = 0;
> outWinCfgADC.userAccessType = VME_SUPER;
> outWinCfgADC.dataAccessType = VME_DATA;
> outWinCfgADC.windowSizeL = 0x200000;
> outWinCfgADC.xferProtocol = VME_SCT;
> outWinCfgADC.addrSpace = VME_A24;
> outWinCfgADC.maxDataWidth = VME_D16;
>
> status = ioctl(fdOut, VME_IOCTL_SET_OUTBOUND, &outWinCfgADC);
> perror("ioctl");
> if(status < 0){
> printf("*** ioctl set on outWinCfgADC failed. Errno = %d\n",
> errno);
> exit (1);
> }
> memset(&outWinGetADC, 0, sizeof(vmeOutWindowCfg_t));
> outWinGetADC.windowNbr = 0;
>
> status = ioctl(fdOut, VME_IOCTL_GET_OUTBOUND, &outWinGetADC);
> perror("ioctl");
> if(status < 0){
> printf("*** ioctl get on outWinGetADC failed. Errno = %d\n",
> errno);
> exit (1);
> }
>
> /*
> * Check wheather the get and set configurations are the same
> */
>
> getPtr = (u_char *) mmap(0, outWinCfgADC.windowSizeL,
> PROT_READ|PROT_WRITE, MAP_SHARED, fdOut, 0);
> perror("mmap");
> printf("# Start of outbound win in virtual address space of the
> process: %p\n", getPtr);
>
> rdPtr = getPtr;
>
> for(i=0;i<0x100;i++){
> printf("# Read at address %x = %x\n", rdPtr, *rdPtr);
> rdPtr++;
> }
>
> status = close(fdOut);
> if(status != 0){
> printf("*** close() failed. Errno = %d\n", errno);
> exit (1);
> }
>
> return 0;
> }
>
> __________________________________
> Part of the output:
>
> mmap: Illegal seek
> # Start of outbound win in virtual address space of the process:
> 0x30029000
> # Read at address 30029000 = ff
> # Read at address 30029001 = ff
> # Read at address 30029002 = ff
> # Read at address 30029003 = ff
> # Read at address 30029004 = ff
> # Read at address 30029005 = ff
> # Read at address 30029006 = ff
> # Read at address 30029007 = ff
> # Read at address 30029008 = ff
> # Read at address 30029009 = ff
> # Read at address 3002900a = ff
> # Read at address 3002900b = ff
>
> and etc.
> ------------------------------------------------------------------------
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
More information about the Linuxppc-embedded
mailing list