diff --git a/src/libDevCom/IOExpander.h b/src/libDevCom/IOExpander.h
index b371073bb3a4eee4920b233ce6e27a55d9dbdf05..43b804b1bf3477a2de2ebd98736c0f756e81a88d 100644
--- a/src/libDevCom/IOExpander.h
+++ b/src/libDevCom/IOExpander.h
@@ -6,21 +6,105 @@
 #include <memory>
 #include <vector>
 
+//! Abstract implementation of digital input/output
+/**
+ * The `IOExpander` class abstracts devices that output or
+ * read (input) a digital signal on a number of pins.
+ *
+ * The number of IO's on the device is not predefined in the
+ * abstract class, but limited to 32 bits by types used. If
+ * a request is made to access a pin outside of range, then
+ * it is silently ignored.
+ */
 class IOExpander {
  public:
     IOExpander() = default;
     virtual ~IOExpander() = default;
 
-    // bit operations
+    /** \name Bit operations
+     *
+     * Manipulate a single IO pin at a time. The default
+     * implementation works by using the block functions
+     * and isolating the specified bit.
+     * @{
+     */
+
+    //! Set direction of pin
+    /**
+     * Throws `OutOfRangeException` if `bit` does not exist.
+     *
+     * \param bit Pin number
+     * \param output Set pin `bit` to output (true) or input (false)
+     */
     void setIO(uint32_t bit, bool output);
+
+    //! Set value of output pin
+    /**
+     * Throws `OutOfRangeException` if `bit` does not exist.
+     *
+     * \param bit Pin number
+     * \param value New value on pin (true=high, false=low)
+     */
     void write(uint32_t bit, bool value);
+
+    //! Read value of input pin
+    /**
+     * Throws `OutOfRangeException` if `bit` does not exist.
+     *
+     * \param bit Pin number
+     *
+     * \return Value read by pin (true=high, false=low).
+     */
     bool read(uint32_t bit);
 
-    // block operations
+    /** @} */
+
+    /** \name Block operations
+     *
+     * Manipulate multiple pins at a time. Assumes a limit of
+     * 32 pins per device, with the bit position corresponding
+     * to the pin number. Any bits outside of supported range
+     * are silently ignored.
+     * @{
+     */
+
+    //! Get direction of pins
+    /**
+     * Bit position in returned integer corresponds to the bit
+     * number.
+     *
+     * \return True means output, false means input.
+     */
     virtual uint32_t getIO() = 0;
+
+    //! Set direction of pins
+    /**
+     * Bit position in `output`  corresponds to the bit
+     * number.
+     *
+     * \param output True means output, false means input.
+     */
     virtual void setIO(uint32_t output) = 0;
+
+    //! Write value of output pins
+    /**
+     * Bit position in `value` corresponds to the bit
+     * number.
+     *
+     * \param value true=high, false=low
+     */
     virtual void write(uint32_t value) = 0;
+
+    //! Read value of input pins
+    /**
+     * Bit position in returned integer corresponds to the bit
+     * number.
+     *
+     * \return true=high, false=low
+     */
     virtual uint32_t read() = 0;
+
+    /** @} */
 };
 
 #endif  // IOEXPANDER_H