:: Style
:: Setting up Cortex for Recording Many Spike Channels  
The following documentation and the "byte_out" utility were contributed by Dr. Andrew R. Mitz, Laboratory of Systems Neuroscience, NIMH) Starting with Cortex version 5.9.4, Cortex is able to record spike data from a large number of spike channels. To do this you will need:

  1. Adding Circuitry for many spike latches. See the Thalamus documentation page for an example printed circuit board.
  2. Adding additional I/O boards (PIO12, PIO24, or PIO96).
  3. Modifying the CORTEX.CFG file.
  4. Manual configuration of I/O boards. See also the Table of PIO board control bytes.
The hardware arrangement that will be used in the examples is the one we use in our lab. A Compuboard (Computer Boards CIO-DAS16) is configured in its usual way. The Compuboard has two sections, the A/D section, which also includes four bits of input and four bits of output, and the PIO section. On the A/D section, most people use IN0 and IN1 (same as user0 and user1) for spike inputs. Sometimes the other two input bits of the A/D section, IN2 and IN3, are used for BAR_UP/BAR_DOWN and for BAR_RIGHT/BAR_LEFT. The PIO section of the DAS16 is always arranged with Port A=input, Port B=output, Port C low-bits=input, Port C high-bits=output.

Our traditional arrangement differs from the usual arrangement in that we assign a total of 8 of the inputs to spike latches. IN0 through IN3 from the A/D section are used for four spike inputs, and all four Port C low-bits from the PIO section are used for the other four. However, these eight spike inputs are no longer enough. This document explains how to add PIO24 boards to increase the number of spike inputs. Each PIO24 board adds 24 inputs.

:: Circuitry for many spike latches  
The minimum circuit for a spike latch is a flip-flop. The output of a spike discriminator is usually a narrow digital pulse. The flip-flop is latched by a pulse from the output of a discriminator, and held in the latched state until Cortex has an opportunity to check for new spikes (once each millisecond). After Cortex reads the status of the spike latch flip-flop, it sends a reset pulse to prepare the flip-flop for the next discriminator pulse. All spike latch flip-flops receive the same reset pulse. The Thalamus documentation page has an example design for a printed circuit card that has flip-flop latches. The design also includes a neat little circuit to flash an LED each time a spike arrives.

:: Adding PIO12, PIO24, or PIO96 boards  
Normal Cortex operation uses a Compuboard CIO-DAS16 (or similar) board. (The Compuboard is equivalent to the old Metrabyte DAS16 A/D board and a Metrabyte PIO12 on the same board.) In addition to the Compuboard, Cortex has provisions to read and write digital information from various PIO boards. PIO boards come in various flavors. For the purpose of Cortex, a PIO12 is the same as a PIO24. The PIO96 is the same as having four PIO24 boards.

It is possible to run Cortex without the CIO-DAS16 board, using only PIO boards. Operating Cortex with just PIO boards is not difficult, but is not covered here.

A PIO24 board has three input-output ports, Port A, Port B, and Port C, each of which can handle 8 bits of data. When using a Compuboard, Cortex initializes the PIO part of the Compubard with: Port A as an input port, Port B as an output port, and Port C as half input / half output. Any input port can be used for spike latches. The default initializations can be overridden; it is possible to have all ports on the Compuboard arranged as input ports, so all 24 bits can be used to detect spikes. It is also possible to add additional PIO boards and use these boards for receiving spike inputs. In either case, CORTEX.CFG has to be changed.

:: CORTEX.CFG changes  
CORTEX.CFG must be changed in two places to handle many spike channels, the DEVICE definitions and the MULTI_SPIKE definitions. Cortex supports five devices: COMPUBOARD, DASH16 (or equivalently, METRABYTE), PIO24, PIO96, and PCIDAS1602. Each of these can occur only once in the CORTEX.CFG file. So, if you have four PIO24 boards, you cannot use the PIO24 command four times. There are some tricks, however. The PIO96 is a board that is the equivalent of four PIO24 boards. So, if you have one, two, three, or four PIO24 boards in sequential addresses, you can just treat them as one PIO96. If you have two PIO24 boards at very different addresses, you can use the PIO24 entry for one board and the PIO96 entry for the other board. There is no problem using the PIO96 entry to talk to a PIO24 board as long as input and output commands are restricted to the first group of port addresses.

To add 24 new spike channels to your existing arrangement, insert a new PIO24 board in the computer and add a DEVICE entry that identifies the board. In this example, we add a PIO24 at address 320 (hex).

DEVICE COMPUBOARD 0x300 (already in the file)
DEVICE PIO24 0x320 NO_INIT (new entry)

Note, if you are using are already using the DEVICE PIO24 entry in CORTEX.CFG, you cannot repeat that entry in the file. Many existing CORTEX.CFG files use the METRABYTE entry followed by the PIO24 entry.

DEVICE METRABYTE 0x300 (already in the file)
DEVICE PIO24 0x310 (already in the file)
DEVICE PIO24 0x320 (NOT ALLOWED!)

Using the METRABYTE entry is a bit wasteful. It is better to use the COMPUBOARD entry, which serves both functions. Switching from the METRABYTE / PIO24 combination to the COMPUBOARD entry, however, requires some care. If you are using the DEVoutp() or DEVinp() commands in your state file, changing the DEVICE entries might require a few state file changes. If you are using the METRABYE / PIO24 combination and do not want to make a mess with changing your state files, you can use the PIO96 DEVICE entry for your new PIO24 board:

DEVICE METRABYTE 0x300 (already in the file)
DEVICE PIO24 0x310 (already in the file)
DEVICE PIO96 0x320 NO_INIT (new entry)

Just substitute "PIO96" for "PIO24" when implementing the examples shown here.

The NO_INIT option in the DEVICE entry is a new option for Cortex. It tells Cortex not to initialize the ports on the device. In fact, the new version of Cortex expects to see the INIT option on the old entries, but will work ok without it, since INIT is the default:

DEVICE COMPUBOARD 0x300 INIT (expected INIT, but not required)
DEVICE PIO24 0x320 NO_INIT (NO_INIT is required)

(As an aside, the NO_INIT option can not be used with the PCIDAS1602 board with the current version of Cortex. It must always be initialized by Cortex, since Cortex uses its Port C internally.)

Now that the PIO24 board is listed in the cortex.cfg file, it can be assigned to spike channels. The MULTI_SPIKE entry provides this feature. The MULT_SPIKE entry is a bit cryptic, but not hard to understand. Here is the default entry for the typical user0 and user1 spike inputs:

MULTI_SPIKE COMPUBOARD 0x03 2 1 // default

This entry says that the third I/O port (0x03) on the COMPUBOARD will provide 2 spike channels. According to the Compuboard documentation, address 0x03 is where the four input bits (IN0 through IN4) reside. The last number in the MULTI_SPIKE line (1) is simply the event code Cortex will insert into the data stream when a spike occurs. Since there are two spike channels, code "1" and code "2" will be assigned to data from IN0 and IN1, respectively. The event codes are always in sequence starting from the number given on the MULTI_SPIKE line.

The systems in our lab use four bits from the A/D part of the COMPUBOARD and four bits from Port C of the PIO part of the COMPUBOARD. Even though all the bits come from the same I/O device, two MULTI_SPIKE entries are required:

MULTI_SPIKE COMPUBOARD 0x03 4 1 // 4 spikes from IN0 to IN3
MULTI_SPIKE COMPUBOARD 0x12 4 5 // 4 spikes from PIO Port C

Note the last entry in each line. The first four spikes get event codes 1, 2, 3, and 4. So, the second MULTI_SPIKE line has a 5 on the end. This assigns codes 5, 6, 7, and 8 to the second group of spike channels. The address of Port C on a Compuboard is 0x12. (The user should check the documentation that is shipped with the board for the port addresses. The CIO-DAS1602/12 has Ports A, B, and C assigned 0x400 through 0x402, instead of 0x10 through 0x12.)

To add 24 new spike inputs to our system, we chose 24 event codes above 110 and assigned the hardware this way:

MULTI_SPIKE COMPUBOARD 0x03 4 1 // as above
MULTI_SPIKE COMPUBOARD 0x12 4 5 // as above
MULTI_SPIKE PIO24 0x00 8 111 // 8 spikes from Port A
MULTI_SPIKE PIO24 0x01 8 119 // 8 spikes from Port B
MULTI_SPIKE PIO24 0x02 8 127 // 8 spikes from Port C

Each 8 bit port on the PIO24 has its own I/O address, so each 8 bits requires a new entry. The event codes for the 24 new spike channels will be codes 111 through 134.

:: Manual configuration of I/O boards  
The new PIO board should be initialized such that the ports used for spike latches are set up as input ports. In our example, this initialization is not essential because all the ports on a PIO board are set up as input ports when the computer boots. Using the NO_INIT entry in the CORTEX.CFG file prevents Cortex from changing the PIO24 settings. However, what if we want to use Port B of the Compuboard for spikes? That port is initialized by Cortex as an output. We can override Cortex with the NO_INIT option in CORTEX.CFG, but then we have to configure the COMPUBOARD ourselves. Likewise, if we add a PIO24 board and wish to use some of the board for spike inputs and some of the board for digital outputs, we need to manually configure the I/O board.

There are two places that the manual configuration can take place, in the state file or in DOS.

Manual configuration in the state file

There is a Cortex programming trick that tells Cortex to execute a group of program steps in the state file only once during a session. That trick can be used to add the commands for manual configuration into the state file, and have the state file configure the PIO board only once. To demonstrate this trick, we first need to determine the acutal commands needed for configuring the PIO. Assume the DEVICE commands in the CORTEX.CFG file look like this:

DEVICE COMPUBOARD 0x300 INIT
DEVICE PIO24 0x320 NO_INIT

By convention, Cortex numbers the devices by the order in which they are executed in the cortex.cfg file. In the case above, DEVICE number 0 is the Compuboard and device number 1 is the PIO24. In our application, we set up the PIO24 as all inputs. Using the Table below, the control byte for making all ports input ports is 0x9C. The control register for a PIO board is the fourth address on the board, counting from zero. The state file command format is:

DEVoutp(,,)

In our case,

DEVoutp(1,3,0x9C); /* PIO24, control register, set all ports to input */

To execute this command only once, choose one of the persistent integers, for example, _int10. Cortex initializes this integer to zero. Any change to that integer is retained from trial to trial. Wrap the DEVoutp command in an IF statement at the start of "main" in the state file.

if (!_int10) { /* initialized yet? */
_int10=1; /* set initialization flag */
DEVoutp(1,3,0x9C); /* initialize the port */
}

It is actually very simple code.

Manual configuration using BYTE_OUT

In some cases it might be preferable to initialize the I/O boards even before starting Cortex. Such an approach obviates the need to modify the state file. The I/O boards can be initialized using a small DOS program called BYTE_OUT.EXE.BYTE_OUT can be put into the AUTOEXEC.BAT file so the PIO boards are initialized as the computer boots. It can also be used to change the PIO board setting between experiments. BYTE_OUT is a very general purpose program that can send control data to any computer I/O port. It is simple to use:

BYTE_OUT < address > < data >

< address > is the I/O address of where the data should be sent. < data > is the actual 8 bit data byte to send to that address Both of these parameters are entered as hexadecimal values with no special prefix or suffix. Here is an example:

BYTE_OUT 313 9B

In this example the hexadecimal value 9B is sent to port number 313 (also hexadecimal).

If you have a Compuboard DAS16 at address 300 and wish to initialize the PIO ports on that DAS16 to the Cortex defaults (i.e., Port A=input, Port B=output, Port C=input on low bits, output on high bits), use this command:

BYTE_OUT 313 91

If you have a PIO24 at address 320 and wish to use all of its bits for spike latches (all ports=input), use:

BYTE_OUT 323 9B

These last two examples are what we use in our AUTOEXEC.BAT file. As indicated earlier, neither initializations are really necessary in our case, because the PIO24 defaults to all ports as inputs when the computer boots, and Cortex initializes the Compuboard exactly as shown. But, if you want any other assignment of inputs or outputs, you need to run BYTE_OUT in DOS or DEVoutp() in the Cortex state file.

:: Table of PIO port control bytes  
Derived from the Intel 8255A/8255A-5 Programmable Peripheral Interface Data Sheet

Control byte (hex) Port A Port B Port C lower 4 bits Port C upper 4 bits
         
80 output output output output
81 output output input output
82 output output output output
83 output input input output
84 output output output input
89 output output input input
8A output input output input
8B output input input input
90 input output output output
91 input output input output
92 input input output output
93 input input input output
98 input output output input
99 input output input input
9A input input output input
9C input input input input


NIMH CORTEX was written by a team of dedicated researchers for the NIMH Laboratory of Neuropsychology.
Questions or problems regarding this web site should be directed to CortexSite@salk.edu.