Hi Florian,
I now understand the problem. If an asynPort has autoConnect=true then the pasynCommon->connect() function is called as soon as the asynCommon interface is registered. For ports
created with asynPortDriver this happens in the base class constructor. At that time your derived classes virtual methods have not yet been registered, so it calls asynPortDriver::connect, not your derived class connect() method.
So I have now learned that if your derived class implements the connect() method and if autoConnect is true, then you must do the following in your derived class constructor:
- Call pasynManager->disconnect, because the base class connect method will have succeeded, and asynManager will think the port is connected
- Call your derived class connect() method directly
I have modified your driver to do this:
********************************************
diff -U2 drvAsynI2c/drvAsynI2CApp/src/drvAsynI2C.cpp drvAsynI2c_new/drvAsynI2CApp/src/
--- drvAsynI2c/drvAsynI2CApp/src/drvAsynI2C.cpp 2016-01-18 03:52:49.000000000 -0600
+++ drvAsynI2c_new/drvAsynI2CApp/src/drvAsynI2C.cpp 2016-01-18 18:20:07.361358828 -0600
@@ -376,4 +376,5 @@
///------------------------------------------------------------------------------
asynStatus drvAsynI2C::connect( asynUser *pasynUser ) {
+printf("%s: drvAsynI2C::connect entry, device=%s\n", portName, _deviceName);
if( _fd >= 0 ) {
epicsSnprintf( pasynUser->errorMessage,pasynUser->errorMessageSize,
@@ -434,7 +435,21 @@
0 ) // Default stack size
{
+ asynStatus status;
+
_deviceName = epicsStrDup( ttyName );
_fd = -1;
_slaveAddress = 0;
+
+ if (autoConnect) {
+ // If autoConnect is true then asynPortDriver::connect will have been called by the asynPortDriver
+ // constructor and asynManager will think the port is connected. Must disconnect and then call
+ // our connect() method
+ pasynManager->exceptionDisconnect(pasynUserSelf);
+ status = this->connect(pasynUserSelf);
+ if (status) {
+ asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
+ "drvAsynI2C::drvAsynI2C, error calling connect %s\n", pasynUserSelf->errorMessage);
+ }
+ }
// createParam( SLAVEADDRESS_STRING, asynParamInt32, &_paramSlaveAddress );
********************************************
This is what I then get when I run the IOC. Note that on my system connect() will fail because I don't have an I2C device.
drvAsynI2CConfigure( "I2C", "/dev/i2c-1", 1 )
I2C: drvAsynI2C::connect entry, device=/dev/i2c-1
2016/01/18 18:20:51.369 drvAsynI2C::drvAsynI2C, error calling connect I2C: Can't open /dev/i2c-1: No such file or directory
dbLoadRecords("/home/epics/devel/asyn/db/asynRecord.db", "P=test:,R=asyn,OMAX=80,IMAX=80,PORT=I2C,ADDR=0")
iocInit()
Starting iocInit
############################################################################
## EPICS R3.14.12.5 $Date: Tue 2015-03-24 09:57:35 -0500$
## EPICS Base built Dec 9 2015
############################################################################
2016/01/18 18:20:51.370 test:asyn: queueRequest failed
I2C: drvAsynI2C::connect entry, device=/dev/i2c-1
The final message is because autoConnect is true and the initial connect failed. asynManager will keep periodically trying to connect the device.
Mark
-----Original Message-----
From: Florian Feldbauer [mailto:[email protected]]
Sent: Monday, January 18, 2016 9:57 AM
To: Mark Rivers; [email protected]
Subject: Re: Device Support for I2C and GPIO
Hey
On 01/18/2016 03:07 PM, Mark Rivers wrote:
> The error you were getting was in the pasynOctet->write() method. But was that method actually being called from the asynRecord, i.e. were you using the asynRecord to do the write operation to the driver? If so, how did you do that?
Or were you using some other device support like streamDevice or devGpib?
I've used the asynRecord. The records looks like this:
record( asyn, "TEST" ) {
field( DTYP, "asynRecordDevice" )
field( PORT, "I2C" )
field( ADDR, "0" )
field( IFACE, "asynOctet" )
## AsynOctet output
field( OEOS, "" )
field( OFMT, "Binary" )
field( OMAX, "6" )
## AsynOctet input
field( IEOS, "" )
field( IFMT, "Binary" )
field( IMAX, "2" )
field( NRRD, "2" )
}
To write to the device I run the command `caput -a TEST.BOUT 2 33 2`
>
> Regarding autoConnect, please put a simple printf at the start of your ::connect() function so you can see if it is being called. When you run asynReport does asynManager say the port is connected when the only thing that should have
been run is autoConnect, i.e. you do not manually connect it? If asynReport says the port is connected then I find it hard to believe that your ::connect method was not called.
Ok. I now put in the line
printf( "%s: Open connection to %s\n", portName, _deviceName );
as the first line of my connect funciton.
For some reason asynReports says the device is connected, but the printf
is not present in the shell.
The output from both, autoConnect on and off, are below:
drvAsynI2CConfigure( "I2C", "/dev/i2c-1", 1 )
dbLoadRecords("/home/debian/i2cTest/db/asyn.db")
iocInit()
Starting iocInit
############################################################################
## EPICS R3.14.12.5-3.14.12.5-3~jessie $Date: Tue 2015-03-24 09:57:35 -0500$
## EPICS Base built Aug 31 2015
############################################################################
iocRun: All initialization complete
asynReport 1 I2C
I2C multiDevice:No canBlock:Yes autoConnect:Yes
enabled:Yes connected:Yes numberConnects 1
nDevices 0 nQueued 0 blocked:No
asynManagerLock:No synchronousLock:No
exceptionActive:No exceptionUsers 1 exceptionNotifys 0
traceMask:0x8 traceIOMask:0x8 traceInfoMask:0x1
Port: I2C
Timestamp: <undefined>
Input EOS[0]:
Output EOS[0]:
Parameter list 0
Number of parameters is: 0
When manually connecting:
drvAsynI2CConfigure( "I2C", "/dev/i2c-1", 0 )
dbLoadRecords("/home/debian/i2cTest/db/asyn.db")
iocInit()
Starting iocInit
############################################################################
## EPICS R3.14.12.5-3.14.12.5-3~jessie $Date: Tue 2015-03-24 09:57:35 -0500$
## EPICS Base built Aug 31 2015
############################################################################
iocRun: All initialization complete
asynReport 1 I2C
I2C multiDevice:No canBlock:Yes autoConnect:No
enabled:Yes connected:No numberConnects 0
nDevices 0 nQueued 0 blocked:No
asynManagerLock:No synchronousLock:No
exceptionActive:No exceptionUsers 1 exceptionNotifys 0
traceMask:0x8 traceIOMask:0x8 traceInfoMask:0x1
Port: I2C
Timestamp: <undefined>
Input EOS[0]:
Output EOS[0]:
Parameter list 0
Number of parameters is: 0
epics> dbpf TEST.CNCT "Connect"
I2C: Open connection to /dev/i2c-1
2016/01/18 15:52:11.712 I2C: Open connection to /dev/i2c-1
DBR_STRING: "Connect"
Florian
>
> Mark
>
>
> ________________________________________
> From: Florian Feldbauer [[email protected]]
> Sent: Monday, January 18, 2016 4:00 AM
> To: Mark Rivers;
[email protected]
> Subject: Re: Device Support for I2C and GPIO
>
> Hey Marc,
>
> as far is I have seen, the asynRecord is not printing the error message
> to the iocsh,
> put is storing it inside the ERRS field.
> I have now found another ADC with uses the same supply voltage as the
> BeagleBone,
> so now I can communicate with it.
>
> The only thing which still does not work, is the autoConnect.
> When setting autoConnect to 1, the device seems to never connect.
>
> I uploaded the latest version of my code here
>
http://www.ep1.rub.de/~florian/drvAsynI2c.tar.gz
>
> in case someone wants to look at it....
>
> Cheers,
> Florian
>
>
> On 01/14/2016 10:01 PM, Mark Rivers wrote:
>>> So the asynOctet/asynRecord do not print the error Message of the asynUser?
>> Yes, it should print the error message
>>
>> The asynRecordThe asynRecord::performOctetIO function calls asynRecord::reportError passing pasynUser->errorMessage if the write returns an error. reportError calls asynPrint.
>>
>> Here is the code snippet from performOctetIO:
>>
>> status = pasynRecPvt->pasynOctet->write(pasynRecPvt->asynOctetPvt,
>> pasynUser, outptr, nwrite, &nbytesTransfered);
>> if (saveEosLen)
>> pasynRecPvt->pasynOctet->setOutputEos(pasynRecPvt->asynOctetPvt,
>> pasynUser,saveEosBuf,saveEosLen);
>> } else {
>> /* ASCII or Hybrid mode */
>> status = pasynRecPvt->pasynOctet->write(pasynRecPvt->asynOctetPvt,
>> pasynUser, outptr, nwrite, &nbytesTransfered);
>> }
>> pasynRec->nawt = (int)nbytesTransfered;
>> asynPrintIO(pasynUser, ASYN_TRACEIO_DEVICE, outptr, nbytesTransfered,
>> "%s: nwrite=%lu, status=%d, nawt=%lu\n", pasynRec->name, (unsigned long)nwrite,
>> status, (unsigned long)nbytesTransfered);
>> if(status != asynSuccess || nbytesTransfered != nwrite) {
>> /* Something is wrong if we couldn't write everything */
>> reportError(pasynRec, status, "Write error, nout=%d, %s",
>> nbytesTransfered, pasynUser->errorMessage);
>> }
>>
>> I suspect your problem is that you are not calling the pasynOctet->write() method from the asynRecord, you are calling it from some other device support? What device support are you using? streamDevice or devGpibio? They call the
driver, and it is their responsibility to print the error message, including pasynUser->errorMessage.
>>
>> If you actually did the I/O from the asynRecord (which you inquired about earlier) then I think you would see the correct error message.
>>
>> You could probably also use the standard asyn device support for the asynOctet interface with a stringout or waveform record and that should also print the correct error message.
>>
>> Mark
>>
>> -----Original Message-----
>> From: Florian Feldbauer [mailto:[email protected]]
>> Sent: Thursday, January 14, 2016 11:32 AM
>> To: Mark Rivers; 'Pete Jemian';
[email protected]
>> Subject: Re: Device Support for I2C and GPIO
>>
>> So the asynOctet/asynRecord do not print the error Message of the asynUser?
>>
>> I guess I found the source of that write failing error. I have connected
>> an ADC to the I2C bus.
>> But the BeagleBone uses 3.3V as high level....according to the data
>> sheet this is the threshold for
>> a high level, because the ADC works normally with 5V.
>> Looking at the scope, the ADC doesn't send a ACK bit to the BeagleBone.
>> I will place a level shifter between both ics and try again.
>>
>> Could an error like this also cause the autoConnect to fail?
>>
>> Best regards,
>> Florian
>>
>> On 01/14/2016 03:44 PM, Mark Rivers wrote:
>>> epicsSnprintf does not print a message. It places the error message in pasynUser->errorMessage. It is then the responsibility of the calling code (e.g. device support, etc.) to print the message if so desired.
>>>
>>> Mark
>>>
>>> ________________________________________
>>> From: Florian Feldbauer [[email protected]]
>>> Sent: Thursday, January 14, 2016 8:38 AM
>>> To: Mark Rivers; 'Pete Jemian';
[email protected]
>>> Subject: Re: Device Support for I2C and GPIO
>>>
>>> Hey again,
>>>
>>> somehow the error message from
>>> if( 0 > thisWrite && ( errno != EWOULDBLOCK )
>>> && ( errno != EINTR )
>>> && ( errno != EAGAIN ) ) {
>>> epicsSnprintf( pasynUser->errorMessage,
>>> pasynUser->errorMessageSize,
>>> "%s: %s write error: %s",
>>> portName, _deviceName, strerror( errno ) );
>>> status = asynError;
>>> break;
>>> }
>>>
>>> this block is not printed. I replaced the epicsSnprintf call with asynPrint
>>> and then I get the following:
>>>
>>> 2016/01/14 14:35:07.229 I2C: /dev/i2c-1 write error: Remote I/O error
>>> 2016/01/14 14:35:07.231 I2C: wrote 1 bytes to /dev/i2c-1, return asynError
>>>
>>> So there is still a problem accessing the device itself...I will test
>>> this furher outside
>>> EPICS with a standalone C program, to see why this Remote I/O error occures.
>>>
>>> Many thanks for your help so far!!
>>>
>>> Florian
>>>
>>>
>>> On 01/14/2016 03:01 PM, Mark Rivers wrote:
>>>> Hi Florian,
>>>>
>>>> If you set autoConnect=1 then after iocInit please send the output of
>>>>
>>>> asynReport 1 I2C
>>>>
>>>> Your driver printed this:
>>>> 2016/01/14 13:11:54.967 I2C: wrote 1 bytes to /dev/i2c-1, return asynError
>>>>
>>>> Why is it returning asynError if the write was successful?
>>>>
>>>>> I have a question concerning the asynRecord.
>>>>> To read out the control register of my ADC I have to send the two bytes 0x42 0x02.
>>>>> Is this possible using the asyn record with OFMT="Binary" ?
>>>>> How would the corresponding put to the BOUT field look like?
>>>> Yes, this is possible. If you are doing the put from a programming language (C, Python, etc.) you would just send a byte array of length 2 containing those bytes.
>>>>
>>>> >From the command line you can do this with caput. I don't think you can use hex notation, but the following appears to work using decimal notation:
>>>>
>>>> corvette:~>caput -a quadEMTest:TetrAMM:Asyn.BOUT 2 66 2
>>>> Old : quadEMTest:TetrAMM:Asyn.BOUT 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>>>> New : quadEMTest:TetrAMM:Asyn.BOUT 80 66 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>>>>
>>>> Mark
>>>>
>>>> ________________________________________
>>>> From: Florian Feldbauer [[email protected]]
>>>> Sent: Thursday, January 14, 2016 7:33 AM
>>>> To: Mark Rivers; 'Pete Jemian';
[email protected]
>>>> Subject: Re: Device Support for I2C and GPIO
>>>>
>>>> Hey,
>>>>
>>>> concerning the compiler error, I uploaded the unfinished version from my
>>>> desktop PC instead of
>>>> the one used on the Beagle Bone...I now uploaded the correct version.
>>>> Link is still the same.
>>>> Sorry for the mistake!
>>>>
>>>> I also tested the asynRecord. This is my record:
>>>> record( asyn, "TEST" ) {
>>>> field( DTYP, "asynRecordDevice" )
>>>> field( PORT, "I2C" )
>>>> field( ADDR, "0" )
>>>> field( IFACE, "asynOctet" )
>>>>
>>>> ## AsynOctet output
>>>> field( OEOS, "" )
>>>> field( OFMT, "Binary" )
>>>>
>>>> ## AsynOctet input
>>>> field( IEOS, "" )
>>>> field( IFMT, "Binary" )
>>>> }
>>>>
>>>> in the IOC I checked the following:
>>>> iocRun: All initialization complete
>>>> dbgf TEST.PCNCT
>>>> DBR_STRING: "Connect"
>>>> dbgf TEST.CNCT
>>>> DBR_STRING: "Connect"
>>>> dbgf TEST.ENBL
>>>> DBR_STRING: "Enable"
>>>> dbgf TEST.AUCT
>>>> DBR_STRING: "autoConnect"
>>>> dbgf TEST.ERRS
>>>> DBR_CHAR[100]: "" + ""
>>>> dbpf TEST.NOWT 1
>>>> DBR_LONG: 1 0x1
>>>> dbpf TEST.BOUT B
>>>> DBR_CHAR[2]: "B"
>>>> dbgf TEST.ERRS
>>>> DBR_CHAR[100]: "error nread 0 I2C: /dev/i2c-1 disconnected:" + ""
>>>>
>>>> "I2C: /dev/i2c-1 disconnected:" is the error message when
>>>> asynOctet->read is called,
>>>> but the file handle (drvAsynI2c::_fd) is negative, so either ::connect()
>>>> was not called,
>>>> or the connect failed without printing the error message.
>>>>
>>>> I set autoConnect to false in my code, and tried it again:
>>>> dbgf TEST.PCNCT
>>>> DBR_STRING: "Connect"
>>>> dbgf TEST.CNCT
>>>> DBR_STRING: "Disconnect"
>>>> dbgf TEST.ENBL
>>>> DBR_STRING: "Enable"
>>>> dbgf TEST.AUCT
>>>> DBR_STRING: "noAutoConnect"
>>>> dbpf TEST.CNCT "Connect"
>>>> 2016/01/14 13:11:54.957 I2C: Open connection to /dev/i2c-1
>>>> DBR_STRING: "Connect"
>>>> dbgf TEST.ERRS
>>>> DBR_CHAR[100]: "" + ""
>>>> dbpf TEST.NOWT 1
>>>> DBR_LONG: 1 0x1
>>>> dbpf TEST.BOUT B
>>>> 2016/01/14 13:11:54.964 I2C: read 0 bytes from /dev/i2c-1, return asynError
>>>> 2016/01/14 13:11:54.965 drvAsynI2C::writeOctet: trying to send 2 bytes
>>>> drvAsynI2C::writeOctet: sending: 0x420x00
>>>> 2016/01/14 13:11:54.967 I2C: wrote 1 bytes to /dev/i2c-1, return asynError
>>>> 2016/01/14 13:11:54.969 I2C: read 0 bytes from /dev/i2c-1, return asynError
>>>> DBR_CHAR[2]: "B"
>>>> dbgf TEST.ERRS
>>>> DBR_CHAR[100]:
>>>> "error nread 0 I2C: /dev/i2c-1 read error: Remote I/O error" + ""
>>>>
>>>> So with this second test, writing works, but reading not. The beaglebone
>>>> doesn't continue the clock for reading...
>>>> I will further study the problem...
>>>>
>>>> I have a question concerning the asynRecord. To read out the control
>>>> register of my ADC I have to send
>>>> the two bytes 0x42 0x02.
>>>> Is this possible using the asyn record with OFMT="Binary" ? How would
>>>> the corresponding put to the BOUT field look like?
>>>>
>>>> Cheers
>>>> Florian
>>>>
>>>>
>>>> On 01/12/2016 09:02 PM, Mark Rivers wrote:
>>>>> You can also load an asynRecord in your IOC. With that you can turn AutoConnect on and off, and you can manually force calls to ::connect() and ::disconnect() from medm. If you do that then do you see your methods being called?
>>>>>
>>>>> Mark
>>>>>
>>>>> ________________________________________
>>>>> From: Florian Feldbauer [[email protected]]
>>>>> Sent: Tuesday, January 12, 2016 8:58 AM
>>>>> To: Mark Rivers; 'Pete Jemian';
[email protected]
>>>>> Subject: Re: Device Support for I2C and GPIO
>>>>>
>>>>> Hey,
>>>>>
>>>>> the current version of my code can be found here:
>>>>>
http://www.ep1.rub.de/~florian/drvAsynI2C.tar.gz
>>>>>
>>>>> The value for the writeOctet and readOctet is expected to be
>>>>> a bitstream.
>>>>> Currently I tried to use StreamDevice as the interface between records
>>>>> and asynPortDriver...
>>>>>
>>>>> Florian
>>>>>
>>>>>
>>>>> On 01/12/2016 01:22 PM, Mark Rivers wrote:
>>>>>> Your derived method's connect function should be called. Can you send your code? I'll take a look and see if I can spot anything wrong.
>>>>>>
>>>>>> Mark
>>>>>>
>>>>>> ________________________________________
>>>>>> From: Florian Feldbauer [[email protected]]
>>>>>> Sent: Tuesday, January 12, 2016 4:38 AM
>>>>>> To: Mark Rivers; 'Pete Jemian';
[email protected]
>>>>>> Subject: Re: Device Support for I2C and GPIO
>>>>>>
>>>>>> Hey Marc, hey all!
>>>>>>
>>>>>> unfortunately, I did not had the time to write and test the I2C device
>>>>>> support last year.
>>>>>> But now I have the time and I'm currently facing a problem:
>>>>>> My I2C device support is written as a class derived from the asynPortDriver,
>>>>>> reimplementing writeOctet, readOctet, connect and disconnect.
>>>>>>
>>>>>> When calling the ctor of asynPortDriver I set the "autoConnect" flag to 1,
>>>>>> but the connect function of my class is never called, thus the file
>>>>>> handle for the
>>>>>> I2C interface is never opened.
>>>>>>
>>>>>> Is there something I'm missing?
>>>>>> I thought autoConnect means that the connect function is automatically
>>>>>> called?
>>>>>>
>>>>>> Cheers
>>>>>> Florian
>>>>>>
>>>>>> On 11/25/2015 06:24 PM, Mark Rivers wrote:
>>>>>>> The I2C asyn driver could be considered for going into asyn itself, since it is conceptually similar to the serial, IP, GPIB, USBTMC, and VXI11 drivers.
>>>>>>>
>>>>>>> Note that "ip" is really not for software related to Industry Pack modules any more. Most industry pack drivers now have their own modules (ip330, ipUnidig, dac128V, softGlue, ipac for ipOctal). "ip" is really now software
for asynOctet devices (serial, GPIB, TCP) that do not have another home like "vac" and "delayGen". "ip" is no longer a good name for it.
>>>>>>>
>>>>>>> Similarly "std" was originally the home for a lot "standard" beamline control stuff. Most of this has now been moved to other modules (calc, busy, optics, sscan), so "std" is more like "misc" now.
>>>>>>>
>>>>>>> Mark
>>>>>>>
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From:
[email protected] [mailto:[email protected]] On Behalf Of Pete
Jemian
>>>>>>> Sent: Wednesday, November 25, 2015 11:10 AM
>>>>>>> To: [email protected]
>>>>>>> Subject: Re: Device Support for I2C and GPIO
>>>>>>>
>>>>>>> Michael describes a good procedure for completely new functionality.
>>>>>>> New modules should provide support distinct from other modules.
>>>>>>>
>>>>>>> This _might_ have a place in one of the existing synApps modules. This
>>>>>>> is not "ip" functionality (related to Industry Pack modules), not
>>>>>>> "calc", not "optics", perhaps "std" is the catchall module for new
>>>>>>> synApps support?
>>>>>>>
>>>>>>> On 11/25/2015 9:08 AM, Michael Davidsaver wrote:
>>>>>>>> On 11/25/2015 03:08 AM, Florian Feldbauer wrote:
>>>>>>>>> I would like to upload the sources to github. Is it possible to upload
>>>>>>>>> it to the "epics-modules" group?
>>>>>>>> At this point there isn't any established criteria for when/if
>>>>>>>> repositories in this group are created.
>>>>>>>> It would suggest starting with a repository under your own account (what
>>>>>>>> I do), then think about moving to epics-modules at some later date,
>>>>>>>> which isn't difficult.
>>>>>>>>
>>>>>>>> That said, if you want to go straight to epics-modules I'm inclined to
>>>>>>>> just add it. Let me know if you want to do this and I'll do this in a
>>>>>>>> day or so, assuming no one objects. Of course, first you need to solve
>>>>>>>> the hard problem, the repository name ;)
>>>>>>>>
>>>>>>>>
>>>>>>>> Michael
>>>>>>>>
>>>>>> --
>>>>>> ----------------------------------------
>>>>>> | Dr. Florian Feldbauer |
>>>>>> | |
>>>>>> | Helmholtz-Institut Mainz / |
>>>>>> | Johannes Gutenberg-Universität Mainz |
>>>>>> | Johann-Joachim-Becher-Weg 36 |
>>>>>> | D-55128 Mainz |
>>>>>> | |
>>>>>> | Office: SB1 / 00-213 |
>>>>>> | Phone: (+49)6131 / 39-29605 |
>>>>>> ----------------------------------------
>>>>>>
>>>>> --
>>>>> ----------------------------------------
>>>>> | Dr. Florian Feldbauer |
>>>>> | |
>>>>> | Helmholtz-Institut Mainz / |
>>>>> | Johannes Gutenberg-Universität Mainz |
>>>>> | Johann-Joachim-Becher-Weg 36 |
>>>>> | D-55128 Mainz |
>>>>> | |
>>>>> | Office: SB1 / 00-213 |
>>>>> | Phone: (+49)6131 / 39-29605 |
>>>>> ----------------------------------------
>>>>>
>>>> --
>>>> ----------------------------------------
>>>> | Dr. Florian Feldbauer |
>>>> | |
>>>> | Helmholtz-Institut Mainz / |
>>>> | Johannes Gutenberg-Universität Mainz |
>>>> | Johann-Joachim-Becher-Weg 36 |
>>>> | D-55128 Mainz |
>>>> | |
>>>> | Office: SB1 / 00-213 |
>>>> | Phone: (+49)6131 / 39-29605 |
>>>> ----------------------------------------
>>>>
>>> --
>>> ----------------------------------------
>>> | Dr. Florian Feldbauer |
>>> | |
>>> | Helmholtz-Institut Mainz / |
>>> | Johannes Gutenberg-Universität Mainz |
>>> | Johann-Joachim-Becher-Weg 36 |
>>> | D-55128 Mainz |
>>> | |
>>> | Office: SB1 / 00-213 |
>>> | Phone: (+49)6131 / 39-29605 |
>>> ----------------------------------------
>>>
> --
> ----------------------------------------
> | Dr. Florian Feldbauer |
> | |
> | Helmholtz-Institut Mainz / |
> | Johannes Gutenberg-Universität Mainz |
> | Johann-Joachim-Becher-Weg 36 |
> | D-55128 Mainz |
> | |
> | Office: SB1 / 00-213 |
> | Phone: (+49)6131 / 39-29605 |
> ----------------------------------------
>
--
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universität Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------