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 | 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 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Array Writes to HW Registers - How to ??? |
From: | Stephen Beckwith <[email protected]> |
To: | Mark Rivers <[email protected]> |
Cc: | "[email protected]" <[email protected]> |
Date: | Mon, 14 Apr 2014 15:05:54 -0400 |
I don’t know if one can do a dbpf to write to multiple values in a waveform record, I have never tried this.
But you can do it from the OS shell with caput using the –a option. The first argument after the PV name is the number of value you are writing.
corvette:motor/motorApp/MotorSrc>caget -#20 13LAB:EDB:file
13LAB:EDB:file 20 1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0
corvette:motor/motorApp/MotorSrc>caput –a 13LAB:EDB:file 10 1 2 3 4 5 6 7 8 9 10
Old : 13LAB:EDB:file 128 1 2 3 4 5 6 7 8 9 10 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 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 : 13LAB:EDB:file 128 1 2 3 4 5 6 7 8 9 10 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 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
corvette:motor/motorApp/MotorSrc>caget -#20 13LAB:EDB:file
13LAB:EDB:file 20 1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0
Mark
From: Stephen Beckwith [mailto:[email protected]]
Sent: Monday, April 14, 2014 1:13 PM
To: Mark Rivers
Cc: [email protected]
Subject: Re: Array Writes to HW Registers - How to ???
Mr. Rivers;
Thank you for quick reply! Much Appreciated!
1) Yes, I did see the "asynInt32ArrayOut" in the waveform dbd file, but when I used the "OUT" the DB would complain - Guess it's one of those "nuances" that isn't obvious until you've beat your head against the wall a few times. . .
2) YES!!! this example was EXACTLY what I was looking for. . . THANK YOU!
So. . .
a) Modified the DB accordingly and NO errors on loading - record shows up.
b) Added an FLNK so that when one does a write, this also triggers the "read-back" into the DB. However, something is amiss, but I believe it's with my C code in the int32ArrayWrite() - a place where I can more comfortably debug. . .
A follow-up question:
- When I do the "dbgf" for the _R.VAL PV, it will dump for me the expected (pre-init) values:
epics> dbgf TEST01:Sample1_R.VAL
DBR_LONG[8]: 0 0x0 16 0x10
32 0x20 48 0x30
64 0x40 80 0x50
96 0x60 112 0x70- How do I then "write" this? I was doing a:
epics> dbpf <record>_W.VAL 1 2 3 4 5 6 7 8
==> is this correct?
Thank you for your speedy reply.
Regards,
Stephen Beckwith
On Mon, Apr 14, 2014 at 1:34 PM, Mark Rivers <[email protected]> wrote:
Stephen,
I’m not sure I understood your question correctly in my previous response. Were you thinking that you could not use a waveform record for output?
If you want an example of using a waveform record to write multiple registers at once, my Modbus driver is a good example. Look at the drvModbusAsyn.c::writeInt32Array function and intarray_out.template, which is simply the following:
record(waveform,"$(P)$(R)") {
field(DTYP,"asynInt32ArrayOut")
field(INP,"@asyn($(PORT) 0)MODBUS_DATA")
field(FTVL,"LONG")
field(NELM,"$(NELM)")
}
Mark
From: [email protected] [mailto:[email protected]] On Behalf Of Stephen Beckwith
Sent: Monday, April 14, 2014 12:05 PM
To: [email protected]
Subject: Array Writes to HW Registers - How to ???
Greetings All,
I am currently developing an IOC for a customer (so details will be limited).
EPICS Base: 3.14.12.4
ASYN - 4.22
- I have successfully built both of these "bases" and I have implemented in C code via the ASYN model to provide the following capabilities:
- R/W Strings
- R/W 32 bit registers in the device.
Searching documentation and tech-talk, the way I implemented the 32 bit read/writes was:
record(longin,"$(nodeID)Sample1_R")
{
field(DTYP,"asynInt32")
field(INP,"@asyn(fpga,0x0f)")
field(PINI,"1")
}
record(longout,"$(nodeID)Sample1_W")
{
field(DTYP,"asynInt32")
field(OUT,"@asyn(fpga,0x0f)")
field(FLNK,"$(nodeID)Sample1_R")
}Where:
"fpga" is a "port" that I've created (vs. the strings which use a port called "local") and the address (0x0f) becomes an index into a structure that then maps this to the memory mapped I/O to access the physical HW.
The target platform is a Dual-Core ARM Cortex-A9 driven system running Embedded Linux. I have tested this on the HOST (another Linux based system) successfully. When I write to Sample1_W, EPICS will also do the read to update the DB. OK, so far, so good.
Now I get to where I need to deal with an "array" - a group of 8 x 32 bit registers, that need to be treated as a single entity for reading and writing.
I implemented the "read" via a waveform record and this works OK (other Init code will pre-set this during simulation, so I have something other than 0's to read back). So this is OK.
But I can't seem to find a way to implement the writing of a block of 8 functionality.I haven't found a scheme that works yet, for all 8 at one time. I did develop something using an "aSub" (since subArray is INPUT only, like waveforms. . .), however, the "update to HW register" (i.e. calling the SNAM function) only occurs when the .PROC gets set to 1 (dbpf _W.PROC 1). Whereas when I do the "dbpf" from the cmd line on the host to the Sample1_W.VAL above, this will "write through" to the HW (lots of debug prints. . .). I'm guessing something internal to the DB is causing this action.
This is my "attempt" :
record(aSub, "$(nodeID)BunchOfRegs_W")
{
field(INAM, "arrayInit")
field(SNAM, "arrayWrite")
field(SCAN, "Passive")
field(FTA, "LONG")
field(NOA, "8")
field(OUTA, "$(nodeID)RegWrite")
field(FTVA, "LONG")
field(NOVA, "8")
}
record(longout,"$(nodeID)RegisterElement")
{
field(DESC,"Single Array Entity")
field(OUT, "$(nodeID)BunchOfRegs.VALA")
}Questions:
1) How to properly handle/define writing these 8 registers as a single entity? (meaning, a single call through the DB to C code to loop through and write these to HW vs. having to make 8 DB calls, which would obviously take much longer).
2) If I tried to bolt this up to the the "fpga" port in the ASYN setup (as in the Longout above), I get DB errors about INST_IO and other database related issues. . .
3) In the waveform read scheme, since I know I'm reading a "waveform" (i.e. an array of 8), the VAL passed in is this array, so I just loop through filling in the *val pointer passed into the read. But in the case above, how do I know where to find .VALA? (i.e. the data to write)??
- would EPICS pass in the same buffer of 8 for me to access? Then I would just loop through this buffer and write to the HW Registers??
My time is short in completing this task for my customer.
Your speedy replies with some examples/pointers to examples are Greatly Appreciated.
Warmest Regards,
Stephen BeckwithEmbedded Linux Engineer
Timesys Corp.