Getting Started with tsctl on the TS-4500

From Technologic Systems Manuals

First, download and install the latest version of tsctl as documented in the Getting Started Guide.

In the examples below you can follow along by typing the commands (the portion after the prompt) and expect to see the output below the prompt. Note that while the results should be similar, in some cases you might not see exactly the same results due to variations in execution.

Let's start the tsctl shell:

$ tsctl
tsctl 0.93-ts (Dec  7 2012 16:13:33)
Type "?" to get context-sensitive help.
tsctl>

Let's check that we really have a TS-4500.

tsctl> System ModelId
17664
tsctl>

That doesn't look like 4500! The reason is that the ModelId (and BaseBoardId) commands return 0x4500 (hexadecimal 4500), but the tsctl shell defaults to decimal output. (Note that the command line defaults to hexadecimal!)

We can change to hexadecimal output using the mode command. There is no output from this command.

tsctl> Mode Hex
tsctl>

Now let's try again.

tsctl> System ModelId
0x00004500
tsctl>

In addition to the base the output is represented in, you can also change the general format. The tsctl shell defaults to "NoAssign" mode in which only the input or inputs are printed, each on a separate line. The "Assign" mode (which is the default for the command line) prints a descriptive name=value pair for each value output.

tsctl> Mode Assign
tsctl>

Now let's re-run the previous command. If your version of tsctl is linked against libreadline, you can use the up-arrow twice to pull the System ModelId command back instead of typing it out.

tsctl> System ModelId
System_ModelId_0=0x00004500
tsctl>

Let's run the command again.

tsctl> System ModelId
System_ModelId_1=0x00004500
tsctl>

Notice that the name changed slightly. The first part of the name is the class, the second it the field name (which is also the function name in cases where the value is directly returned at the C API level), and the third is a number. This number is the index of the number of times this class function has been called during the current invocation of tsctl.

Let's switch back to NoAssign mode. Although the field names can be useful if you aren't familiar with what the output fields mean, mostly Assign mode is meant for evaluating by the shell to set variables.

tsctl> Mode NoAssign
tsctl>

Now let's see what base board we have. Your output will differ depending on what you actually have installed.

tsctl> System BaseBoardId
0x00008200
tsctl>

Let's switch back to decimal output.

tsctl> Mode Dec
tsctl>

Now, let's enter the System class onto the command stack so that we don't have to type it repeatedly.

tsctl> System
tsctl System>

Note that our first command, "System" was incomplete, which caused tsctl to push it onto the command stack. This can be used to reduce typing when repetitive sequences start with the same partial command. To pop an element off the stack in the shell, enter an empty line.

One feature of libtsctl is the System Map, which contains name/value pairs. The name is any string (8-bit Array) and the value is an integer. First, let's see how many entries are stored in the table.

tsctl System> MapLength
431
tsctl System>

The entries in the table are stored sorted by name (case-insensitively). Entries are used to store DIO names, enumerated values, attributes, and user-defined name/value pairs. If you want to see the entire table you can get each entry one at a time by index number, starting at 1:

tsctl System> MapGet 1
AIO_ADC
1
tsctl System>

The first line contains the name, while the second contains the value.

To get several entries at once let's first put the function name on the command stack

tsctl System> MapGet
tsctl System MapGet>

One feature of tsctl is the ability to separate commands by a semi-colon. In the shell (e.g. bash) this requires quoting the semi-colon; in the tsctl shell it does not. Let's get the next ten entries:

tsctl System MapGet> 2;3;4;5;6;7;8;9;10;11
AIO_DAC
2
attrib.8200.Wire.Connector.1.0
1
attrib.8200.Wire.Connector.1.1
1
attrib.8200.Wire.Connector.10.0
2
attrib.8200.Wire.Connector.12.0
2
attrib.8200.Wire.Connector.12.1
2
attrib.8200.Wire.Connector.13.0
2
attrib.8200.Wire.Connector.13.1
2
attrib.8200.Wire.Connector.14.0
2
attrib.8200.Wire.Connector.15.0
2
tsctl System MapGet>

What happened here is that each number got appended as the parameter to the System MapGet function.

Hit enter on an empty line to pop the MapGet function off the command stack.

tsctl System MapGet> 
tsctl System>

Let's look at some of the attributes available. We can find the name of a connector by number as follows:

tsctl System> MapLookupPartial attrib.Connector.Name. 2
CN2_
tsctl System>

How many connectors are there?

tsctl System> MapLookup attrib.Connector.Count
2
tsctl System>

Depending on your system, you may have more than this! How many pins does connector 1 have?

tsctl System> MapLookup attrib.Connector.1.Pins
100
tsctl System>

Most boards have a green and red LEDs, but the DIO number differs from board to board. Let's see what DIO numbers they are on this board. If the lookup fails, a negative value will be returned.

tsctl System> MapLookup;GREEN_LED;RED_LED;;
54
55
tsctl System>

Note that we used two semi-colons with nothing between them to pop the MapLookup function back off the stack.

What connector is the GREEN_LED on? We can determine this by searching the connector attribute for a value corresponding to the DIO number of GREEN_LED. In the above case, that value is 128. However we can also use GREEN_LED, as the tsctl text interface will automatically translate it to the correct value:

tsctl System> MapLookupPartial attrib.Connector. GREEN_LED
2.8
tsctl System>

Note that in a few rare cases the above lookup will conflict with another attribute and may not work. This is because MapLookupPartial looks for a name starting with the specified string, having the specified value. If we specified a value of "100" we might match "attrib.Connector.1.Pins", "attrib.Connector.2.Pins", or "attrib.Connector.1.8" as these all have a value of 100.

The interpretation of 2.8 is "Connector 2, Pin 8". This is also known as "CN2_8", by combining the name of the connector with the pin number on that connector.

tsctl System> MapLookup CN2_8
54
tsctl System>

NOTE: For widest cross-platform compatibility it is recommended to perform lookups based on connectors, rather than board specific DIO names.

How many DIO are on the board?

tsctl System> MapLookup attrib.DIO.Count
88
tsctl System>

If you have a peripheral board such as a baseboard or PC-104 board with supported DIO, you will see a higher number than this. Note that this number counts all raw, internally addressable DIO, regardless of whether or not they are brought out to pins. As such the actual number of usable DIO will frequently be lower than the number contained in this attribute.

Let's pop the System class from the command stack.

tsctl System> 
tsctl>

What revision of the FPGA is on the board?

tsctl> System FPGARevision
4
tsctl>

We can read the I2C (TWI) temp sensor on the TS-4200 with tsctl. First let's switch to hexadecimal output for Arrays of bytes.

tsctl> Mode AHex
tsctl>

Next, we need to make sure that the pins that are used for TWI are correctly set up, as they are frequently multi-function pins. The easiest way to make sure the pins are set correctly is to lock the function you are going to use. As part of locking the pin will be initialized to the correct function. For some boards (notably the TS-4800) the TWI must always be locked during use as it uses an underlying operating system file to perform its functionaity.

tsctl> TWI Lock 0 0
1
tsctl>

Now verify that the temperature sensor is present at device address 0x49.

tsctl> TWI Read 0x49 1 7 2
TWISuccess
0x01:0x90
tsctl>

If the bytes read back are not 0x01:0x90 (the first value returned is the result code), then the temperature sensor is not present, or there is another problem with the TWI bus. Assuming we get the correct response back, we can next send the commands to start an aquisition, and read back the raw temperature data from the sensor.

tsctl> TWI Write;0x49 1 1 0x40:0x0;0x49 0 0 0x40:0x0;;Read 0x49 1 0 2;;
TWISuccess
TWISuccess
TWISuccess
0x15:0x40
tsctl>


The value returned can be converted to a temperature as follows:

tempC = (byte[0] * 256 + byte[1]) / 128
tempC = (0x15 * 256 + 0x40) / 128
tempC = 42.5C

Note: The ts8160ctl sample application provides the above TWI temp sensor reading functionality using the -t option.

Be sure to unlock any resource when you are done. Best practice is to hold a lock for the minimum amount of time necessary.

tsctl> TWI Unlock 0 0
1
tsctl>

There are also several timing based functions you can use. For instance, you can delay for a specific amount of time. You should see a delay of approximately 1 second (1,000,000 microseconds) when running the command below:

tsctl> Time;Delay 1000000
tsctl Time>

Note that the Delay function does not return a value. If you want to see the actual number of microseconds delayed, use the Wait function instead:

tsctl Time> Wait 1000000;;
1018053
tsctl>

The only difference between Wait and Delay is that the former returns the number of microseconds actually spend waiting, and the latter returns no value. This is an important nuance in the TCP classes, as in certain modes functions that return no data are not called until subsequent functions that do return data are called. This allows for things such as commanding a relay to cycle power on the board issuing the command (so long as it isn't the board interpreting the command), since otherwise the command to restore power would not be sent before power was cut.

Short delay times are generally only useful when using direct access from C. Otherwise, the overhead of parsing the command, sending it across TCP, and interpreting it on the server will be significant in comparison to the amount of time to delay.

We can send and receive CAN messages with tsctl. To do this, it is first necessary to connect the TS-4700 CAN bus to another device which is able to send and receive messages.

First, switch to the CAN class:

tsctl> CAN
tsctl CAN>

Next, set the baud rate:

tsctl CAN> BaudSet 1000000
1000000
tsctl CAN>

Now set up the remote device to receive, and then send a message from the TS-4500. The message will used extended addressing, will have an address of 0x1234, and have eight bytes of incrementing data starting with a value of 1:

tsctl CAN> Tx FLAG_EXT_ID 0x1234 1:2:3:4:5:6:7:8
CANSuccess
tsctl CAN>

If all goes well Tx should return a positive value to indicate success. Now wait for a CAN message to be received. Our initial call to Tx automatically enabled CAN to transmit, so if we received a message between that time and when we call Rx it will return immediately. TO DO: CAN Rx

Sometimes it may be desirable to try to receive multiple CAN messages with a single command. The RxMulti command specifies a maximum and minimum number of messages to receive before returning. A minimum value of zero indicates to only poll for any messages ready and does not block if no message is waiting. TO DO: CAN RxMulti