* Reading and writing from/to VME device @ 2007-03-26 15:14 Konstantin Boyanov 2007-03-26 18:31 ` Martin, Tim 2007-03-27 9:09 ` Didier Kryn 0 siblings, 2 replies; 12+ messages in thread From: Konstantin Boyanov @ 2007-03-26 15:14 UTC (permalink / raw) To: linuxppc-embedded [-- Attachment #1: Type: text/plain, Size: 4490 bytes --] 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 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. [-- Attachment #2: Type: text/html, Size: 6396 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Reading and writing from/to VME device 2007-03-26 15:14 Reading and writing from/to VME device Konstantin Boyanov @ 2007-03-26 18:31 ` Martin, Tim 2007-03-27 9:09 ` Didier Kryn 1 sibling, 0 replies; 12+ messages in thread From: Martin, Tim @ 2007-03-26 18:31 UTC (permalink / raw) To: Konstantin Boyanov, linuxppc-embedded > I'm using the MVME6100 board with the Motorola driver for linux v3.5 (kernel 2.6.15). I'm not sure what a "Linux v3.5" is - Montavista? There are patches available from Motorola to the vanila kernel if you're interested in using something newer than 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. > 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),=20 > 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=20 This sounds like the right steps. You don't appear to have the ioctl() configuration structure set correctly. =09 > memset(&outWinCfgADC, 0, sizeof(vmeOutWindowCfg_t)); > perror("memset"); > outWinCfgADC.windowNbr =3D 0; > outWinCfgADC.windowEnable =3D 1; > outWinCfgADC.wrPostEnable =3D 0; > outWinCfgADC.userAccessType =3D VME_SUPER; > outWinCfgADC.dataAccessType =3D VME_DATA; > outWinCfgADC.windowSizeL =3D 0x200000; > outWinCfgADC.xferProtocol =3D VME_SCT; > outWinCfgADC.addrSpace =3D VME_A24; > outWinCfgADC.maxDataWidth =3D VME_D16; =09 This will setup a window of size 0x200000, type SingleCycleTransfer (vs. BLT, 2eSST, etc), 24-bit addressing, 16-bit data.=09 The target VME address will be 0x00000000, since you didn't configure the .xlatedAddrU or .xlatedAddrL portions of outWinCfgADC. Typically, the VME address space is partitioned by VME chassis slot number or some other application-specific scheme. I'm guessing that 0 is not an address that any VME board in your chassis is configured to respond to, hence your errors. Also, since you're doing 16-bit SCT reads, you probably want to dereference your mmap'ed pointer as a 16-bit (unsigned short *) instead of a (u_char *). Tim ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-26 15:14 Reading and writing from/to VME device Konstantin Boyanov 2007-03-26 18:31 ` Martin, Tim @ 2007-03-27 9:09 ` Didier Kryn 2007-03-27 12:38 ` Didier Kryn 2007-03-27 15:47 ` Konstantin Boyanov 1 sibling, 2 replies; 12+ messages in thread From: Didier Kryn @ 2007-03-27 9:09 UTC (permalink / raw) To: Konstantin Boyanov; +Cc: linuxppc-embedded Hi Konstantin, I am new to this board, and, by chance I am just starting this week=20 my first test wit the VME on this board (I have however more than 20=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=20 uses the same structures. I just noticed three things which bother me: 1) You declare outWinCfg and use later in the code outWinCfgADC. I=20 guess the compiler will complain, unless I missed something. I guess=20 this is not the file you actually compiled. 2) Why do you specify MAP_SHARED in the mmap() call ? I sort of=20 understood that the philosophy of this driver was all against sharing.=20 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=20 *. If you configure your interface for D16, you must perform D16 access. = For example, you might do the following: unsigned short *rdPtr; =2E.. rdPtr =3D (unsigned short *)mmap(...); for(i=3D0;i<0x50;i++){ printf("# Read at VME address %x =3D %x\n", i*sizeof(*rdPtr),=20 rdPtr[i] ); } I like using sizeof() instead of 2 because it remains valid if you=20 convert your code for D32. If you want to perform D8 access, you should configure your window=20 accordingly. Beware that there are 2 kinds of D8 transfers, which make=20 them more complicated and, for that reason mostly abandonned. IIRC, the=20 VITA standard for CR/CSR defines 1byte data words at even addresses so=20 as to transfer them as D16. Therefore you should transfer them as short=20 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,=20 because, since a bus error would set all bits to 1, you can check=20 immediately the sucess of the transfer. Hope this helps. Didier Konstantin Boyanov a =E9crit : > Hi list, > > I'm using the MVME6100 board with the Motorola driver for linux v3.5=20 > (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=20 > bus using one of the outbound windows defined by the driver. As I am=20 > new to the whole VME stuff, I'm getting into trouble to find out when=20 > I'm actually reading something on the VME, i.e. which addresses respond= =2E > I'm trying the following schema (source code @ EOM): > > 1. open() and ioctl() one of the /dev/vme_m* devices, which I assume=20 > 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*=20 > device file > 3. and finally doing incrementation of the pointer returned by mmap()=20 > and dereferencing it in the hope that I'll read something, which in=20 > most cases is 0xFF > > In fact my code is very similar to test code that comes with the=20 > driver and also with a sample code I found in this thread=20 > ->http://ozlabs.org/pipermail/linuxppc-dev/1999-May/001906.html=20 > <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=20 > succeed in reading 0 bytes, and when I try to read in chunks from the=20 > VME bus i get errno 22 on reads like read(fd, buffer, 1024) for example= =2E > > I don't know if my strategy is correct in the first place but that's=20 > what I came up with. > When I try to run one of the test applications that came with the=20 > driver (the "testout" one) I get an errno =3D 29 (Illegal seek?! ) on=20 > 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=20 > some directions as to how to be sure whether I'm reading something=20 > 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 =3D open("/dev/vme_m0", O_RDWR); > perror("open"); > if(fdOut < 0){ > printf("Opening /dev/vme_m0 failed. Errno =3D %d\n", errno); > } > > memset(&outWinCfgADC, 0, sizeof(vmeOutWindowCfg_t)); > perror("memset"); > > outWinCfgADC.windowNbr =3D 0; > outWinCfgADC.windowEnable =3D 1; > outWinCfgADC.wrPostEnable =3D 0; > outWinCfgADC.userAccessType =3D VME_SUPER; > outWinCfgADC.dataAccessType =3D VME_DATA; > outWinCfgADC.windowSizeL =3D 0x200000; > outWinCfgADC.xferProtocol =3D VME_SCT; > outWinCfgADC.addrSpace =3D VME_A24; > outWinCfgADC.maxDataWidth =3D VME_D16; > > status =3D ioctl(fdOut, VME_IOCTL_SET_OUTBOUND, &outWinCfgADC); > perror("ioctl"); > if(status < 0){ > printf("*** ioctl set on outWinCfgADC failed. Errno =3D %d\n", = > errno); > exit (1); > } > memset(&outWinGetADC, 0, sizeof(vmeOutWindowCfg_t)); > outWinGetADC.windowNbr =3D 0; > > status =3D ioctl(fdOut, VME_IOCTL_GET_OUTBOUND, &outWinGetADC); > perror("ioctl"); > if(status < 0){ > printf("*** ioctl get on outWinGetADC failed. Errno =3D %d\n", = > errno); > exit (1); > } > > /* > * Check wheather the get and set configurations are the same > */ > > getPtr =3D (u_char *) mmap(0, outWinCfgADC.windowSizeL,=20 > PROT_READ|PROT_WRITE, MAP_SHARED, fdOut, 0); > perror("mmap"); > printf("# Start of outbound win in virtual address space of the=20 > process: %p\n", getPtr); > > rdPtr =3D getPtr; > > for(i=3D0;i<0x100;i++){ > printf("# Read at address %x =3D %x\n", rdPtr, *rdPtr); > rdPtr++; > } > > status =3D close(fdOut); > if(status !=3D 0){ > printf("*** close() failed. Errno =3D %d\n", errno); > exit (1); > } > =20 > return 0; > } > > __________________________________ > Part of the output: > > mmap: Illegal seek > # Start of outbound win in virtual address space of the process:=20 > 0x30029000 > # Read at address 30029000 =3D ff > # Read at address 30029001 =3D ff > # Read at address 30029002 =3D ff > # Read at address 30029003 =3D ff > # Read at address 30029004 =3D ff > # Read at address 30029005 =3D ff > # Read at address 30029006 =3D ff > # Read at address 30029007 =3D ff > # Read at address 30029008 =3D ff > # Read at address 30029009 =3D ff > # Read at address 3002900a =3D ff > # Read at address 3002900b =3D ff > > and etc. > -----------------------------------------------------------------------= - > > _______________________________________________ > Linuxppc-embedded mailing list > Linuxppc-embedded@ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc-embedded ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-27 9:09 ` Didier Kryn @ 2007-03-27 12:38 ` Didier Kryn 2007-03-27 15:47 ` Konstantin Boyanov 1 sibling, 0 replies; 12+ messages in thread From: Didier Kryn @ 2007-03-27 12:38 UTC (permalink / raw) Cc: Konstantin Boyanov, linuxppc-embedded Sorry, I was wrong about my second point, mmap: MAP_SHARED works=20 fine and anyway seems more reasonable than MAP_PRIVATE. I just made=20 A24/D16 transfers, with a sequence similar to yours. Good luck. Didier Didier Kryn a =E9crit : > Hi Konstantin, > I am new to this board, and, by chance I am just starting this week= =20 > my first test wit the VME on this board (I have however more than 20=20 > years of VME experience). Your whole logic is mainly OK. My driver use= s=20 > slightly different device names but it seems very similar and the API=20 > 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=20 > this is not the file you actually compiled. > 2) Why do you specify MAP_SHARED in the mmap() call ? I sort of=20 > 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= =2E=20 > For example, you might do the following: > > unsigned short *rdPtr; > ... > rdPtr =3D (unsigned short *)mmap(...); > for(i=3D0;i<0x50;i++){ > printf("# Read at VME address %x =3D %x\n", i*sizeof(*rdPtr),=20 > rdPtr[i] ); > } > > I like using sizeof() instead of 2 because it remains valid if you=20 > convert your code for D32. > If you want to perform D8 access, you should configure your window=20 > accordingly. Beware that there are 2 kinds of D8 transfers, which make = > them more complicated and, for that reason mostly abandonned. IIRC, the= =20 > 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= =20 > and then mask the high order byte. I don't know what the high order byt= e=20 > will be in case of successfull transfer. If it is 0, then it is fine,=20 > because, since a bus error would set all bits to 1, you can check=20 > immediately the sucess of the transfer. > > Hope this helps. > Didier > > Konstantin Boyanov a =E9crit : > =20 >> Hi list, >> >> I'm using the MVME6100 board with the Motorola driver for linux v3.5=20 >> (kernel 2.6.15). I try to access the CSR registers of an ADC board, in= =20 >> order to configure it as to be able to access its memory, on the VME=20 >> bus using one of the outbound windows defined by the driver. As I am=20 >> 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 respon= d. >> I'm trying the following schema (source code @ EOM): >> >> 1. open() and ioctl() one of the /dev/vme_m* devices, which I assume=20 >> is corresponding to an outbound window (at least I try to configure it= =20 >> as one), >> 2. then mmap() a memory area to hold the contents of the /dev/vme_m*=20 >> 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=20 >> most cases is 0xFF >> >> In fact my code is very similar to test code that comes with the=20 >> driver and also with a sample code I found in this thread=20 >> ->http://ozlabs.org/pipermail/linuxppc-dev/1999-May/001906.html=20 >> <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 exampl= e. >> >> I don't know if my strategy is correct in the first place but that's=20 >> what I came up with. >> When I try to run one of the test applications that came with the=20 >> driver (the "testout" one) I get an errno =3D 29 (Illegal seek?! ) on = >> the read() operations. >> So my question is whether I make the right steps in reading an address= =20 >> on the VME bus. I know I'm missing something, so I'll be glad to get=20 >> some directions as to how to be sure whether I'm reading something=20 >> 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 =3D open("/dev/vme_m0", O_RDWR); >> perror("open"); >> if(fdOut < 0){ >> printf("Opening /dev/vme_m0 failed. Errno =3D %d\n", errno); >> } >> >> memset(&outWinCfgADC, 0, sizeof(vmeOutWindowCfg_t)); >> perror("memset"); >> >> outWinCfgADC.windowNbr =3D 0; >> outWinCfgADC.windowEnable =3D 1; >> outWinCfgADC.wrPostEnable =3D 0; >> outWinCfgADC.userAccessType =3D VME_SUPER; >> outWinCfgADC.dataAccessType =3D VME_DATA; >> outWinCfgADC.windowSizeL =3D 0x200000; >> outWinCfgADC.xferProtocol =3D VME_SCT; >> outWinCfgADC.addrSpace =3D VME_A24; >> outWinCfgADC.maxDataWidth =3D VME_D16; >> >> status =3D ioctl(fdOut, VME_IOCTL_SET_OUTBOUND, &outWinCfgADC); >> perror("ioctl"); >> if(status < 0){ >> printf("*** ioctl set on outWinCfgADC failed. Errno =3D %d\n",= =20 >> errno); >> exit (1); >> } >> memset(&outWinGetADC, 0, sizeof(vmeOutWindowCfg_t)); >> outWinGetADC.windowNbr =3D 0; >> >> status =3D ioctl(fdOut, VME_IOCTL_GET_OUTBOUND, &outWinGetADC); >> perror("ioctl"); >> if(status < 0){ >> printf("*** ioctl get on outWinGetADC failed. Errno =3D %d\n",= =20 >> errno); >> exit (1); >> } >> >> /* >> * Check wheather the get and set configurations are the same >> */ >> >> getPtr =3D (u_char *) mmap(0, outWinCfgADC.windowSizeL,=20 >> PROT_READ|PROT_WRITE, MAP_SHARED, fdOut, 0); >> perror("mmap"); >> printf("# Start of outbound win in virtual address space of the=20 >> process: %p\n", getPtr); >> >> rdPtr =3D getPtr; >> >> for(i=3D0;i<0x100;i++){ >> printf("# Read at address %x =3D %x\n", rdPtr, *rdPtr); >> rdPtr++; >> } >> >> status =3D close(fdOut); >> if(status !=3D 0){ >> printf("*** close() failed. Errno =3D %d\n", errno); >> exit (1); >> } >> =20 >> return 0; >> } >> >> __________________________________ >> Part of the output: >> >> mmap: Illegal seek >> # Start of outbound win in virtual address space of the process:=20 >> 0x30029000 >> # Read at address 30029000 =3D ff >> # Read at address 30029001 =3D ff >> # Read at address 30029002 =3D ff >> # Read at address 30029003 =3D ff >> # Read at address 30029004 =3D ff >> # Read at address 30029005 =3D ff >> # Read at address 30029006 =3D ff >> # Read at address 30029007 =3D ff >> # Read at address 30029008 =3D ff >> # Read at address 30029009 =3D ff >> # Read at address 3002900a =3D ff >> # Read at address 3002900b =3D ff >> >> and etc. >> ----------------------------------------------------------------------= -- >> >> _______________________________________________ >> Linuxppc-embedded mailing list >> Linuxppc-embedded@ozlabs.org >> https://ozlabs.org/mailman/listinfo/linuxppc-embedded >> =20 > > > _______________________________________________ > Linuxppc-embedded mailing list > Linuxppc-embedded@ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc-embedded > =20 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-27 9:09 ` Didier Kryn 2007-03-27 12:38 ` Didier Kryn @ 2007-03-27 15:47 ` Konstantin Boyanov 2007-03-27 19:02 ` Martin, Tim 1 sibling, 1 reply; 12+ messages in thread From: Konstantin Boyanov @ 2007-03-27 15:47 UTC (permalink / raw) To: linuxppc-embedded [-- Attachment #1: Type: text/plain, Size: 5987 bytes --] Hi, First of all, thanks for the feedback! @Tim Martin: >I'm not sure what a "Linux v3.5" is - Montavista? There are patches >available from Motorola to the vanila kernel if you're interested in >using something newer than 2.6.15. Well, 3.5 is just the version of the driver, which is shown by # cat /proc/vmeinfo Otherwise, I'm using ELinOS 4.1 for building the linux system. And as for now I think the 2.6.15 is fine for testing purposes. >The target VME address will be 0x00000000, since you didn't configure >the .xlatedAddrU or .xlatedAddrL portions of outWinCfgADC. Typically, >the VME address space is partitioned by VME chassis slot number or some >other application-specific scheme. I tried to assign it to some other value (just a guess like 0x10000000, which I think is 0x1000 in A16), and then try to read through as many addresses as the size of the window contains. I get the following output (source again @EOM): # Read @ VME address a000 = 0 # Read @ VME address a002 = 0 # Read @ VME address a004 = 1 # Read @ VME address a006 = 0 # Read @ VME address a008 = 0 # Read @ VME address a00c = eda2 # Read @ VME address a00e = eda2 # Read @ VME address a010 = 0 # Read @ VME address a012 = 0 # Read @ VME address a014 = 0 # Read @ VME address a016 = 0 # Read @ VME address a018 = 0 # Read @ VME address a01a = 0 # Read @ VME address a01c = 0 # Read @ VME address a020 = 0 # Read @ VME address a080 = 4546 # Read @ VME address a082 = 5f4c # Read @ VME address a084 = 4146 # Read @ VME address a086 = 4344 # Read @ VME address a088 = 4445 # Read @ VME address a08a = 5953 # Read @ VME address a08c = 3 # Read @ VME address a08e = 3 # Read @ VME address a090 = 2 # Read @ VME address a092 = 0 # Read @ VME address a094 = 0 # Read @ VME address a096 = 0 # Read @ VME address a098 = 0 # Read @ VME address a09a = 0 # Read @ VME address a09c = 0 # Read @ VME address a09e = e369 repeatedly for all addresses up to 0xFD04F when I get a Segmentation fault. At least now I got something, but I just cannot figure out why the output repeats again and again about 20-30. The ADC board is in slot 4, and it's CSR space is available at 0x10100000 (set by junpers) , containing 15 registers. Is it possible that I'm actualy accessing them, or I just read garbage? >Typically, the VME address space is partitioned by VME chassis slot number or some >other application-specific scheme. Does this mean that (theoretically) all slots (respectively boards in them) are visible through a single outbound window? Or one must configure one outbound window per slot? I tried ot find some more info on this issue but with no success. I only found something similar to what you are refering in the driver documentation, but it is about the inbound windows, not the outbound ones. The schema for the inbound wins is the following: Each of the inbound windows is mapped into A32/D32 space at an address determined by the boards slot number. The address is calculated as 0x80000000+(0x20000000*slotnum)+(0x400000*inboundnum). Thus, in total, each board responds to a 32 MB chunk of VME address space. I don't know whether the schema for the outbound wins is the same, or where to find it. Maybe its driver specific, in other words defined by some driver function? Can somebody shed some light on this please? @Didier Kryn: > 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. This is just a typo, and yes, that's not the code that I compiled, just a "snippet" to illustrate how I've really implemented my ideas. About the MAP_SHARED flag - after getting over the VME accesses I'll have to integrate the API to the VME bus ina control server, which uses shared memory when reading out the data from the ADC, so I thought it would be a good idea to test with shared memory in the first place. Thanks again for all the help. Best regards, Konstantin _______________________________________ int main(int argc, char ** args) { vmeInfoCfg_t outWinCfgInfo; vmeOutWindowCfg_t outWinCfgADC; vmeOutWindowCfg_t outWinGetADC; int fdOut, status, i, j; unsigned int n; unsigned short *rdPtr, *getPtr; 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_A16; outWinCfgADC.maxDataWidth = VME_D16; outWinCfgADC.xlatedAddrL = 0x10000000; 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)); perror("memset"); 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); } getPtr = (unsigned short *) 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 < 0x200000 ; i++) { if((*rdPtr)!=0xFFFF){ printf("%x = %x\n", i, *rdPtr); } rdPtr++; } status = close(fdOut); if(status != 0){ printf("*** close() failed. Errno = %d\n", errno); exit (1); } return 0; } [-- Attachment #2: Type: text/html, Size: 8065 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Reading and writing from/to VME device 2007-03-27 15:47 ` Konstantin Boyanov @ 2007-03-27 19:02 ` Martin, Tim 2007-03-28 9:56 ` Didier Kryn 0 siblings, 1 reply; 12+ messages in thread From: Martin, Tim @ 2007-03-27 19:02 UTC (permalink / raw) To: Konstantin Boyanov, linuxppc-embedded >I tried to assign it to some other value (just a guess like 0x10000000, which I think is > 0x1000 in A16), and then try to read through as many addresses as the size of the > window contains. Your code indicated said you're using A24 addressing. You should assign an A24 address. =09 > I get the following output (source again @EOM):=09 ... > repeatedly for all addresses up to 0xFD04F when I get a Segmentation fault. At least now > I got something, but I just cannot figure out why the output repeats again and again about > 20-30. The ADC board is in slot 4, and it's CSR space is available at 0x10100000 (set by junpers) >, containing 15 registers. Is it possible that I'm actualy accessing them, or I just read garbage?=20 =09 Looks like you're reading something. Address 0x10100000 is larger than a 24 bit address. Perhaps you should be using A32 transfers instead of A24? >>Typically, the VME address space is partitioned by VME chassis slot number or some=20 >>other application-specific scheme. >Does this mean that (theoretically) all slots (respectively boards in them) are visible > through a single outbound window? Or one must configure one outbound window per slot? Yes, theoretically, all boards could be visible through one outbound window, IF 1. The boards are configured to respond to an address in that window 2. None of the boards address spaces overlap. > I tried ot find some more info on this issue but with no success. I only found something > similar to what you are refering in the driver documentation, but it is about the inbound > windows, not the outbound ones. The schema for the inbound wins is the following:=20 >=09 > Each of the inbound windows is mapped into A32/D32 space at an address determined by the > boards slot number. The address is calculated as 0x80000000+(0x20000000*slotnum)+(0x400000*inboundnum).=20 > Thus, in total, each board responds to a 32 MB chunk of VME address space.=20 I don't believe there are any VITA / VME requirements for a particular addressing scheme. The one above looks reasonable...I've used other schemes as well. It depends on your system configuration. > I don't know whether the schema for the outbound wins is the same, or where to find it. > Maybe its driver specific, in other words defined by some driver function? > Can somebody shed some light on this please? I believe Outbound/Inbound windows in the Tundra chip refer to the bus mastership, not direction of data transfer. VME Bus Master VME Target Data Direction Window Self Other Read Outbound Self Other Write Outbound Other Self Read Inbound Other Self Write Inbound You would configure an Inbound window if you want some other board in the system to be able to read/write your local address space. You would configure an Outbound window if you want to read/write some other board's address space. Tim =09 =09 =09 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-27 19:02 ` Martin, Tim @ 2007-03-28 9:56 ` Didier Kryn 2007-03-29 10:13 ` Konstantin Boyanov 0 siblings, 1 reply; 12+ messages in thread From: Didier Kryn @ 2007-03-28 9:56 UTC (permalink / raw) To: Konstantin Boyanov; +Cc: linuxppc-embedded Konstantin, I am a little confused; You tell you want to access CR/CSR space but you configure your window for A24. Even if addresses are coded in 24-bit in CR/CSR, this is not the same space as A24. Although I never still used it, I believe that CR/CSR is a geographical address space (base address of the board defined by its location in the crate) while all others are logical address spaces where the base address is set at power up from a switch... and can be changed by writing the proper register in CR/CSR. CR/CSR has address modifier 2F, while you are configuring your window for A24/data/supervisory which gives address modifier 3D. BTW, most boards don't care about user or supervisory, they would respond as well to address modifier 39 To answer one of your questions, for sure inbound windows are dedicated to configure the response of the module as a slave and outbound windows as a master. When you are reading anything else than FF, then you are actually reading something, which means that some slave module has accepted the transaction. You always get all bits set to 1 in case of VMEbus timeout. Hope this helps Didier ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-28 9:56 ` Didier Kryn @ 2007-03-29 10:13 ` Konstantin Boyanov 2007-03-29 19:27 ` Martin, Tim 2007-03-30 9:24 ` Didier Kryn 0 siblings, 2 replies; 12+ messages in thread From: Konstantin Boyanov @ 2007-03-29 10:13 UTC (permalink / raw) To: linuxppc-embedded [-- Attachment #1: Type: text/plain, Size: 1780 bytes --] Hi again, Thank you once again for presenting the VME world to me :) >Looks like you're reading something. Address 0x10100000 is larger than >a 24 bit address. Perhaps you should be using A32 transfers instead of >A24? No, no, I need to do A16 access, thats the only way to read the control registers. Form here comes also my confusion - I thought that when I'm reading CS/CSR register I need to do it in CSR address space. So no algorithms for geographical location of boards are needed in my case I guess. Actually the base address of CSR on the board is 0xA000 (10100000 is the first byte of the address selection in inary, shame on me :( ). But when I try to configure it with outWinCfgADC.zlatedAddrL = 0xA000, when I run the programm I get an errno 29 (Invalid argument) from ioctl(). In fact if I set the xlatedAddrL to some value smaller that 0x10000 I get this error. Here's my most recent configuration: outWinCfgADC.windowNbr = 0; outWinCfgADC.windowEnable = 1; outWinCfgADC.wrPostEnable = 0; outWinCfgADC.userAccessType = VME_SUPER; outWinCfgADC.dataAccessType = VME_DATA; outWinCfgADC.windowSizeL = 0x10000; outWinCfgADC.xferProtocol = VME_SCT; outWinCfgADC.addrSpace = VME_A16; outWinCfgADC.maxDataWidth = VME_D16; outWinCfgADC.xlatedAddrL = 0x10000000; I think that 0x10000 for window size is big enough to encompass the whole A16 addressable space. With the 0x10000000 xlatedAddr I get no errors and read the desired registers when I increment this address to 0x1000A000. But nevertheless it seems strange to me that the device does not accept xlatedAddr lower that 0x10000. Maybe its due to the configuration of the VME controller? Best regards, Konstantin [-- Attachment #2: Type: text/html, Size: 2241 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Reading and writing from/to VME device 2007-03-29 10:13 ` Konstantin Boyanov @ 2007-03-29 19:27 ` Martin, Tim 2007-03-30 9:24 ` Didier Kryn 1 sibling, 0 replies; 12+ messages in thread From: Martin, Tim @ 2007-03-29 19:27 UTC (permalink / raw) To: Konstantin Boyanov, linuxppc-embedded >But when I try to configure it with outWinCfgADC.zlatedAddrL =3D = 0xA000, >when I run the programm I get an errno 29 (Invalid argument) from ioctl(). >In fact if I set the xlatedAddrL to some value smaller that 0x10000 I get this >error. Here's my most recent configuration:=20 The VME device driver has an (artificial, as far as I can tell) limit that rejects window base addresses on an offset less than 0x10000. You could change the driver (in drivers/vme/vmedrv.c or vmelinux.c) to accept a smaller base address offset. I'm not sure of the reason for the limit - I don't _think_ the TSI148 has such a limit, but I haven't looked into it at all. Tim ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-29 10:13 ` Konstantin Boyanov 2007-03-29 19:27 ` Martin, Tim @ 2007-03-30 9:24 ` Didier Kryn 2007-04-02 9:15 ` Didier Kryn 1 sibling, 1 reply; 12+ messages in thread From: Didier Kryn @ 2007-03-30 9:24 UTC (permalink / raw) Cc: linuxppc-embedded [-- Attachment #1: Type: text/plain, Size: 4204 bytes --] Konstantin, Martin, First, I am not sure that our discussion is in the scope of the list, but the others didn't complain still... I gave a look at the VITA publications about the CR/CSR. CR/CSR was introduced in the VME64 standard. These registers are dedicated to inform the user of the board's identity and capabilities and perform some settings. they belong to a space different of the "logical" address spaces (A16/A24/A32/A64). The base address of the "logical" address spaces was traditionally set by hexadecimal switches. VME64 allows to set it by writing registers in the CR/CSR space. Obviously, this should not relocate the CR/CSR space itself. VME64 does not specify how the base address of the CR/CSR space is set. VME64 was a transitional standard and this uncertainty has been solved by VME64x which specifies that this base address is coded on the backplane connectors this is what makes it a "geographical" address space (a term derived from FastBus). It allows an application to discover which board is present in which slot. For this to work, you should have a VME64x crate and a VME64x board, with the new connector type for P1 and P2. To allow the use of CR/CSR in non-VME64x devices and/or crates, the CR/CSR base address can sometimes be set by switches (not the same switches as the other spaces). According to what Konstantin is saying, his board also maps the CR/CSR to the A16 address space, which seems strange to me. Have you an online documentation of the board? Now, for the ioctl problem, Konstantin, did you try to set xlatedAddrL to zero. The Tsio148, and therefore the driver, enforce alignment on rather big blocks and maybe misalignment is the cause of the "invalid argument" error. I see no reason not to map the entire A16, A24 or CR/CSR spaces. For the others, of course, you are limited by the size of the cpu's address space. I will eventually try to reproduce your ioctl problem next week. Hopping you will solve it before :-) . Best regards. Didier Konstantin Boyanov said: > Hi again, > > Thank you once again for presenting the VME world to me :) > > >Looks like you're reading something. Address 0x10100000 is larger than > >a 24 bit address. Perhaps you should be using A32 transfers instead of > >A24? > > No, no, I need to do A16 access, thats the only way to read the > control registers. Form here comes also my confusion - I thought that > when I'm reading CS/CSR register I need to do it in CSR address space. > So no algorithms for geographical location of boards are needed in my > case I guess. > Actually the base address of CSR on the board is 0xA000 (10100000 is > the first byte of the address selection in inary, shame on me :( ). > But when I try to configure it with outWinCfgADC.zlatedAddrL = 0xA000, > when I run the programm I get an errno 29 (Invalid argument) from > ioctl(). In fact if I set the xlatedAddrL to some value smaller that > 0x10000 I get this error. Here's my most recent configuration: > > outWinCfgADC.windowNbr = 0; > outWinCfgADC.windowEnable = 1; > outWinCfgADC.wrPostEnable = 0; > outWinCfgADC.userAccessType = VME_SUPER; > outWinCfgADC.dataAccessType = VME_DATA; > outWinCfgADC.windowSizeL = 0x10000; > outWinCfgADC.xferProtocol = VME_SCT; > outWinCfgADC.addrSpace = VME_A16; > outWinCfgADC.maxDataWidth = VME_D16; > outWinCfgADC.xlatedAddrL = 0x10000000; > > I think that 0x10000 for window size is big enough to encompass the > whole A16 addressable space. With the 0x10000000 xlatedAddr I get no > errors and read the desired registers when I increment this address to > 0x1000A000. But nevertheless it seems strange to me that the device > does not accept xlatedAddr lower that 0x10000. Maybe its due to the > configuration of the VME controller? > > Best regards, > Konstantin > ------------------------------------------------------------------------ > > _______________________________________________ > Linuxppc-embedded mailing list > Linuxppc-embedded@ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc-embedded [-- Attachment #2: Type: text/html, Size: 5320 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-03-30 9:24 ` Didier Kryn @ 2007-04-02 9:15 ` Didier Kryn 2007-04-02 9:21 ` Didier Kryn 0 siblings, 1 reply; 12+ messages in thread From: Didier Kryn @ 2007-04-02 9:15 UTC (permalink / raw) Cc: Konstantin Boyanov, linuxppc-embedded Konstantin, I reproduced your ioctl() problem with the attached=20 program. The conclusion is that the only valid size and base parameters=20 for A16 are windowSizeL=3D0x10000 and xlatedAddrL=3D0. This means the A16= =20 space can only be mapped as a whole. What you observed with =20 xlatedAddrL=3D0x10100000 is that the ioctl(), gently masks the irrelevant= =20 high order bits. Best regards. Didier Didier Kryn a =E9crit : > > > Now, for the ioctl problem, Konstantin, did you try to set=20 > xlatedAddrL to zero. The Tsio148, and therefore the driver, enforce=20 > alignment on rather big blocks and maybe misalignment is the cause of = > the "invalid argument" error. I see no reason not to map the entire=20 > A16, A24 or CR/CSR spaces. For the others, of course, you are limited=20 > by the size of the cpu's address space. > > I will eventually try to reproduce your ioctl problem next week.=20 > Hopping you will solve it before :-) . > > Best regards. Didier > > Konstantin Boyanov said: >> Hi again, >> >> Thank you once again for presenting the VME world to me :) >> >> >Looks like you're reading something. Address 0x10100000 is larger th= an >> >a 24 bit address. Perhaps you should be using A32 transfers instead = of >> >A24? >> >> No, no, I need to do A16 access, thats the only way to read the=20 >> control registers. Form here comes also my confusion - I thought that = >> when I'm reading CS/CSR register I need to do it in CSR address=20 >> space. So no algorithms for geographical location of boards are=20 >> needed in my case I guess. >> Actually the base address of CSR on the board is 0xA000 (10100000 is=20 >> the first byte of the address selection in inary, shame on me :( ).=20 >> But when I try to configure it with outWinCfgADC.zlatedAddrL =3D=20 >> 0xA000, when I run the programm I get an errno 29 (Invalid argument)=20 >> from ioctl(). In fact if I set the xlatedAddrL to some value smaller=20 >> that 0x10000 I get this error. Here's my most recent configuration: >> >> outWinCfgADC.windowNbr =3D 0; >> outWinCfgADC.windowEnable =3D 1; >> outWinCfgADC.wrPostEnable =3D 0; >> outWinCfgADC.userAccessType =3D VME_SUPER; >> outWinCfgADC.dataAccessType =3D VME_DATA; >> outWinCfgADC.windowSizeL =3D 0x10000; >> outWinCfgADC.xferProtocol =3D VME_SCT; >> outWinCfgADC.addrSpace =3D VME_A16; >> outWinCfgADC.maxDataWidth =3D VME_D16; >> outWinCfgADC.xlatedAddrL =3D 0x10000000; >> >> I think that 0x10000 for window size is big enough to encompass the=20 >> whole A16 addressable space. With the 0x10000000 xlatedAddr I get no=20 >> errors and read the desired registers when I increment this address=20 >> to 0x1000A000. But nevertheless it seems strange to me that the=20 >> device does not accept xlatedAddr lower that 0x10000. Maybe its due=20 >> to the configuration of the VME controller? >> > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Reading and writing from/to VME device 2007-04-02 9:15 ` Didier Kryn @ 2007-04-02 9:21 ` Didier Kryn 0 siblings, 0 replies; 12+ messages in thread From: Didier Kryn @ 2007-04-02 9:21 UTC (permalink / raw) To: Didier Kryn; +Cc: Konstantin Boyanov, linuxppc-embedded [-- Attachment #1: Type: text/plain, Size: 488 bytes --] Didier Kryn a écrit : > Konstantin, I reproduced your ioctl() problem with the attached > program. The conclusion is that the only valid size and base parameters > for A16 are windowSizeL=0x10000 and xlatedAddrL=0. This means the A16 > space can only be mapped as a whole. What you observed with > xlatedAddrL=0x10100000 is that the ioctl(), gently masks the irrelevant > high order bits. > > Best regards. > Didier > Oops! I forgot the attachment... [-- Attachment #2: test148.c --] [-- Type: text/x-csrc, Size: 1554 bytes --] #include <linux/stddef.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/ioctl.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include "vmedrv.h" #if !defined(offsetof) /* maybe defined (if <linux/stddef.h> included indirectly) */ # define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif int main(void) { int vmepd, i; char *devname="/dev/vme/vme_out0"; vmeOutWindowCfg_t a16d16 = {0,1,0,0,0,0x1000000,0,0,0,0,0,0,VME_SSTNONE, VME_A16,VME_D16,VME_SCT,VME_SUPER,VME_DATA,0}; unsigned size_max=0x10000; unsigned base, size; unsigned short *vmebus; vmepd = open(devname, O_RDWR); if(vmepd==-1) { perror(devname); return 1; } for( base=0 ; (size = size_max - base) ; base+=0x100 ) { a16d16.xlatedAddrL = base; a16d16.windowSizeL = size; if(ioctl(vmepd, VME_IOCTL_SET_OUTBOUND, &a16d16)) printf("ioctl failed for base %x, size %x: %s\n", base, size, strerror(errno)); else printf("ioctl OK for base %x, size %x\n", base, size); } for( base=0, size=0x100 ; size <= size_max ; size+=0x100 ) { a16d16.xlatedAddrL = base; a16d16.windowSizeL = size; if(ioctl(vmepd, VME_IOCTL_SET_OUTBOUND, &a16d16)) printf("ioctl failed for base %x, size %x: %s\n", base, size, strerror(errno)); else printf("ioctl OK for base %x, size %x\n", base, size); } close(vmepd); } ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2007-04-02 9:21 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-03-26 15:14 Reading and writing from/to VME device Konstantin Boyanov 2007-03-26 18:31 ` Martin, Tim 2007-03-27 9:09 ` Didier Kryn 2007-03-27 12:38 ` Didier Kryn 2007-03-27 15:47 ` Konstantin Boyanov 2007-03-27 19:02 ` Martin, Tim 2007-03-28 9:56 ` Didier Kryn 2007-03-29 10:13 ` Konstantin Boyanov 2007-03-29 19:27 ` Martin, Tim 2007-03-30 9:24 ` Didier Kryn 2007-04-02 9:15 ` Didier Kryn 2007-04-02 9:21 ` Didier Kryn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).