The PRIO "HIGH" setting should give the output priority over the input
in the StreamDevice layer. But when you see the output string in asyn
trace, it is already through the StreamDevice layer. So everything seems
fine from the StreamDevice point of view. Also asyn prints this as it
writes its output. Thus from the asyn point of view everything is fine
as well.
What type of connection do you have to the device? RS232?
I have seen RS232 devices, that needed some time between characters.
(Maybe they don't have an input buffer?) When you type in the command
manually, there is usually plenty of time between the chars, but from a
program, there isn't.
What if you write to the serial port from the command line, like:
echo -en "STM\r" > /dev/ttyS0
If that also does not work, then it may be a the character timing.
I have once written an asynInterposeDelay driver to spit out chars one
by one (code attached).
Usage like this:
drvAsynSerialPortConfigure "device", "/dev/ttyS0"
asynInterposeDelay "device", 0, 0.001
It supports dynamic change of the delay as well, so you don't need to
reboot to find the best delay:
asynShowOption "device", 0, "delay"
asynSetOption "device", 0, "delay", 0.05
Maybe that helps.
Dirk
On 29.11.2018 17:00, William Kirstaedter via Tech-talk wrote:
Yes, I am issuing
caput CRYVISIL:TC09:Toggle 0
--
when the IOC starts and the device doesnt already send data, I am able
to toggle with
caput CRYVISIL:TC09:Toggle 1
which results in "STM\r" showing up in the asyn TraceMask, followed by
the stream.
When simulating the process "by hand" with telnet, it's no problem
sending STM and ETM.
William Kirstaedter (PP&B)
Fritz-Haber-Institut der MPG
Faradayweg 4-6
14195 Berlin
Tel: 030 8413 5405
Mail:[email protected]
Am 29.11.2018 um 16:10 schrieb Michael Westfall via Tech-talk:
How are you commanding the bo record?
Are you sure its value is being commanded to zero when you want to
stop reading?
Did you try something like, 'caput xxx:Toggle 0' ?
On Thu, Nov 29, 2018 at 10:21 AM William Kirstaedter via Tech-talk
<[email protected] <mailto:[email protected]>> wrote:
Hi Dirk,
thanks for the quick answer.
I have set
field(PRIO, "HIGH")
but this doesnt seem to do anything?
I have asynTraceMask on aswell but I dont see the "ETM" command ever
pass through...
William Kirstaedter (PP&B)
Fritz-Haber-Institut der MPG
Faradayweg 4-6
14195 Berlin
Tel: 030 8413 5405
Mail: [email protected]
<mailto:[email protected]>
Am 29.11.2018 um 13:37 schrieb Dirk Zimoch via Tech-talk:
> Hi William,
>
> Have you tried to give the output record a high priority?
>
> Dirk
>
> On 29.11.2018 13:27, William Kirstaedter via Tech-talk wrote:
>> I'm sorry to send this again but my first mail got soft-rejected
>> because I wasnt a subscriber.
>>
>> William Kirstaedter (PP&B)
>> Fritz-Haber-Institut der MPG
>> Faradayweg 4-6
>> 14195 Berlin
>> Tel: 030 8413 5405
>> Mail: [email protected]
<mailto:[email protected]>
>>
>> Am 29.11.2018 um 11:34 schrieb William Kirstaedter:
>>> Hi,
>>>
>>> I have a small problem with a fast Device, maybe somebody already
>>> had this problem and can help out? :)
>>>
>>> It runs via I/O Intr.
>>> I am able to start the reporting, but I cant stop it. It seems
that
>>> the stop command doesnt get through....
>>> could it be that somehow the communication is blocked by the fast
>>> input? how could I fix that?
>>>
>>> Its really simple to control:
>>> You send "STM\r", it starts reporting every 18ms
>>> "tmp,<float>,<float>\r"
>>> You send "ETM\r", it stops doing that, terminating communication
>>> with "txx\r".
>>>
>>> all ASCII formatted.
>>>
>>> my records:
>>>
>>> tc.db file:
>>>
>>> record(bo, "$(P):$(R):Toggle"){
>>> field(DESC, "Toggle Reading")
>>> field(DTYP, "stream")
>>> field(OUT, "@tc.proto toggle $(BUS)")
>>> field(ZNAM, "ETM")
>>> field(ONAM, "STM")
>>> field(VAL, "0")
>>> }
>>>
>>> record(ai, "$(P):$(R):Temperature") {
>>> field(DESC, "Temperature")
>>> field (DTYP, "stream")
>>> field (INP, "@tc.proto read_K $(BUS)")
>>> field (SCAN, "I/O Intr")
>>> field(EGU, "K")
>>> }
>>>
>>> record(ai, "$(P):$(R):ThermoVoltage"){
>>> field(DESC, "TC Thermovoltage")
>>> field(DTYP, "stream")
>>> field(INP, "@tc.proto read_nV $(BUS)")
>>> field(SCAN, "I/O Intr")
>>> field(EGU, "nV")
>>> }
>>>
>>> tc.proto file:
>>>
>>> Terminator = CR;
>>> ExtraInput = Ignore;
>>>
>>>
>>> toggle {
>>> out "%{ETM|STM}";
>>> in "txx";
>>> };
>>>
>>> read_K {
>>> in "tmp,%f,%*f";
>>> };
>>>
>>> read_nV {
>>> in "tmp,%*f,%f";
>>> };
>>>
>>
>>
----------------------------------------------------------------------
>> Das FHI verarbeitet, speichert und loescht Daten im Rahmen seiner
>> Geschaeftstaetigkeit gemaess der Datenschutz-Grundverordnung
(DSGVO)
>> [General Data Protection Regulation (GDPR)] der Europaeischen
Union.
>>
----------------------------------------------------------------------
Das FHI verarbeitet, speichert und loescht Daten im Rahmen seiner
Geschaeftstaetigkeit gemaess der Datenschutz-Grundverordnung (DSGVO)
[General Data Protection Regulation (GDPR)] der Europaeischen Union.
--
Mike Westfall
Control Systems Software Engineer
----------------------------------------------------------------------
Das FHI verarbeitet, speichert und loescht Daten im Rahmen seiner
Geschaeftstaetigkeit gemaess der Datenschutz-Grundverordnung (DSGVO)
[General Data Protection Regulation (GDPR)] der Europaeischen Union.
registrar(asynInterposeDelayRegister)
/*asynInterposeDelay.c */
/***********************************************************************/
/* Interpose for devices where each written char needs a delay
* before sending the next char.
*
* Author: Dirk Zimoch
*/
#include <cantProceed.h>
#include <epicsStdio.h>
#include <epicsString.h>
#include <epicsThread.h>
#include <iocsh.h>
#include <epicsExport.h>
#include "asynDriver.h"
#include "asynOctet.h"
#include "asynOption.h"
#include <epicsExport.h>
typedef struct interposePvt {
asynInterface octet;
asynOctet *pasynOctetDrv;
void *octetPvt;
asynInterface option;
asynOption *pasynOptionDrv;
void *optionPvt;
double delay;
}interposePvt;
/* asynOctet methods */
static asynStatus writeIt(void *ppvt, asynUser *pasynUser,
const char *data, size_t numchars, size_t *nbytesTransfered)
{
interposePvt *pvt = (interposePvt *)ppvt;
size_t n;
size_t transfered = 0;
asynStatus status = asynSuccess;
while (transfered < numchars) {
/* write one char at a time */
status = pvt->pasynOctetDrv->write(pvt->octetPvt,
pasynUser, data, 1, &n);
if (status != asynSuccess) break;
/* delay */
epicsThreadSleep(pvt->delay);
transfered+=n;
data+=n;
}
*nbytesTransfered = transfered;
return status;
}
static asynStatus readIt(void *ppvt, asynUser *pasynUser,
char *data, size_t maxchars, size_t *nbytesTransfered, int *eomReason)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->read(pvt->octetPvt,
pasynUser, data, maxchars, nbytesTransfered, eomReason);
}
static asynStatus flushIt(void *ppvt, asynUser *pasynUser)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->flush(pvt->octetPvt, pasynUser);
}
static asynStatus registerInterruptUser(void *ppvt, asynUser *pasynUser,
interruptCallbackOctet callback, void *userPvt, void **registrarPvt)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->registerInterruptUser(
pvt->octetPvt,
pasynUser, callback, userPvt, registrarPvt);
}
static asynStatus cancelInterruptUser(void *drvPvt, asynUser *pasynUser,
void *registrarPvt)
{
interposePvt *pvt = (interposePvt *)drvPvt;
return pvt->pasynOctetDrv->cancelInterruptUser(
pvt->octetPvt, pasynUser, registrarPvt);
}
static asynStatus setInputEos(void *ppvt, asynUser *pasynUser,
const char *eos, int eoslen)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->setInputEos(pvt->octetPvt,
pasynUser, eos, eoslen);
}
static asynStatus getInputEos(void *ppvt, asynUser *pasynUser,
char *eos, int eossize, int *eoslen)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->getInputEos(pvt->octetPvt,
pasynUser, eos, eossize, eoslen);
}
static asynStatus setOutputEos(void *ppvt, asynUser *pasynUser,
const char *eos, int eoslen)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->setOutputEos(pvt->octetPvt,
pasynUser, eos, eoslen);
}
static asynStatus getOutputEos(void *ppvt, asynUser *pasynUser,
char *eos, int eossize, int *eoslen)
{
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->pasynOctetDrv->getOutputEos(pvt->octetPvt,
pasynUser, eos, eossize, eoslen);
}
static asynOctet octet = {
writeIt, readIt, flushIt,
registerInterruptUser, cancelInterruptUser,
setInputEos, getInputEos, setOutputEos, getOutputEos
};
/* asynOption methods */
static asynStatus
getOption(void *ppvt, asynUser *pasynUser,
const char *key, char *val, int valSize)
{
interposePvt *pvt = (interposePvt *)ppvt;
if (epicsStrCaseCmp(key, "delay") == 0) {
epicsSnprintf(val, valSize, "%g", pvt->delay);
return asynSuccess;
}
if (pvt->pasynOptionDrv)
return pvt->pasynOptionDrv->getOption(pvt->optionPvt,
pasynUser, key, val, valSize);
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Unknown option \"%s\"", key);
return asynError;
}
static asynStatus
setOption(void *ppvt, asynUser *pasynUser, const char *key, const char *val)
{
interposePvt *pvt = (interposePvt *)ppvt;
if (epicsStrCaseCmp(key, "delay") == 0) {
if(sscanf(val, "%lf", &pvt->delay) != 1) {
epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
"Bad number %s", val);
return asynError;
}
return asynSuccess;
}
if (pvt->pasynOptionDrv)
return pvt->pasynOptionDrv->setOption(pvt->optionPvt,
pasynUser, key, val);
epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
"Unknown option \"%s\"", key);
return asynError;
}
static asynOption option = {
setOption, getOption
};
epicsShareFunc int
asynInterposeDelay(const char *portName, int addr, double delay)
{
interposePvt *pvt;
asynStatus status;
asynInterface *poctetasynInterface;
asynInterface *poptionasynInterface;
pvt = callocMustSucceed(1, sizeof(interposePvt), "asynInterposeDelay");
pvt->octet.interfaceType = asynOctetType;
pvt->octet.pinterface = &octet;
pvt->octet.drvPvt = pvt;
status = pasynManager->interposeInterface(portName, addr,
&pvt->octet, &poctetasynInterface);
if ((status!=asynSuccess) || !poctetasynInterface) {
printf("%s interposeInterface asynOctetType failed.\n", portName);
free(pvt);
return -1;
}
pvt->pasynOctetDrv = (asynOctet *)poctetasynInterface->pinterface;
pvt->octetPvt = poctetasynInterface->drvPvt;
pvt->option.interfaceType = asynOptionType;
pvt->option.pinterface = &option;
pvt->option.drvPvt = pvt;
status = pasynManager->interposeInterface(portName, addr,
&pvt->option, &poptionasynInterface);
if ((status!=asynSuccess) || !poptionasynInterface) {
status = pasynManager->registerInterface(portName,&pvt->option);
if(status != asynSuccess) {
printf("drvAsynSerialPortConfigure: Can't interpose or register option.\n");
}
} else {
pvt->pasynOptionDrv = (asynOption *)poptionasynInterface->pinterface;
}
pvt->delay = delay;
return 0;
}
/* register asynInterposeDelay*/
static const iocshFuncDef asynInterposeDelayFuncDef =
{"asynInterposeDelay", 3, (const iocshArg *[]) {
&(iocshArg) { "portName", iocshArgString },
&(iocshArg) { "addr", iocshArgInt },
&(iocshArg) { "delay(sec)", iocshArgDouble },
}};
static void asynInterposeDelayCallFunc(const iocshArgBuf *args)
{
asynInterposeDelay(args[0].sval, args[1].ival, args[2].dval);
}
static void asynInterposeDelayRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&asynInterposeDelayFuncDef, asynInterposeDelayCallFunc);
}
}
epicsExportRegistrar(asynInterposeDelayRegister);
- Replies:
- Re: streamdevice I/O Intr William Kirstaedter via Tech-talk
- References:
- Re: streamdevice I/O Intr William Kirstaedter via Tech-talk
- Re: streamdevice I/O Intr Dirk Zimoch via Tech-talk
- Re: streamdevice I/O Intr William Kirstaedter via Tech-talk
- Re: streamdevice I/O Intr Michael Westfall via Tech-talk
- Re: streamdevice I/O Intr William Kirstaedter via Tech-talk
- Navigate by Date:
- Prev:
RE: streamdevice I/O Intr Mark Rivers via Tech-talk
- Next:
Re: streamdevice I/O Intr William Kirstaedter via Tech-talk
- 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: streamdevice I/O Intr Dirk Zimoch via Tech-talk
- Next:
Re: streamdevice I/O Intr William Kirstaedter via Tech-talk
- 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
|