Under The Hood (How microspeclib works)
=======================================

Every API function call **sends a command** to the dev-kit and **receives a
reply** from the dev-kit.

All commands are sent (and replies received) via a single method,
``sendAndReceive()``. This method takes care of all low-level communication
concerns like waiting for a reply and packages the reply as an object with each
field in its own attribute.

For example, the reply to ``captureFrame()`` has attribute ``num_pixels`` (the
number of pixels in the frame) and attribute ``pixels`` (the actual pixel data).

Hardware under the hood
^^^^^^^^^^^^^^^^^^^^^^^

The dev-kit has a ``Sensor`` board that talks directly to the spectrometer chip
and a ``Bridge`` board that provides the USB interface to ``Sensor``. Most API
calls are commands for ``Sensor``. There are a few ``Bridge`` commands, but
applications do not need to use them.

Two APIs: simple and expert
^^^^^^^^^^^^^^^^^^^^^^^^^^^

``microspec`` actually has two APIs:

- ``microspeclib.simple``

  - *high-level* API for writing applications
  - hides the call to ``sendAndReceive()``
  - represents each command as its own API function calls, e.g.,
    ``setExposure(500)`` and ``reply=captureFrame()``

- ``microspeclib.expert``

  - *low-level* API for developers
  - applications *never* need to use this API
  - this API is helpful when troubleshooting USB communication
  - all commands are explicitly passed to ``sendAndReceive()``, e.g.,
    ``sendAndReceive(CommandSetExposure(cycles=500))`` and
    ``reply=sendAndReceive(CommandCaptureFrame())``
  - commands may also be *sent* and *received* separately, e.g.,
    ``sendCommand(CommandCaptureFrame())`` followed by ``reply=receiveReply()``

For an example of this lower-level interface, clone the ``microspec``
respository and see ``src/microspeclib/examples/microspec_lowlevel_api.py``

Where is the code?
^^^^^^^^^^^^^^^^^^

Do not look for the API function definitions in the source code. The
``microspeclib`` package *does not manually define dev-kit interface functions*.

The API function definitions are auto-generated by
``microspeclib.simple._generateFuction()`` using the protocol defined in JSON in
``microspec.cfg``.


