Jump to content

properties/methods for a serial port in FPGA: how to assign the port?


Recommended Posts

Hello,
I am just trying using Scripting to put Property Node and Method Nodes for accessing a serial port in FPGA VI.

I can get these Nodes, and I suppose the property list and method are correct - but I don't know how am I to specify the serial port for these Nodes - when I select the port manually for a Node, it becomes correct. I can get the Property Node with FPGA I/O terminals (till npow I did not try this with a Method Node), but I don't know what should I put into a constant that I will connect to FPGA I/O input terminal (when I added the constant manually there, I was unable to select a serial port from I/O items menu). I can also use the Scripting to find serial ports in the target where I am putting the edited VI (it has Type String "RIO Subresource", Name "Port1", and Item ID (non-0, while its Source ID contains 0-s only).

I am creating these Nodes using EIOPlaceDownEIOPropertyNode.vi and EIOPlaceDownEIOMethodNode.vi; the State input contains item="Mod1\Port1", the name is shown in the Node header line, and it is the same after assigning the serial port manually, but the manual assignment is needed to get the port name recognized.

Have anyone found what function and how can be used to specify a serial port for these Nodes?

Thanks in advance for any hint, Jerzy Tarasiuk

Link to comment

Hello. Likely the problem could be solved if there were a way to create an "I/O Constant" (like this from FPGA I/O Palette) specifying a serial port - I can create an FPGA I/O terminal for a Method or Property Node., so connecting such an I/O Constant would configure these nodes. Unfortunately, seems I/O Constant cannot specify a serial port - at least I cannot select it in LabVIEW editor. Maybe some future LabVIEW version...

The I/O Constant allows selection of project items that can be found using "Get All Descendents" method with Type="Elemental I/O" on an FPGA Target reference, or "eio_Utilities_GetAliasNames.vi" on an FPGA Application reference. Serial ports can be found using "eio_Utilities_GetNonAliasNames.vi" on an FPGA Application reference.

Edited by Jerzy Tarasiuk
added more info
Link to comment
On 2/24/2024 at 8:05 PM, Jerzy Tarasiuk said:

Hello. Likely the problem could be solved if there were a way to create an "I/O Constant" (like this from FPGA I/O Palette) specifying a serial port - I can create an FPGA I/O terminal for a Method or Property Node., so connecting such an I/O Constant would configure these nodes. Unfortunately, seems I/O Constant cannot specify a serial port - at least I cannot select it in LabVIEW editor. Maybe some future LabVIEW version...

The I/O Constant allows selection of project items that can be found using "Get All Descendents" method with Type="Elemental I/O" on an FPGA Target reference, or "eio_Utilities_GetAliasNames.vi" on an FPGA Application reference. Serial ports can be found using "eio_Utilities_GetNonAliasNames.vi" on an FPGA Application reference.

I think you are confusing an IO signal with a logical interface. The serial port is typically a logical device that contains a TxD and RxD pin and possibly others. On the FPGA you deal exclusively with IO signals. But there is no way to access the serial port as an IO signal. Either you would have to access the individual IO pins that make up the serial port individually and implement the serial port bit protocol yourself in FPGA or you need to access the serial port through the RT OS on the controller as serial port and let the OS driver handle the actual IO control (usually it doesn't really control the IO pins directly but uses a device driver to communicate with the serial port registers).

Link to comment

Are you sure? I initially supposed NI-9871 serial ports are accessed via the RT OS, but I was pointed that I was wrong - they are connected to FPGA and the RT OS accessed them via FPGA. Seems to be sure I need a test: write a LabVIEW FPGA program that will send data via a serial port, start the FPGA program and reboot the RT OS (it is configured to allow the FPGA program to continue), monitoring the serial port data on a PC host: if the serial port is accessed via the RT OS, the data will be disturbed. I hope these serial ports are connected directly to FPGA - it is important for safety of the system.

In LabVIEW FPGA NI-9871 serial ports are accessed using Property and Method nodes (there are several properties and 3 methods - Read Byte, Write Byte, Clear Rx FIFO); I/O Node cannot be used for them.

Seems that two serial ports on cRIO itself (not on a C-Module) can be accessed from RT OS only, as well as serial ports connected via USB ports.

Edited by Jerzy Tarasiuk
added serial port method names
Link to comment
15 hours ago, Jerzy Tarasiuk said:

Are you sure? I initially supposed NI-9871 serial ports are accessed via the RT OS, but I was pointed that I was wrong - they are connected to FPGA and the RT OS accessed them via FPGA. Seems to be sure I need a test: write a LabVIEW FPGA program that will send data via a serial port, start the FPGA program and reboot the RT OS (it is configured to allow the FPGA program to continue), monitoring the serial port data on a PC host: if the serial port is accessed via the RT OS, the data will be disturbed. I hope these serial ports are connected directly to FPGA - it is important for safety of the system.

In LabVIEW FPGA NI-9871 serial ports are accessed using Property and Method nodes (there are several properties and 3 methods - Read Byte, Write Byte, Clear Rx FIFO); I/O Node cannot be used for them.

Seems that two serial ports on cRIO itself (not on a C-Module) can be accessed from RT OS only, as well as serial ports connected via USB ports.

Well I'm for sure sure about the built in serial ports on cRIOs and sbRIOs. The987x serial C modules are a different story. And serial ports through USB ports definitely never ever could be just accessed from FPGA mode. You need at least a USB-CDC driver and while that might be possible in FPGA, it is not something that the Xilinx chips that are used on the RIO hardwares would even support, even if you might find some IP design somewhere implementing that. The communication channels such as Ethernet, Uart, USB and similar are NOT directly routable to the FPGA fabric but only accessible through their register interface, which requires a software driver to control them (and an OS on which that driver can be loaded).

Link to comment

Hello. I need access serial ports of NI-9871. From https://www.ni.com/pl-pl/shop/model/ni-9871.html they are directly accessible from FPGA:

Quote

The NI‑9871 adds RS485/RS422 serial ports to CompactRIO systems. The serial ports are accessed directly from the FPGA to offer you flexibility in communicating with serial devices. The module has individual buffers on every port that save FPGA space and simplify programming.

Link to comment
8 minutes ago, Jerzy Tarasiuk said:

Hello. I need access serial ports of NI-9871. From https://www.ni.com/pl-pl/shop/model/ni-9871.html they are directly accessible from FPGA:

So what is your problem or question? I never said that you can't access the 987x modules from FPGA. But you never specified in your OP that you meant those. As far as scripting these things, it's undocumented territory. And complicated enough that reverse engineering would be a pretty tedious job.

Supposedly the C module development Toolkit has some documentation about how so called Elemental IO can be created, but I highly doubt that it documents how that is done through scripting, but it simply provides some tools that do all these things behind the surface. That Toolkit was however not free (~1600 for non-commercial version, 6k for commercial version). The non-commercial version does let you develop your own C modules, but you are not allowed to sell them to others. However it is not anymore findable in the NI store as an order-able product.

Edited by Rolf Kalbermatter
Link to comment

Hello, Rolf. Thank you for the time you are spending on it.

My problem is: I can create - using Scripting - a serial port Method Node (with EIOPlaceDownEIOMethodNode.vi, for any of 3 methods the port has), or a Property Node (with EIOPlaceDownEIOPropertyNode.vi, having read/write elements for a set of properties which I wish); and then I can assign a serial port to the node using LabVIEW editor (i.e. click the node with a mouse, select from menu...); but I cannot assign the port with Scripting.
When creating these nodes using Scripting, I was putting the port name as 'item' in the State cluster (EIOMethodNode.xnode:EIOMethodNode.ctl or EIOPropertyNode.xnode:EIOPropertyNode.ctl) - the name was shown in the created node title, as it is shown after manual assignment, but the node did not recognize the name as a serial port and was shown as misconfigured.

I don't know where it is going wrong: maybe the port name I specify is incorrect (it requires some prefix that isn't shown in the node title, but is necessary for the name to be recognized), maybe except the EIOPlaceDownEIO* some other function is necessary to make the setting active. Is there a way to get State from such a node that was configured manually and see what is its 'item' value?

With kind regards, Jerzy

Link to comment

This is undocumented territory for sure and as such there is a high chance that:

- parts of what you want to do might be obscure and difficult to impossible to find out without the according non-public documentation

- it might be present but not implemented, either returning an error or simply doing nothing

- it might be simply not possible as the LabVIEW developers haven't found a need for this particular operation yet, and why would they spend time on implementing something that is neither a public function nor required for internal use?

Edited by Rolf Kalbermatter
Link to comment
On 2/28/2024 at 12:33 AM, Jerzy Tarasiuk said:

Are you sure? I initially supposed NI-9871 serial ports are accessed via the RT OS, but I was pointed that I was wrong - they are connected to FPGA and the RT OS accessed them via FPGA. Seems to be sure I need a test: write a LabVIEW FPGA program that will send data via a serial port, start the FPGA program and reboot the RT OS (it is configured to allow the FPGA program to continue), monitoring the serial port data on a PC host: if the serial port is accessed via the RT OS, the data will be disturbed. I hope these serial ports are connected directly to FPGA - it is important for safety of the system.

In LabVIEW FPGA NI-9871 serial ports are accessed using Property and Method nodes (there are several properties and 3 methods - Read Byte, Write Byte, Clear Rx FIFO); I/O Node cannot be used for them.

Seems that two serial ports on cRIO itself (not on a C-Module) can be accessed from RT OS only, as well as serial ports connected via USB ports.

The 987x modules *can* be accessed just like any other in-built serial port (using the VISA serial functions) as long as you have installed the 987x support package on the cRIO (option that should be available in the list when you choose to install the system image etc on it). No need to even think about their connection to the FPGA then. Now, before that support package was available you did need to add FPGA code, but even then that code is available as an example so you do not need to figure much out anymore...We used the FPGA-method 15 years back or so, now we just install the support package and use it with VISA.

Link to comment
8 hours ago, Jerzy Tarasiuk said:

Hello. My aim is to access these ports directly from FPGA program, without VISA and drivers that are in RT part. It is possible when the program is edited manually in LabVIEW development environment.

And to do that you can use the examples you find if you search for 987 in LabVIEW examples. But you are for some reason also trying to script the creation of such code, is that an additional requirement or could you just edit the examples and compile it into your bitfile?

Link to comment

Elemental IO is not a public documented feature. The according project provider knows how to do it but it was never intended to have that interface opened as a user accessible feature. And the main reason is not that NI is evil and wants to deprive you of the fun to thinker with this but because they want to prevent customers to create easily crashing projects that require an immense support demand that NI is not able to fulfill.

Link to comment
2 hours ago, Jerzy Tarasiuk said:

Hello. Seems none of these examples show how to use VI Scripting to create an FPGA VI that accesses NI-987x serial port...

Yes, I never said they did, but I did wonder why you need to script their creation.

Link to comment

Hello. I want to create a VI for each serial port that will configure the port according to configuration data sent to the VI - this requires many connections inside the VI and results in many possibilities of mistakes in these connections if they are to be done manually. I would like to avoid these mistakes. Currently, I can use Scripting to create Method Nodes and Property Nodes needed, then request setting the serial port in them manually, then  use Scripting to create connections, and finally report all connections to a text file for verification. But I neither know how to set the serial port in these nodes using Scripting, nor I know how to get these settings for verification.

BTW: is it possible that two Property Nodes for a serial port look identically (have the same port in their header lines, the same elements, data types for these elements are shown by the same colors...), but have different functionality (e.g. something hidden was created in one of these nodes while editing it)?

Link to comment
1 hour ago, Jerzy Tarasiuk said:

Hello. I want to create a VI for each serial port that will configure the port according to configuration data sent to the VI - this requires many connections inside the VI and results in many possibilities of mistakes in these connections if they are to be done manually. I would like to avoid these mistakes. Currently, I can use Scripting to create Method Nodes and Property Nodes needed, then request setting the serial port in them manually, then  use Scripting to create connections, and finally report all connections to a text file for verification. But I neither know how to set the serial port in these nodes using Scripting, nor I know how to get these settings for verification.

BTW: is it possible that two Property Nodes for a serial port look identically (have the same port in their header lines, the same elements, data types for these elements are shown by the same colors...), but have different functionality (e.g. something hidden was created in one of these nodes while editing it)?

Any code can contain errors. If you script the code you are just adding another layer where you can have errors (the script itself, in addition to the code it generates). When the script has created the code you still have to test the generated code to see if it works correctly. If you write it manually and test it (easier than testing scripts as you can test its intermediate steps directly as you progress) you can use that code for all ports, not just for one.

Having to repeatedly create complex but similar code from scratch could justify doing it with scripting to reduce the risk of human errors, but here you can still handle it by having the code cover all scenarios and/or with code reuse . And much of the code has been written and tested for you already (examples) so all you need to do is add whatever extra functionality you need and test those changes.

Have you tried solving this the easy way by relying on the RT OS and VISA support already, but observed that it does not meet the your reliability requirements? Or have you just assumed that it will not and are optimizing it prematurely, making the path to a working solution unnecessarily hard and complex? 

Link to comment
  • 1 month later...
Posted (edited)

I need a program in FPGA to control a hardware, without mediation of RT part - and I plan to use LabVIEW for the FPGA only. Because of this, there is no place for using VISA. I want to have the same code for each serial port - they are to be configured differently, but the configuration should be passed as data to the code that is to set it to these ports. FPGA has access to these ports (the VISA would access them via FPGA), but I don't know how to place a port name in LabVIEW - the only way I know is to select manually the port resource for each Property and Method used to access the port. And I don't know how can I programmatically verify that the correct port resource is selected in each place, as I have no way to read it.

Edited by Jerzy Tarasiuk
corrected misspelling
Link to comment

Hi, seems I found a solution. The program should do the following:

  • use Invoke Node for This Application constant to open a project with an FPGA target;
  • use Property Node on the project ref to get targets;
  • look for a matching FPGA target (in my example I also compare target name, so it can
    handle a project with many FPGA targets if it happens), closing the other target refs;
  • use Property Node on the selected target ref to get its Application ref;
  • create (or open) a VI for the Application, open its BD window, gets its BD ref;
    (the above action is in the upper line of my VI)
  • use eio_Utilities_GetNonAliasNames.vi on the Application to get names to be used:
    - "persistent names" output gives names (array of strings) that can be used,
    - "resource names" and "display names" (arrays of strings) can be used to find
       an element in the "persistent names" - choose e.g. Mod1\Port3 in display names,
       and use its index on the "persistent names" to get required persistent name;
  • the persistent name is to be used as "item" for EIOPlaceDownEIOMethodNode.vi
    and for EIOPlaceDownEIOPropertyNode.vi - the "item" is in "State" cluster;
  • few other elements of the "State" cluster, common for these both "Place"-s, are:
    "alias selected", "DoSpecify", "ref in wired", "ignore ref inputs"; the "alias selected"
    must be False, the "ref in wired" must be True; do the other matter? I don't know;
  • making a Method needs also a "method name" to be set, valid methods for
    an NI9871 serial port are "Clear Rx FIFO", "Read Byte", "Write Byte";
  • for making a property I specified "id counter" = 1 (is it needed? I don't know),
    and of course the "properties" - an array of clusters, in each of them I set:
    "name" (string), "direction" (enum, I used read or write), "terminal id" (int);
  • each "Place" needs also Diagram (I used the BD ref), context (= Application ref),
    and "Position" (a cluster containing left-top corner coordinates);
  • each "Place" returns a "Terms[]" - an array of terminals - I show some info on them.

Attached files: a picture w/ BD and FP, a PDF containing the BD, the VI (LabVIEW 2018).
   

ni9871cmp.png

ni9871cmp.pdf ni9871cmp.vi

Link to comment

Yet another program: list I/O names and methods/properties available for each of them.

Inputs for the VI: LabVIEW project path, FPGA target name, log path (for writing the info).
A sample of I/O name lines from the log:
 

Quote

+++crio_M3
+++crio_M4
+++crio_Module5
+++crio_Mod6
+++crio_Mod1
+++crio_Mod1/Port1
+++crio_Mod1/Port2
+++crio_Mod1/Port3
+++crio_Mod1/Port4
+++crio_Mod7
+++/Chassis Temperature
+++/Sleep
+++/System Reset
+++/USER FPGA LED
+++/USER Push Button
+++/Scan Clock
+++/crio_M3/DO0
+++/crio_M3/DO1
+++/crio_M3/DO2
+++/crio_M3/DO3

These '+'-es at the beginning of each line tell that looking for methods/properties of the I/O item found the item and no error resulted from the operation (each '+' has a different meaning, but I was getting +++ only). First 10 names have no leading '/' - they were found as non-alias names, all remaining - as alias names.
 

Quote

+++crio_Module5
 m: Check Output Status
 p: Module ID (R)
 p: Serial Number (R)
 p: Vendor ID (R)
+++crio_Mod6
 m: IO Sample
 m: Set Terminal Mode
 m: Set Triggers
 m: Set Voltage Range
 p: Linearization Coefficient 0 (R)
 p: Linearization Coefficient 1 (R)
 p: Linearization Coefficient 2 (R)
 p: Linearization Coefficient 3 (R)
 p: LSB Weight (+/- 10V range) (R)
 p: LSB Weight (+/- 1V range) (R)
 p: LSB Weight (+/- 200mV range) (R)
 p: LSB Weight (+/- 5V range) (R)
 p: Module ID (R)
 p: Offset (+/- 10V range) (R)
 p: Offset (+/- 1V range) (R)
 p: Offset (+/- 200mV range) (R)
 p: Offset (+/- 5V range) (R)
 p: Serial Number (R)
 p: Vendor ID (R)
+++crio_Mod1
 p: Module ID (R)
 p: Serial Number (R)
 p: Vendor ID (R)
+++crio_Mod1/Port1
 m: Clear Rx FIFO
 m: Read Byte
 m: Write Byte
 p: Baud Rate (W)
 p: Baud Rate Divider (Bw)
 p: Baud Rate Prescaler (Bw)
 p: Break state (W)
 p: Bytes at Port (R)
 p: CTS state (R)
 p: Data Bits (Bw)
 p: DTR state (W)
 p: Flow Control (Bw)
 p: Parity (Bw)
 p: RTS state (W)
 p: Stop Bits (Bw)
 p: Transceiver Mode (Bw)
 p: XOFF character (Bw)
 p: XON character (Bw)

Here crio_Module5 is NI9476, it has a "Check Output Status" method and 3 properties (these properties common to all C-Modules, and they are read-only, it is shown by '(R)'); crio_Mod6 is NI9205, it has 4 methods and 15 properties; crio_Mod1 is NI9871, it has 3 properties and no methods; its Port1 has 3 methods and several properties, some are read-only (R), some write-only (W), some bidirectional default-write (Bw), a (Br) would mean bidirectional default-read.

Quote

+++crio_Mod7
 p: Conversion Time (Bw)
 p: Module ID (R)
 p: Serial Number (R)
 p: Vendor ID (R)
+++/Chassis Temperature
 m: Read
+++/Sleep
 m: Read
 m: Write
+++/System Reset
 m: Read
 m: Write
+++/USER FPGA LED
 m: Read
 m: Write
+++/USER Push Button
 m: Read
+++/Scan Clock
 m: Read
 m: Wait on Rising Edge
 p: Enabled (R)
 p: High Time (R)

Here crio_Mod7 is NI9208, it has 4 properties (an additional is "Conversion Time"). Then alias I/O items follow: "Chassis Temperature" can be read, "Sleep" can be read and written, as well as "System Reset" and "USER FPGA LED", "USER Push Button" can be read, and "Scan Clock" has 2 methods and 2 properties.

Quote

+++/crio_M3/DO0
 m: Read
 m: Write

+++/crio_M4/DI0
 m: Read

+++/crio_Module5/DO0
 m: Read
 m: Write

+++/crio_Mod6/AI0
 m: Read

+++/crio_Mod6/AI31
 m: Read
+++/crio_Mod6/Trig
 m: Read
+++/crio_Mod6/DI0
 m: Read
+++/crio_Mod6/DO0
 m: Write

+++/v1/SignalList/a.b0
 m: Write
+++/v1/SignalList/aw
 m: Read
 

Here crio_M3 is NI9477, its DO0 signal can be read and written, as well as DO0 signal of crio_Module5 (NI9476); crio_M4 is NI9425, its DI signal can be read, as well as crio_Mod6 (NI9205) AI0 and AI31 signals.

The NI9205 has also Trig signal (read-only), DI0 signal (read-only), DO0 signal (write-only).

And finally few CLIP signals: "/v1/SignalList/a.b0" is "a.b0" of CLIP "v1" (write-only), "/v1/SignalList/aw" is "aw" signal of the CLIP (read-only).

Attached: a VI used to produce the list and its BD picture.

io_names_list.png

io_names_list2l.vi

Link to comment

Some additions:

  1. the name ni9871cmp is an abbreviation from NI9871 Create Methods and Properties.
  2. when looking for a way to create them, I attempter to use "pylabview"
    https://github.com/mefistotelis/pylabview to examine VI-s created manually and
    with scripting and to find their differences; first of all, the "pylabview" is said to be
    for LabVIEW 2014 - in fact, it couldn't handle VI-s from the LabVIEW 2018 I am using,
    and it couldn't handle VI-s saved for older LabVIEW versions until I specified as old
    as 2011; even then, when I used the pylabview to extract contents of a VI containing
    a valid serial port Method or Property, none of text files produced contained the port
    name - I found the port name in a binary file only, and it contained UUID-s in "{}", with
    ">>" as a separator, like "Mod1.{uuid1}>>Port2.{uuid2}" - and I found this all must be
    exactly the same for the port to be recognized - when I put exactly this string in the
    alue used for port specification, the scripting produced valid Methods and Properties;
    then I started to look for a function that can get such a string from my project...
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.