Subject: Re: Reading and writing from/to VME device

From: Didier Kryn <[email-masked]>
Date: Tue, 27 Mar 2007 14:38:56 +0200

Sorry, I was wrong about my second point, mmap: MAP_SHARED works 
fine and anyway seems more reasonable than MAP_PRIVATE. I just made 
A24/D16 transfers, with a sequence similar to yours.
    Good luck.
    Didier

Didier Kryn a écrit :
>     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
>> [email-masked]
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>     
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> [email-masked]
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>