Hey all,
using streamDevice from github it works now works in combination with my
I2C driver.
In case others are interested, I put the code on github:
https://github.com/ffeldbauer/drvAsynI2C
There is still a small issue using streamDevice:
If enabling the debug output I get the following:
2016/01/19 18:32:04.769482 I2C AsynDriverInterface.cc:752:
AsynDriverInterface::readRequest(AD7998:33:CTRLREGISTER:READ, 100 msec
reply, 100 msec read, expect 2 bytes, async=no)
2016/01/19 18:32:04.772000 I2C AsynDriverInterface.cc:777:
AsynDriverInterface::readRequest AD7998:33:CTRLREGISTER:READ:
queueRequest(..., priority=0, queueTimeout=0.1 sec) = asynSuccess
[async=false]
2016/01/19 18:32:04.774785 I2C AsynDriverInterface.cc:1438:
AsynDriverInterface::handleRequest(AD7998:33:CTRLREGISTER:READ) Read
2016/01/19 18:32:04.776092 I2C AsynDriverInterface.cc:837:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ) input EOS
set to
2016/01/19 18:32:04.777315 I2C AsynDriverInterface.cc:896:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ):
ioAction=Read read(..., bytesToRead=1, ...) [timeout=0.1 sec]
2016/01/19 18:32:04.781795 I2C AsynDriverInterface.cc:903:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ): read
returned asynSuccess: ioAction=Read received=1, eomReason=CNT, buffer="<00>"
2016/01/19 18:32:04.783058 I2C AsynDriverInterface.cc:910:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ): device is
now connected
2016/01/19 18:32:04.784266 I2C AsynDriverInterface.cc:948:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ): received
1 of 1 bytes "<00>" eomReason=CNT
2016/01/19 18:32:04.786068 I2C StreamCore.cc:938:
StreamCore::readCallback(AD7998:33:CTRLREGISTER:READ,
status=StreamIoSuccess input="<00>", size=1)
2016/01/19 18:32:04.787383 I2C StreamCore.cc:994:
StreamCore::readCallback(AD7998:33:CTRLREGISTER:READ)
inputBuffer="<00>", size 1
2016/01/19 18:32:04.789140 I2C StreamCore.cc:1075:
StreamCore::readCallback(AD7998:33:CTRLREGISTER:READ) wait for more input
2016/01/19 18:32:04.790333 I2C AsynDriverInterface.cc:1074:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ) readMore=1
bytesToRead=1
2016/01/19 18:32:04.792323 I2C AsynDriverInterface.cc:896:
AsynDriverInterface::readHandler(AD7998:33:CTRLREGISTER:READ):
ioAction=Read read(..., bytesToRead=1, ...) [timeout=0.1 sec]
My ADC has 16-bit registers, so I have to read 2 bytes. But for the
first read call inside the readHandler the length is hardcoded to 1
(lines 854/901 in AsynDriverInterface.cc).
The problem is, that the kernel module for the I2C bus is not buffering.
If one calls `read( fd, buffer, bytesToRead )` then the kernel module
sends the slave address with the R/!W bit set, and reads "bytesToRead"
bytes from the bus.
Calling the function again repeats this procedure. That means, with the
above log I read two times the high byte of the control register, but
never the low byte.
A possible workaround I'm now using is to read 3 bytes.
The second read call (last line of the debug output) than has
bytesToRead=2. In the protocol I'm using
in "%*01r%02r";
Of course one can also patch streamDevice, but without looking deeper
into the code (and without having proper knowledge about all the other
drivers accessed with the same method),
I'm not sure if there is a reason for setting the peaksize hardcoded to 1.
Thanks to everyone for the support!
Florian
On 01/19/2016 03:28 PM, Florian Feldbauer wrote:
Hey,
I'm using version 2.6 with the 3 "official" patches from the
StreamDevice webpage
which are all in deed dated from 2012...
I will switch to the version at github and test it again!
Thanks for the info!
Florian
On 01/19/2016 02:20 PM, Mark Rivers wrote:
Hi Florian,
What version of streamDevice are you using?
I fixed the problem you are having in April 2014. My fix is in the
version on github (https://github.com/epics-modules/stream):
********************************
commit 02e5f0a2a7eda45c7e13b0d66f7c1675b671204e
Author: MarkRivers <[email protected]>
Date: Fri Apr 11 19:03:22 2014 +0000
Fix for infinite loop in WriteHandler for disconnected devices
********************************
This is the patch:
********************************
corvette:stream/streamDevice/src>git diff
f0fe997b0dbf60285b5c7dd328805ba06105022f AsynDriverInterface.cc
diff --git a/streamDevice/src/AsynDriverInterface.cc
b/streamDevice/src/AsynDriverInterface.cc
index 8f64180..1ae3e7f 100644
--- a/streamDevice/src/AsynDriverInterface.cc
+++ b/streamDevice/src/AsynDriverInterface.cc
@@ -630,6 +630,7 @@ writeHandler()
int eomReason = 0;
status = pasynOctet->read(pvtOctet, pasynUser,
buffer, received, &received, &eomReason);
+ if (status == asynError) break;
#ifndef NO_TEMPORARY
if (received) debug("AsynDriverInterface::writeHandler(%s):
flushing %ld bytes: \"%s\"\n",
clientName(), (long)received, StreamBuffer(buffer,
received).expand()());
********************************
This problem came up again in November 2015 in this tech-talk thread:
http://www.aps.anl.gov/epics/tech-talk/2015/msg01836.php
In both cases Dirk Zimoch, the author of streamDevice, was e-mailed
with the patch. Unfortunately there has not been an official release
of streamDevice since 2.6, which I believe dates from 2012.
I would recommend using either the master branch or release 2-6c from
the github link above.
Mark
________________________________
From: [email protected] [[email protected]]
on behalf of Florian Feldbauer [[email protected]]
Sent: Tuesday, January 19, 2016 6:26 AM
To: [email protected]; [email protected]
Subject: Re: Device Support for I2C and GPIO -> StreamDevice
Hey,
I had a look at the code of streamDevice
If I understood it correct, the write command of the
protocol is performed by the function
AsynDriverInterface::writeHandler()
Looking at the lines 621 and following of the source this might cause
the problem:
pasynUser->timeout = 0;
if (pasynGpib)
pasynOctet->flush(pvtOctet, pasynUser);
else
// discard any early input, but forward it to potential async
records
// thus do not use pasynOctet->flush()
do {
char buffer [256];
size_t received = sizeof(buffer);
int eomReason = 0;
status = pasynOctet->read(pvtOctet, pasynUser,
buffer, received, &received, &eomReason);
#ifndef NO_TEMPORARY
if (received) debug("AsynDriverInterface::writeHandler(%s):
flushing %ld bytes: \"%s\"\n",
clientName(), (long)received, StreamBuffer(buffer,
received).expand()());
#endif
} while (status != asynTimeout);
Since the read on the I2C bus fails,
pasynOctet->read returns asynError, and not asynTimeout...
so the break condition of the while-loop gets never satisfied.
If I change the return value to asynTimeout it works...
I'm not sure how this works an other buses/ports,
but wouldn't it make sense also to test on errors at this point
in streamDevice?
Florian
On 01/19/2016 10:18 AM, Florian Feldbauer wrote:
Hey,
after having a look at the link provided by Guy, and
looking at which point :connect() is called, it makes sense
that the "wrong" method was called.
With Marks patch it now works!
But I get a new problem now.
I'm now trying to use my I2C asynPortDriver with StreamDevice, but
somehow this doesn't work.
As a first try I want to readout the control register of my ADC
(AD7998-0). Since the control register is
a 16-bit word, where each bit stands for a specific setting, I'm
using a mbbiDirect record.
I also tried using a longin instead. Same effect.
record( mbbiDirect, "AD7998:$(ID):CTRLREGISTER:READ" ) {
field( DTYP, "stream" )
field( INP, "@ad7998.proto rCtrl($(ID)) I2C" )
}
And the protocol file:
Terminator = "";
MaxInput = 2;
ExtraInput = Error;
rCtrl {
#out ${1} 2;
out 33 2;
in "%02r";
}
I put a printf in the writeOctet and readOctet functions, to see what
happens.
epics> dbpf AD7998:33:CTRLREGISTER:READ.PROC 1
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
DBR_UCHAR: 1 0x1
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
epics> I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
I2C: drvAsynI2C::readOctet: maxChars=256
This output continues endlessly...
I cannot see the printf from the writeOctet call, and the readOctet
seems
to be called in an infinite loop with maxChars=256, although I set
MaxInput=2
Am I missing something?
The record above is the only one in my IOC.
Thanks for the help!
Florian
On 01/19/2016 01:40 AM, Mark Rivers wrote:
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]<mailto:[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
[<mailto:[email protected]>[email protected]<mailto:[email protected]>]
Sent: Monday, January 18, 2016 4:00 AM
To: Mark Rivers; <mailto:[email protected]>
<mailto:[email protected]>
[email protected]<mailto:[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<http://www.ep1.rub.de/%7Eflorian/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]><mailto:[email protected]>mailto:[email protected]]
Sent: Thursday, January 14, 2016 11:32 AM
To: Mark Rivers; 'Pete Jemian';
[email protected]<mailto:[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
[<mailto:[email protected]>[email protected]<mailto:[email protected]>]
Sent: Thursday, January 14, 2016 8:38 AM
To: Mark Rivers; 'Pete Jemian';
[email protected]<mailto:[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]<mailto:[email protected]>]
Sent: Thursday, January 14, 2016 7:33 AM
To: Mark Rivers; 'Pete Jemian';
[email protected]<mailto:[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]<mailto:[email protected]>]
Sent: Tuesday, January 12, 2016 8:58 AM
To: Mark Rivers; 'Pete Jemian';
[email protected]<mailto:[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/%7Eflorian/drvAsynI2C.tar.gz>
<http://www.ep1.rub.de/%7Eflorian/drvAsynI2C.tar.gz>
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]<mailto:[email protected]>]
Sent: Tuesday, January 12, 2016 4:38 AM
To: Mark Rivers; 'Pete Jemian';
[email protected]<mailto:[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: <mailto:[email protected]>
<mailto:[email protected]>
[email protected]<mailto:[email protected]>
[mailto:[email protected]] On Behalf Of Pete Jemian
Sent: Wednesday, November 25, 2015 11:10 AM
To: <mailto:[email protected]>
<mailto:[email protected]>
[email protected]<mailto:[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 |
----------------------------------------
--
----------------------------------------
| 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 |
----------------------------------------
- References:
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO Florian Feldbauer
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO Florian Feldbauer
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO Florian Feldbauer
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO Florian Feldbauer
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO Florian Feldbauer
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO Florian Feldbauer
- RE: Device Support for I2C and GPIO Mark Rivers
- Re: Device Support for I2C and GPIO -> StreamDevice Florian Feldbauer
- Re: Device Support for I2C and GPIO -> StreamDevice Florian Feldbauer
- RE: Device Support for I2C and GPIO -> StreamDevice Mark Rivers
- Re: Device Support for I2C and GPIO -> StreamDevice Florian Feldbauer
- Navigate by Date:
- Prev:
Re: Re: Re:Re: Re:Re: EPICS Multiple Archiver Appliance problem Shankar, Murali
- Next:
Senior Controls Software Engineer at Gemini Mathew Rippa
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
<2016>
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: Device Support for I2C and GPIO -> StreamDevice Florian Feldbauer
- Next:
running multiple iocs on raspberry 2 Christian Pauly
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
<2016>
2017
2018
2019
2020
2021
2022
2023
2024
|