SPICTL MODES The spictl program is intended to be run in one of three modes: 1. Direct Mode In this mode, spictl must be run on a board which has an SBUS (e.g. the TS-7552 which has an SPI bus to SPI controller in the FPGA). The command line options specify what SPI transactions to perform. After these are complete, the program exits. Direct mode is assumed when neither the --client nor --port options are specified. 2. Server Mode Like direct mode, server mode must be run on a board which has an SBUS. In server mode, spictl will daemonize and listen for TCP/IP connections on the port specifed. When a connection is made, the server will process commands in the SPICTL PACKET FORMAT. While spictl will accept multiple connections simultaneously, it is up to the user to ensure that concurrent accesses do not interfere with each other. The command-line option to enable this mode is: --server Where is the TCP port to listen on. 3. Client Mode In client mode, spictl can be run on any machine, such as an X86 Linux PC. The program will connect to the specified spictl server and send it the commands specified. It is possible to connect to multiple servers by specifying this port option multiple times - subsequent commands will be sent to the last server specified. The command-line option to enable this mode is: --port <:port> The host is a TCP/IP host name, and the option is the integer TCP port number to connect on. If the host is omitted, localhost is assumed. If the port number is omitted, 7552 is assumed. SPICTL COMMANDS --clock= Specify the frequency, in Hz, to operate the SPI clock at. If the exact frequency requested cannot be had by the controller, it will use the largest frequency not greater than the specified frequency, unless no such frequency exists, in which case it will use the slowest frequency it can do. --edge= Specify the clock edge on which to perform SPI transaction. A positive integer indicates the positive edge, while a negative integer indicates the negative edge. Not all controllers may support this option for all frequencies. For example, the SBUS controller only support positive edges for 75Mhz (the maximum frequency) and will ignore any request for a negative edge with that frequency. --lun= specifies which chip select number to assert during subsequent commands, which selects which device will be communicated with. --writestream= perform an SPI write transaction with the specified data. The data given must consist of raw hexadecimal digits separated by colons. For instance, to write the values 0x01, 0x02, 0x0E, the option would be: --writestream=01:02:0E --readstream= perform an SPI read transaction of the given length. The data read is output in binary format to stdout. --readwrite= perform an SPI read/write transaction. The data bytes are in the same format as for --writestream, and the data read is output in binary format to stdout. --holdcs normally the chip select is de-asserted after other commands; this option will cause it to remain asserted. SPICTL C API The C functions below provide a means for constructing packets in the SPICTL PACKET FORMAT, and either interpreting them locally, or sending them to a server for evaluation. The flow of operations is as follows. First, the appropriate initialization functions are called. The functions are called to add commands to the packet as desired. Finally, spi_execute() is called to cause the SPI commands requested to be executed. Finally, a shutdown function is provided. After spi_execute() is called the initialization functions can be called again and the whole process repeated as needed. void spi_start(char *ip,int port); This function sets the target of spi_execute to be a remote server at the specified IP address or name, and TCP port. void spi_init(); This function initializes the packet. It must be called before each new packet is built. int spi_assert_cs_config(int cs,int clock,int edge); Queues a command to configure the SPI to talk to the specified chip (cs), using the specified clock frequency (clock) and edge polarity (edge). If either clock or edge are 0, the previous value will remain in effect for the respective parameter. int spi_assert_cs(int cs); Queues a command to configure the SPI to talk to the specified chip (cs), using the current clock frequency and edge. void spi_write(unsigned char value); Queues a command to write the specified bus to SPI. void spi_readwrite(unsigned char value); Queues a command to simultaneously write the specified byte to SPI while reading a byte. void spi_readstream(int bytes) Queues a command to read the specified number of bytes from SPI. void spi_writestream(unsigned bytes,unsigned char *buf1); Queues a command to write the specified number of bytes from the buffer passed to SPI. This function copies the bytes out of the buffer, so it is safe to free it after this function returns. void spi_deassert_cs(int cs); Queues a command to deassert the chip select specified. On most controllers the parameter is a dummy value, as only one chip select is active at a time and so a de-assertion will act on whatever chip-select line is asserted. unsigned char *spi_execute(int *n); Execute all the queued commands. If spi_start() has not been called, then the commands are executed in direct mode, otherwise they are sent to the server specified by the last call to spi_start(). If the passed pointer is not null, the number of bytes read from SPI will be put into the integer pointed to. The return value is a newly allocated buffer of the same size containing all the bytes read as commanded from SPI. The caller should free() this buffer when done with it. void spi_stop(); This function will close any existing connection to a server as specified by spi_start(). Any subsequent spi_execute() will then operate in direct mode. SPICTL PACKET FORMAT The data stream containing SPI commands between an spictl client and an spictl server consists of opcodes and operands. Each opcode is one byte long and may encode part or all of the operand. Some opcodes specify that additional bytes of data follow to contain the remainder of the operands. There are four opcodes encoded in the two msb of the opcode byte: OPCODE 0 = CHIP SELECT The chip number is encoded in the two LSB. 00 = CS#0 01 = CS#1 10 = CS#2 11 = CS#3 If Bit 5 is set, OPCODE = ASSERT CHIP SELECT Then If Bit 3 is set, Bit 2 is the new SPI edge to use (1 = positive edge, 0 = negative edge) Also, two additional bytes follow as operands. These two bytes are a big-endian encoded clock value. This value multiplied by 2048 is the SPI clock frequency to use Else If Bit 5 is clear, OPCODE = DE-ASSERT CHIP SELECT And there are no additional operand bytes. OPCODE 1 = READ The number of bytes to read must be a power of two, encoded in the 6 lsb. These six bits represent the number to raise 2 to the power of to get the length. So, 00_0000 = 1 byte 00_0001 = 2 bytes ... 00_1100 = 4096 bytes etc. And there are no additional operand bytes. OPCODE 2 = WRITE The number of bytes to write is encoded in the same manner as for a READ opcode. After the opcode byte, the number of bytes to write follows as the operands. OPCODE 3 = READWRITE This opcode encodes identically as the WRITE opcode. However it specifies that bytes are to be READ as well as written. The