| IO Ports Common to All Modules | Index |
The TEA VM gives each I/O (Input/Output) device a unique 2-byte address, or port ID. System values, system constants, some reflex elements, and VM semaphores also have IO ports. Additional features and operations may also be controlled with IO ports. Each VM implementation will offer different subsets of these IO ports to allow the VM to interact with the specific I/O offered by the module or host where the VM is running. Most of these ports duplicate the functionality of a command.
To write to an output device, push a value onto the stack. Then pop that value into a device port with the popbm , popbmx , popsm , or popsmx command. To read from an input device, push a value from a device port onto the stack using the pushmb , pushmbx , pushms , or pushmsx command.
The table below lists the ports and reserved address ranges for various I/O devices that are common for the current selection of BrainStem modules.
The table also lists the ports along with the functions, access modes, and default data sizes associated with each port. An asterisk (*) in the data size entry means that the size is strictly enforced. Executing an opcode that uses a different data size will cause an error. If there is no asterisk, the type will be converted appropriately. A char will be padded with a zero byte to convert it to an int. An int will be truncated to convert it to a char.
Port addresses in red denote ports and functions that are available in the newest modules and GP 1.0 modules starting with Build 9.
(See the Common IO Ports chart for a quick reference.)
Port Summary
| Port ID | Name | Description | Access | Size |
|---|---|---|---|---|
| 0x0000 | aPortVMTimer | Delays process execution | w | int |
| 0x0001 | aPortIICRead | Initiates an IIC read | w | int* |
| 0x0002 | aPortProcID | Returns Process ID of calling VM | r | char |
| 0x0010 | aPortSerial | Allows raw serial communication | r/w | char* |
| 0x0011 | aPortDisplayASCII | Formatted VM serial output | w | char |
| 0x0012 | aPortSerialNTX | Initiates raw serial output of N bytes | w | char* |
| 0x0013 | aPortSerialNRX | Initiates raw serial input of N bytes | w | char* |
| 0x0014 | aPortEEPROMRead | Initiates read of byte from module's EEPROM | w | int* |
| 0x0015 | aPortVMQuiet | Immediate acces to quiet mode flag | w | int* |
| 0x0040 | aPortNA2D | Number of A2D inputs | r | char |
| 0x0041 | aPortNDigital | Number of digital I/O pins | r | char |
| 0x0042 | aPortNIR02 | Number of Sharp GP2D02 inputs | r | char |
| 0x0043 | aPortNServo | Number of servo outputs | r | char |
| 0x0044 | aPortNRflxCtr | Number of counters for reflexes | r | char |
| 0x0045 | aPortNRflxEna | Number of reflex enablers | r | char |
| 0x0046 | aPortNScratch | Number of scratch pad bytes | r | char |
| 0x0047 | aPortNGPTimer | Number of general purpose timers | r | char |
| 0x0080 | aPortAddress | Access to module address | r/w | char |
| 0x0081 | aPortRouter | Access to router ID | r/w | char |
| 0x0082 | aPortHBRate | Access to heartbeat rate | r/w | char |
| 0x0083 | aPortIICBaud | Access to IIC baud rate code | r/w | char |
| 0x0084 | aPortSerBaud | Access to serial baud rate code | r/w | char |
| 0x0085 | aPortHBMode | Access to heartbeat mode flag | r/w | char |
| 0x0086 | aPortBootFlag | Access to power-up reflex flag | r/w | char |
| 0x0087 | aPortLinkFlag | Access to link-down reflex flag | r/w | char |
| 0x0088 | aPortVersion | Firmware version | r | int* |
| 0x0089 | aPortBuildNum | Firmware build number | r | int* |
| 0x008A | aPortBoardType | Board type code | r | char |
| 0x008B | aPortSerNum12 | First 2 bytes of board serial number | r | int* |
| 0x008C | aPortSerNum34 | Last 2 bytes of board serial number | r | int* |
| 0x008D | aPortFileSlots | Number of file slots on board | r | char |
| 0x008E | aPortFileBytes | Maximum number of bytes per TEA file | r | int* |
| 0x008F | aPortBoot1 | VM boot program 1 | r/w | char |
| 0x0090 | aPortBoot2 | VM boot program 2 | r/w | char |
| 0x0091 | aPortBoot3 | VM boot program 3 | r/w | char |
| 0x0092 | aPortBoot4 | VM boot program 4 | r/w | char |
| 0x0093 | aPortRelayFlag | Access to serial relay mode flag | r/w | char |
| 0x0094 | aPortQuietFlag | Access to quiet mode flag | r/w | char |
| 0x0095 | aPortTimeout | Access to serial reception timeout | r/w | char |
| 0x0100 - 0x01FF | aPortSemaphore | Semaphore Control | r/w | char |
| 0x0200 - 0x02FF | aPortScratch | Scratch Pad Access | r/w | char |
| 0x0300 - 0x037F | aPortRawInput | Send raw inputs to reflexes | w | char* |
| 0x0380 - 0x039F | aPortRflxEna | Access to reflex enablers | r/w | char* |
| 0x03A0 - 0x03BF | aPortRflxCtr | Access to reflex counters | r/w | int* |
aPortVMTimer
A write to this port puts the VM process to sleep in a quiescent state for the requested period. The period is the value written to the port in 0.1ms increments. If a byte is written to this port, the maximum sleep is 25.5ms. The maximum delay when an int is written to this port is 6.5535 seconds. The value written is interpreted as an unsigned value.
| TEA | The timer port is wrapped by the aCore_Sleep routine. |
aPortProcID
A read from this port pushes the process ID of the calling process onto the stack.
aPortIICRead
A write with an int to this port sets up an IIC read to an arbitrary IIC device on the bus. The high byte of the int is the odd-valued IIC address of the device to be read. The low byte of the int is the number of bytes to be read (1-6). Writing to this port performs the read and the resulting data read from the bus is pushed onto the stack for use by the VM. The current IIC data rate is used for the read transfer. An invalid IIC address or illegal byte count will cause an IO error.
aPortSerial
This port allows transfer of raw serial bytes to/from the serial port. A module using this port must be configured as a router. If it is not, the raw serial IO operation will cause an IO error.
A write with a char outputs a 1-byte value to the serial port. A write with an int outputs a 2-byte value to the serial port. Raw output has no address byte or packet size byte.
Reading from this port stalls the process until a serial byte is available on the serial port. The incoming value is then placed onto the stack and the process continues.
A timeout will occur if data does not arrive within the specified timeout period. When reading a char, a timeout will place a 1-byte value of 0 on the stack. There is no way to tell if the module actually received a 0 or timed out. When reading an int, a timeout will place a 2-byte value of 256 on the stack (0x0100). This makes it possible to distinguish a valid reception of a zero byte from a time out.
The BrainStem serial reception firmware is optimized for receiving command packets. By comparison, VM handling of raw bytes is relatively slow. After receiving a raw byte, it takes some time for a VM to process it. During this processing delay, it is possible to lose incoming bytes. A device transmitting raw bytes to a BrainStem must pause between each byte to ensure reception. The minimum length of this pause must be determined by trial and error.
aPortSerialNTX
Writing a char with value N to this port initiates transmission of the top N bytes on the stack through the serial port. If there are not enough bytes on the stack a stack underflow error will occur. The process stalls until all N bytes are placed in an outgoing serial byte queue. When the process resumes, there may still be bytes in the queue that have not been transmitted. The bytes in the queue will be sent as quickly as the baud rate and hardware will allow. To transmit "hello" with this function, the user would push the 5 characters in order onto the stack, then push a 5, then pop that 5 into the aPortSerialNTX port. This port does not have the router restriction of the aPortSerial port.
aPortSerialNRX
Writing a char with value N to this port initiates reception of N bytes from the serial port. If there is not enough room for N bytes a stack overflow error will occur. The process stalls until all N bytes are received and placed on the stack or a timeout occurs. When a timeout occurs, a zero byte is pushed onto the stack for any bytes that have not been received. Upon completing the reception or timeout, this operation pushes a final byte onto the stack with the number of characters actually received. The total number of bytes pushed will always be N+1. This port does not have the router restriction of the aPortSerial port.
aPortEEPROMRead
Writing an int with value N to this port initiates the read of a byte at address N of the module's EEPROM. When the read is completed, the byte will be pushed onto the stack.
aPortVMQuiet
Reading from this port puts the Quiet Mode flag onto the stack. Writing a 1 or 0 to this port enables or disables Quiet Mode . Any mode changes made through this port will take place immediately.
aPortDisplayASCII
This port is for writing VM data. The output to the host is a standard packet that contains a module address byte, length byte, process ID byte, and ASCII data byte.
aPortNA2D
Reading from this port puts the number of A2D inputs for the module onto the stack. Different module types may have a different number of A2D inputs.
aPortNDigital
Reading from this port puts the number of digital I/O pins for the module onto the stack. Different module types may have a different number of digital I/O pins.
aPortNIR02
Reading from this port puts the number of Sharp GP2D02 inputs for the module onto the stack. Different module types may have a different number of Sharp GP2D02 inputs.
aPortNServo
Reading from this port puts the number of servo outputs for the module onto the stack. Different module types may have a different number of servo outputs.
aPortNReflexCtr
Reading from this port puts the number of reflex counter elements in the module onto the stack. These elements are stored in RAM. Different module types may have a different number of reflex counter elements.
aPortNReflexEnable
Reading from this port puts the number of reflex enabler elements for the module onto the stack. These elements are stored in RAM. Different module types may have a different number of reflex enabler elements.
aPortNScratchPad
Reading from this port puts the number of scratch pad RAM bytes for the module onto the stack. Different module types may have a different number of scratch pad RAM bytes.
aPortNGPTimer
Reading from this port puts the number of general purpose reflex timer elements for the module onto the stack. These elements are stored in RAM. Different module types may have a different number of reflex timer elements.
aPortAddress
Reading from this port puts the address of the module onto the stack. Writing to this port changes the address of the module.
aPortRouter
Reading from this port puts the router address for the module onto the stack. Writing to this port changes the router address for the module. For a single BrainStem, the router address and module address must be the same.
aPortHBRate
Reading from this port puts the heart beat rate for the module onto the stack. This value is in units of 25.6ms. Writing to this port changes the heart beat rate for the module.
aPortIICBaud
Reading from this port puts the IIC baud rate code for the module onto the stack. Writing a new code byte to this port changes the IIC baud rate for the module. The baud rates are as follows:
aPortSerBaud
Reading from this port puts the serial baud rate code for the module onto the stack. Writing to this port changes the serial baud rate code for the module. A serial baud rate change is applied at the next power-up or reset. A change to the serial baud rate must be saved prior to a reset by issuing a cmdVAL_SAV command.
aPortHBMode
Reading from this port puts the heartbeat mode flag onto the stack. Writing a 1 or 0 to this port changes the heart beat mode for the module.
aPortBootFlag
Reading from this port puts the power-up reflex flag onto the stack. Writing a 1 or 0 to this port enables or disables the boot reflex at power-up.
aPortLinkFlag
Reading from this port puts the link-down reflex flag onto the stack. Writing a 1 or 0 to this port enables or disables the link-down reflex.
aPortVersion
Reading from this port puts the firmware version onto the stack.
aPortBuildNum
Reading from this port puts the firmware build number onto the stack.
aPortBoardType
Reading from this port puts the board type code onto the stack.
aPortSerNum12
Reading from this port puts the first two bytes of the board serial number onto the stack.
aPortSerNum34
Reading from this port puts the last two bytes of the board serial number onto the stack.
aPortFileSlots
Reading from this port puts the number of TEA file slots available on the module onto the stack.
aPortFileBytes
Reading from this port puts the maximum number of executable bytes for a TEA file in the module onto the stack. Some TEA file slots in a module may not have the maximum number of bytes.
aPortBoot1
Reading from this port puts the file ID for boot-up TEA file 1 onto the stack.
aPortBoot2
Reading from this port puts the file ID for boot-up TEA file 2 onto the stack.
aPortBoot3
Reading from this port puts the file ID for boot-up TEA file 3 onto the stack.
aPortBoot4
Reading from this port puts the file ID for boot-up TEA file 4 onto the stack.
aPortRelayFlag
Reading from this port puts the serial relay mode flag onto the stack. Writing a 1 or 0 to this port enables or disables the serial relay mode.
aPortQuietFlag
Reading from this port puts the Quiet Mode start-up flag onto the stack. Writing a 1 or 0 to this port enables or disables the Quiet Mode . Any changes made through this port will be applied at next power-up or reset. Once Quiet Mode is enabled via this port, the module will require a hard reset to disable it unless it is in a network.
aPortTimeout
Reading from this port puts the timeout period for the module onto the stack. This value is in units of 25.6ms. Writing to this port changes the timeout period for the module. This timeout parameter applies to command packet reception, serial reception routines in TEA programs, and packet transfer in serial relay mode.
aPortSemaphore
This group of memory addresses is reserved for VM semaphore control. Adding an offset to the base address provides access to a particular semaphore. The number of semaphores available on a module is equal to the number of VM processes that the module can run. Reading from one of the ports in this range forces a VM to enter a wait state until another VM or reflex writes to that semaphore port. Writing to one of these ports pops a char or int from the stack and restarts a VM that is waiting for that value. The cmdDEV_VAL command provides semaphore write functionality for a reflex.
When reading a 2-byte semaphore value into a byte, the single byte will get the high-byte of the 2-byte value.
aPortScratch
This group of memory addresses is reserved for scratch pad access. Adding an offset to the base address provides access to a particular byte. Access to an int value requires an even offset since an int is two bytes. An odd offset for an int access will generate an error. Reading from one of the ports in this range puts a char or int from the scratch pad onto the stack. Writing to one of these ports pops a char or int from the stack and stores it in the scratch pad. The cmdPAD_IO command provides equivalent functionality.
aPortRawInput
This group of memory addresses is reserved for sending raw inputs to reflexes via memory writes. Writing to one of these ports pops a byte/short from the stack and forces the module to issue a cmdRAW_INPUT command. The offset from the base address is the raw input ID. The value popped from the stack is the raw input parameter. The cmdRAW_INPUT command provides equivalent functionality.
aPortRflxEna
This group of memory addresses is reserved for reflex enabler access. Adding an offset to the base address provides access to a particular reflex enabler. Writing to one of these ports pops a char from the stack and configures a reflex enabler with the value. The cmdRFLXE_CFG command provides equivalent functionality.
aPortRflxCtr
This group of memory addresses is reserved for reflex counter access. Adding an offset to the base address provides access to a particular reflex counter. Reading from one of these ports pushes the two-byte value of a counter onto the stack. Writing to one of these ports pops an int from the stack and saves it into a two-byte counter. The cmdCTR_SET command provides equivalent functionality.