If you programming for microprocessors you can assign some pins for input and some for outputs. You can even assign all ports for input or all for output, but sometimes you need to use the same pin for read and write. Lot’s of buses like 1-wire, I2C and others using only one wire for data transfer in both directions. So there must be the way, how to operate pins in read/write mode. The way is called tristate register. Value in tristate register defines if the port operates in read or write mode.

TristatePort Class

In .NET Micro Framework is tristate register “encapsulated” into TristatePort class, which provides functionality of the InputPort and OutputPort. TristatePort has bool property called Active to switch between input and output mode. Anyway, switching before every operation is a bit annoying. Why not implement custom class inherited from TristatePort that provides “careless” Read and Write methods. Following IOPort class exposes two methods Read and Write(bool state), which internally switching Active property into appropriate state.

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace IOPortExample
{
    public class IOPort : IDisposable
    {
        private TristatePort _tristatePort;

        // Constructor
        public IOPort(Cpu.Pin portPin, bool initialState, bool glitchFiler, Port.ResistorMode resistor)
        {
            _tristatePort = new TristatePort(portPin, initialState, glitchFiler, resistor);
        }

        // Write state
        public void Write(bool state)
        {
            if (! _tristatePort.Active)
                    _tristatePort.Active = true;

            _tristatePort.Write(state);
        }

        // Read state
        public bool Read()
        {
            if(_tristatePort.Active)
                    _tristatePort.Active = false;

            return _tristatePort.Read();
        }

        // Dispose
        public void Dispose()
        {
            _tristatePort.Dispose();
        }
    }
}

There is no magic when using the class.

IOPort port = new IOPort(Cpu.Pin.GPIO_Pin1, false, false, Port.ResistorMode.PullUp);            

// Writing
port.Write(true);

Thread.Sleep(1000);

// Reading
bool state = port.Read();

port.Dispose();