How to use IOTester® from a PC program application

Connect a PC program application to the IOTester address range, and you have direct access to your own hardware connected to the IOTester box.
Do low-level RD, WR, AND, OR, XOR operations on I/O hardware directly from your PC program application.

Open the IOTester address range

Getting started with IOTester is simple. Just use iot_init() to open access to the address range, and you have access to do I/O operations to your embedded I/O hardware.

In this example, a simple PC console project is used, so the PC program starts from main().

 /* Define IOTester interface and registers in IOTester box */
 #include <iotester.h>

 void main(void)
    {
    if (iot_init(0))
       return -1; /* IOTester box not connected, not installed */

    // The IOTester address range is open.
    // The PC program application now have access to any I/O
    // hardware connected to IOTester pins. The external bus
    // can be accessed directly from the program.
    // ....
    }
 

Access to I/O pins

The use of IOTester pins is controlled via internal I/O registers in the IOTester box. All registers in the IOTester box have predefined symbolic names. Internal IOTester registers can therefore be accessed simply by their name, without specifying any physical address.
(A manual with a detailed decription of the IOTester box, and C source examples, are included with IOTester.)

 

After power-up, all IOTester pins are input pins. There are two sets of I/O pin registers, one for each connector, J1 and J2.
They can be read directly from the PC application after the iot_init(0) call. For example:

unsigned long con1,con2;
con1 = iot_rd( IOT_INPUT_REG1 );  // Status of J1 pins
con2 = iot_rd( IOT_INPUT_REG2 );  // Status of J2 pins

Before a connector pin can be used for Output the pins direction must be initialized.
Pins are controlled via write operations on special Pin-Set (automatic OR) and Pin-Clear (automatic AND) registers. For examle:

// Configure J1 pin 1 and 2 as output
iot_wr(IOT_IODIRSET_REG1, IOT_J1_PIN1|IOT_J1_PIN2 );

// Set J1, pin 1 active high. Set J1 pin 2 active low.
iot_wr(IOT_IOSET_REG1, IOT_J1_PIN1); // Set pin to high (= OR with pin bit pattern)
iot_wr(IOT_IOCLR_REG1,~IOT_J1_PIN2); // Clear pin to low (= AND with reverse pin bit pattern)

Similarly, it is possible to turn on / off passive pull-up, create floating pins, shift between high - low - 3-states, etc.

External device reset

The default RESET pin is toggled low once at IOTester power-up to provide a facility for automatic reset of I/O hardware chips and hardware connected to IOTester. After power-up, the RESET pin can be controlled from the PC program application like any other IOTester I/O pin.

iot_wr(IOT_IODIRSET_REG1, IOT_RESET_BIT);  // Set reset line to output
iot_wr(IOT_IOCLR_REG1,   ~IOT_RESET_BIT);  // Clear reset bit low
iot_wr(IOT_IOSET_REG1,    IOT_RESET_BIT);  // Set reset bit high

Access to Internal IOTester devices

Internal devices in the IOTester are used by the PC application in exactly the same way as above, by doing I/O access operations on I/O registers.

Here is a simple example which reads the IOTester timestamp counter register to create an accurate delay.

void my_delay(unsigned long ms)
  {
  unsigned long t1 = iot_rd(IOT_TIMESTAMP) + ms;
  while( iot_rd(IOT_TIMESTAMP) < t1);
  }

//...
my_delay(10); // wait 10 ms

In a similar way, a PC application has direct access to other internal I/O devices such as: SPI bus device, I2C bus device, touch screen controller device, TFT display controller device, video RAM buffer etc.

Configure the external address / data bus

The external bus on the IOTester connectors is enabled and configured via a write operation to an internal IOTester register.

Update the IOT_PIN_MODE_REG to define the data bus width, the bus type (8080 or 6800), and the number of external address bus pins needed (0-24).

There is now direct low-level write / read access to I/O registers and memory in any I/O device chips connected to the external bus.

// Configure IOTester for 8 bit data bus, 8080 mode and only one
// address line use externally

iot_wr( IOT_PIN_MODE_REG, DBUS8 | DBUS8080 | ADRBUSSIZE(1));

// External I/O hardware access can now be controlled via bus
// signals on IOTester connector 1: A0, /CS, /WR and /RD.

The external address range starts from address 0. The pin mode configuration example above use only allocate one pin for the external address bus (bit 0). The external physical address can therefore be 0 or 1.

IOTester does basic Write, Read, Or, And, and Xor operations in the same way, on internal registers, the external bus, and the internal video buffer.

// Test Example
// Using Write, Or, And, Xor, Read operations on I/O register located
// at byte address 1.
iot_wr(1, 0xaa);       // Bus /WR clock
iot_and(1, 0xf0);      // Bus /RD, /WR clock
iot_or(1, 0x11);       // Bus /RD, /WR clock
iot_xor(1, 0x42);      // Bus /RD, /WR clock
if (iot_rd(1) != 0xf3) // Bus /RD clock
  {
  // External I/O register was not of type read-modify-write
  }

In the above example, the pin address (1) is entered directly. This will work OK as such. However, it is normally highly recommended to use symbolic names for I/O registers instead, so as to encapsulate all (processor) bus hardware specific knowledge. This allows enables I/O driver C source code to be written so it focuses only on the I/O registers and the functionality of the I/O chip device. In this way, the I/O driver C source code for external I/O chips can be made portable across processor systems.