A C++ template library for embedded applications
Designed and maintained by
Aster Consulting Ltd

io_port

A set of templates for building interface classes to memory mapped hardware ports.
They avoid the need to directly map carefully packed (and possibly non-portable) structures onto memory addresses.

Note: A read from a write-only,  or write to a read-only port will result in a compile time error.

Defines classes for the following IO types:-
Read / Write.
Read only.
Write only.
Write only with shadow register.

With a shadow register, the value written is stored locally and may be read back.

The port may either have an address fixed at compile time or set at runtime. The compile time versions require no extra
overhead compared to a plain memory mapped structure.

Compile time port addresses

template <uintptr_t ADDRESS>
struct serial_port
{
  etl::io_port_ro<char,     ADDRESS>     rxdata;   // Read only rx data register.
  etl::io_port_wo<char,     ADDRESS + 1> txdata;   // Write only tx register.
  etl::io_port_rw<uint16_t, ADDRESS + 2> control;  // Read / write control register.
  etl::io_port_ro<uint16_t, ADDRESS + 4> status;   // Read only status register.
  etl::io_port_wos<uint8_t, ADDRESS + 6> control2; // Write only with shadow register.
};

serial_port<0x800> port; // A serial port at address 0x800

char data   = port.rxdata;
port.txdata = 'A';

data = port.txdata; // Compile error!

Runtime time port addresses

struct serial_port
{
  serial_port(uint8_t* base)
    : rxdata(base),
      txdata(base + 1),
      control(base + 2),
      status(base + 4),
      control2(base + 6)
  {
  }

  etl::io_port_ro<char>     rxdata;   // Read only rx data register.
  etl::io_port_wo<char>     txdata;   // Write only tx register.
  etl::io_port_rw<uint16_t> control;  // Read / write control register.
  etl::io_port_ro<uint16_t> status;   // Read only status register.
  etl::io_port_wos<uint8_t> control2; // Write only with shadow register.
};

serial_port port(0x800);

char data   = port.rxdata;
port.txdata = 'A';

data = port.txdata; // Compile error!                                                    
io_port.h