diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,5 +1,5 @@
 name:                  sbp
-version:               0.50.2
+version:               0.50.3
 synopsis:              SwiftNav's SBP Library
 homepage:              https://github.com/swift-nav/libsbp
 license:               LGPL-3
diff --git a/src/SwiftNav/SBP.hs b/src/SwiftNav/SBP.hs
--- a/src/SwiftNav/SBP.hs
+++ b/src/SwiftNav/SBP.hs
@@ -89,6 +89,7 @@
    | SBPMsgHeartbeat MsgHeartbeat
    | SBPMsgIarState MsgIarState
    | SBPMsgInitBase MsgInitBase
+   | SBPMsgLog MsgLog
    | SBPMsgM25FlashWriteStatus MsgM25FlashWriteStatus
    | SBPMsgMaskSatellite MsgMaskSatellite
    | SBPMsgNapDeviceDnaReq MsgNapDeviceDnaReq
@@ -97,7 +98,7 @@
    | SBPMsgObsDepA MsgObsDepA
    | SBPMsgPosEcef MsgPosEcef
    | SBPMsgPosLlh MsgPosLlh
-   | SBPMsgPrint MsgPrint
+   | SBPMsgPrintDep MsgPrintDep
    | SBPMsgReset MsgReset
    | SBPMsgResetFilters MsgResetFilters
    | SBPMsgSetTime MsgSetTime
diff --git a/src/SwiftNav/SBP/Acquisition.hs b/src/SwiftNav/SBP/Acquisition.hs
--- a/src/SwiftNav/SBP/Acquisition.hs
+++ b/src/SwiftNav/SBP/Acquisition.hs
@@ -1,3 +1,13 @@
+-- |
+-- Module:      SwiftNav.SBP.Acquisition
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Satellite acquisition messages from the device.
+
 module SwiftNav.SBP.Acquisition where
 
 import Control.Monad
@@ -14,11 +24,24 @@
 msgAcqResult :: Word16
 msgAcqResult = 0x0014
 
+-- | SBP class for message MSG_ACQ_RESULT (0x0014).
+--
+-- This message describes the results from an attempted GPS signal acquisition
+-- search for a satellite PRN over a code phase/carrier frequency range. It
+-- contains the parameters of the point in the acquisition search space with
+-- the best signal-to-noise (SNR) ratio.
 data MsgAcqResult = MsgAcqResult
   { msgAcqResultSnr :: Float
+    -- ^ SNR of best point. Currently dimensonless, but will have units of dB Hz
+    -- in the revision of this message.
   , msgAcqResultCp  :: Float
+    -- ^ Code phase of best point
   , msgAcqResultCf  :: Float
+    -- ^ Carrier frequency of best point
   , msgAcqResultSid :: Word32
+    -- ^ Signal identifier of the satellite signal for which acquisition was
+    -- attempted - values 0x00 through 0x1F represent GPS PRNs 1 through 32
+    -- respectively (PRN-1 notation); other values reserved for future use.
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgAcqResult where
@@ -38,11 +61,20 @@
 msgAcqResultDepA :: Word16
 msgAcqResultDepA = 0x0015
 
+-- | SBP class for message MSG_ACQ_RESULT_DEP_A (0x0015).
+--
+-- Deprecated.
 data MsgAcqResultDepA = MsgAcqResultDepA
   { msgAcqResultDepASnr :: Float
+    -- ^ SNR of best point. Currently dimensonless, but will have units of dB Hz
+    -- in the revision of this message.
   , msgAcqResultDepACp  :: Float
+    -- ^ Code phase of best point
   , msgAcqResultDepACf  :: Float
+    -- ^ Carrier frequency of best point
   , msgAcqResultDepAPrn :: Word8
+    -- ^ PRN-1 identifier of the satellite signal for which acquisition was
+    -- attempted
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgAcqResultDepA where
diff --git a/src/SwiftNav/SBP/Bootload.hs b/src/SwiftNav/SBP/Bootload.hs
--- a/src/SwiftNav/SBP/Bootload.hs
+++ b/src/SwiftNav/SBP/Bootload.hs
@@ -1,3 +1,16 @@
+-- |
+-- Module:      SwiftNav.SBP.Bootload
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Messages for the bootloading configuration on the device.  These are in the
+-- implementation-defined range (0x0000-0x00FF), and are intended for internal
+-- use only. Note that some of these messages share the same message type ID
+-- for both the host request and the device response.
+
 module SwiftNav.SBP.Bootload where
 
 import Control.Monad
@@ -14,6 +27,11 @@
 msgBootloaderHandshakeReq :: Word16
 msgBootloaderHandshakeReq = 0x00B3
 
+-- | SBP class for message MSG_BOOTLOADER_HANDSHAKE_REQ (0x00B3).
+--
+-- The handshake message request from the host establishes a handshake between
+-- the device bootloader and the host. The response from the device is
+-- MSG_BOOTLOADER_HANDSHAKE_RESP.
 data MsgBootloaderHandshakeReq = MsgBootloaderHandshakeReq
   deriving ( Show, Read, Eq )
 
@@ -27,9 +45,17 @@
 msgBootloaderHandshakeResp :: Word16
 msgBootloaderHandshakeResp = 0x00B4
 
+-- | SBP class for message MSG_BOOTLOADER_HANDSHAKE_RESP (0x00B4).
+--
+-- The handshake message response from the device establishes a handshake
+-- between the device bootloader and the host. The request from the host is
+-- MSG_BOOTLOADER_HANDSHAKE_REQ.  The payload contains the bootloader version
+-- number and the SBP protocol version number.
 data MsgBootloaderHandshakeResp = MsgBootloaderHandshakeResp
   { msgBootloaderHandshakeRespFlags   :: Word32
+    -- ^ Bootloader flags
   , msgBootloaderHandshakeRespVersion :: ByteString
+    -- ^ Bootloader version number
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgBootloaderHandshakeResp where
@@ -45,8 +71,12 @@
 msgBootloaderJumpToApp :: Word16
 msgBootloaderJumpToApp = 0x00B1
 
+-- | SBP class for message MSG_BOOTLOADER_JUMP_TO_APP (0x00B1).
+--
+-- The host initiates the bootloader to jump to the application.
 data MsgBootloaderJumpToApp = MsgBootloaderJumpToApp
   { msgBootloaderJumpToAppJump :: Word8
+    -- ^ Ignored by the device
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgBootloaderJumpToApp where
@@ -60,6 +90,13 @@
 msgNapDeviceDnaReq :: Word16
 msgNapDeviceDnaReq = 0x00DE
 
+-- | SBP class for message MSG_NAP_DEVICE_DNA_REQ (0x00DE).
+--
+-- The device message from the host reads a unique device identifier from the
+-- SwiftNAP, an FPGA. The host requests the ID by sending a
+-- MSG_NAP_DEVICE_DNA_REQ message. The device responds with a
+-- MSG_NAP_DEVICE_DNA_RESP message with the device ID in the payload. Note that
+-- this ID is tied to the FPGA, and not related to the Piksi's serial number.
 data MsgNapDeviceDnaReq = MsgNapDeviceDnaReq
   deriving ( Show, Read, Eq )
 
@@ -73,8 +110,17 @@
 msgNapDeviceDnaResp :: Word16
 msgNapDeviceDnaResp = 0x00DD
 
+-- | SBP class for message MSG_NAP_DEVICE_DNA_RESP (0x00DD).
+--
+-- The device message from the host reads a unique device identifier from the
+-- SwiftNAP, an FPGA. The host requests the ID by sending a
+-- MSG_NAP_DEVICE_DNA_REQ message. The device responds with a
+-- MSG_NAP_DEVICE_DNA_RESP messagage with the device ID in the payload. Note
+-- that this ID is tied to the FPGA, and not related to the Piksi's serial
+-- number.
 data MsgNapDeviceDnaResp = MsgNapDeviceDnaResp
   { msgNapDeviceDnaRespDna :: [Word8]
+    -- ^ 57-bit SwiftNAP FPGA Device ID. Remaining bits are padded on the right.
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgNapDeviceDnaResp where
@@ -88,8 +134,12 @@
 msgBootloaderHandshakeDepA :: Word16
 msgBootloaderHandshakeDepA = 0x00B0
 
+-- | SBP class for message MSG_BOOTLOADER_HANDSHAKE_DEP_A (0x00B0).
+--
+-- Deprecated.
 data MsgBootloaderHandshakeDepA = MsgBootloaderHandshakeDepA
   { msgBootloaderHandshakeDepAHandshake :: [Word8]
+    -- ^ Version number string (not NULL terminated)
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgBootloaderHandshakeDepA where
diff --git a/src/SwiftNav/SBP/ExtEvents.hs b/src/SwiftNav/SBP/ExtEvents.hs
--- a/src/SwiftNav/SBP/ExtEvents.hs
+++ b/src/SwiftNav/SBP/ExtEvents.hs
@@ -1,3 +1,14 @@
+-- |
+-- Module:      SwiftNav.SBP.ExtEvents
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Messages reporting accurately-timestamped external events, e.g. camera
+-- shutter time.
+
 module SwiftNav.SBP.ExtEvents where
 
 import Control.Monad
@@ -14,12 +25,22 @@
 msgExtEvent :: Word16
 msgExtEvent = 0x0101
 
+-- | SBP class for message MSG_EXT_EVENT (0x0101).
+--
+-- Reports detection of an external event, the GPS time it occurred, which pin
+-- it was and whether it was rising or falling.
 data MsgExtEvent = MsgExtEvent
   { msgExtEventWn    :: Word16
+    -- ^ GPS week number
   , msgExtEventTow   :: Word32
+    -- ^ GPS time of week rounded to the nearest millisecond
   , msgExtEventNs    :: Int32
+    -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
+    -- 500000)
   , msgExtEventFlags :: Word8
+    -- ^ Flags
   , msgExtEventPin   :: Word8
+    -- ^ Pin number.  0..9 = DEBUG0..9.
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgExtEvent where
diff --git a/src/SwiftNav/SBP/FileIo.hs b/src/SwiftNav/SBP/FileIo.hs
--- a/src/SwiftNav/SBP/FileIo.hs
+++ b/src/SwiftNav/SBP/FileIo.hs
@@ -1,3 +1,20 @@
+-- |
+-- Module:      SwiftNav.SBP.FileIo
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Messages for using device's onboard flash filesystem functionality. This
+-- allows data to be stored persistently in the device's program flash with
+-- wear-levelling using a simple filesystem interface. The file system
+-- interface (CFS) defines an abstract API for reading directories and for
+-- reading and writing files.  These are in the implementation-defined range
+-- (0x0000-0x00FF), and intended for internal-use only. Note that some of these
+-- messages share the same message type ID for both the host request and the
+-- device response.
+
 module SwiftNav.SBP.FileIo where
 
 import Control.Monad
@@ -14,11 +31,21 @@
 msgFileioReadReq :: Word16
 msgFileioReadReq = 0x00A8
 
+-- | SBP class for message MSG_FILEIO_READ_REQ (0x00A8).
+--
+-- The file read message reads a certain length (up to 255 bytes) from a given
+-- offset into a file, and returns the data in a MSG_FILEIO_READ_RESP message
+-- where the message length field indicates how many bytes were succesfully
+-- read.The sequence number in the request will be returned in the response.
 data MsgFileioReadReq = MsgFileioReadReq
   { msgFileioReadReqSequence   :: Word32
+    -- ^ Read sequence number
   , msgFileioReadReqOffset     :: Word32
+    -- ^ File offset
   , msgFileioReadReqChunkSize  :: Word8
+    -- ^ Chunk size to read
   , msgFileioReadReqFilename   :: ByteString
+    -- ^ Name of the file to read from
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioReadReq where
@@ -38,9 +65,17 @@
 msgFileioReadResp :: Word16
 msgFileioReadResp = 0x00A3
 
+-- | SBP class for message MSG_FILEIO_READ_RESP (0x00A3).
+--
+-- The file read message reads a certain length (up to 255 bytes) from a given
+-- offset into a file, and returns the data in a message where the message
+-- length field indicates how many bytes were succesfully read. The sequence
+-- number in the response is preserved from the request.
 data MsgFileioReadResp = MsgFileioReadResp
   { msgFileioReadRespSequence :: Word32
+    -- ^ Read sequence number
   , msgFileioReadRespContents :: [Word8]
+    -- ^ Contents of read file
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioReadResp where
@@ -56,10 +91,21 @@
 msgFileioReadDirReq :: Word16
 msgFileioReadDirReq = 0x00A9
 
+-- | SBP class for message MSG_FILEIO_READ_DIR_REQ (0x00A9).
+--
+-- The read directory message lists the files in a directory on the device's
+-- onboard flash file system.  The offset parameter can be used to skip the
+-- first n elements of the file list. Returns a MSG_FILEIO_READ_DIR_RESP
+-- message containing the directory listings as a NULL delimited list. The
+-- listing is chunked over multiple SBP packets. The sequence number in the
+-- request will be returned in the response.
 data MsgFileioReadDirReq = MsgFileioReadDirReq
   { msgFileioReadDirReqSequence :: Word32
+    -- ^ Read sequence number
   , msgFileioReadDirReqOffset   :: Word32
+    -- ^ The offset to skip the first n elements of the file list
   , msgFileioReadDirReqDirname  :: ByteString
+    -- ^ Name of the directory to list
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioReadDirReq where
@@ -77,9 +123,18 @@
 msgFileioReadDirResp :: Word16
 msgFileioReadDirResp = 0x00AA
 
+-- | SBP class for message MSG_FILEIO_READ_DIR_RESP (0x00AA).
+--
+-- The read directory message lists the files in a directory on the device's
+-- onboard flash file system. Message contains the directory listings as a NULL
+-- delimited list. The listing is chunked over multiple SBP packets and the end
+-- of the list is identified by an entry containing just the character 0xFF.
+-- The sequence number in the response is preserved from the request.
 data MsgFileioReadDirResp = MsgFileioReadDirResp
   { msgFileioReadDirRespSequence :: Word32
+    -- ^ Read sequence number
   , msgFileioReadDirRespContents :: [Word8]
+    -- ^ Contents of read directory
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioReadDirResp where
@@ -95,8 +150,12 @@
 msgFileioRemove :: Word16
 msgFileioRemove = 0x00AC
 
+-- | SBP class for message MSG_FILEIO_REMOVE (0x00AC).
+--
+-- The file remove message deletes a file from the file system.
 data MsgFileioRemove = MsgFileioRemove
   { msgFileioRemoveFilename :: ByteString
+    -- ^ Name of the file to delete
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioRemove where
@@ -110,11 +169,21 @@
 msgFileioWriteReq :: Word16
 msgFileioWriteReq = 0x00AD
 
+-- | SBP class for message MSG_FILEIO_WRITE_REQ (0x00AD).
+--
+-- The file write message writes a certain length (up to 255 bytes) of data to
+-- a file at a given offset. Returns a copy of the original
+-- MSG_FILEIO_WRITE_RESP message to check integrity of the write. The sequence
+-- number in the request will be returned in the response.
 data MsgFileioWriteReq = MsgFileioWriteReq
   { msgFileioWriteReqSequence :: Word32
+    -- ^ Write sequence number
   , msgFileioWriteReqOffset   :: Word32
+    -- ^ Offset into the file at which to start writing in bytes
   , msgFileioWriteReqFilename :: ByteString
+    -- ^ Name of the file to write to
   , msgFileioWriteReqData     :: [Word8]
+    -- ^ Variable-length array of data to write
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioWriteReq where
@@ -134,8 +203,15 @@
 msgFileioWriteResp :: Word16
 msgFileioWriteResp = 0x00AB
 
+-- | SBP class for message MSG_FILEIO_WRITE_RESP (0x00AB).
+--
+-- The file write message writes a certain length (up to 255 bytes) of data to
+-- a file at a given offset. The message is a copy of the original
+-- MSG_FILEIO_WRITE_REQ message to check integrity of the write. The sequence
+-- number in the response is preserved from the request.
 data MsgFileioWriteResp = MsgFileioWriteResp
   { msgFileioWriteRespSequence :: Word32
+    -- ^ Write sequence number
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFileioWriteResp where
diff --git a/src/SwiftNav/SBP/Flash.hs b/src/SwiftNav/SBP/Flash.hs
--- a/src/SwiftNav/SBP/Flash.hs
+++ b/src/SwiftNav/SBP/Flash.hs
@@ -1,3 +1,17 @@
+-- |
+-- Module:      SwiftNav.SBP.Flash
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Messages for reading/writing the device's onboard flash memory. Many of
+-- these messages target specific flash memory peripherals used in Swift
+-- Navigation devices: the STM32 flash and the M25Pxx FPGA configuration flash.
+-- These are in the implementation-defined range (0x0000-0x00FF), and are
+-- intended for internal-use only.
+
 module SwiftNav.SBP.Flash where
 
 import Control.Monad
@@ -14,11 +28,22 @@
 msgFlashProgram :: Word16
 msgFlashProgram = 0x00E6
 
+-- | SBP class for message MSG_FLASH_PROGRAM (0x00E6).
+--
+-- The flash program message programs a set of addresses of either the STM or
+-- M25 flash. The device replies with either a MSG_FLASH_DONE message
+-- containing the return code FLASH_OK (0) on success, or FLASH_INVALID_LEN (2)
+-- if the maximum write size is exceeded. Note that the sector-containing
+-- addresses must be erased before addresses can be programmed.
 data MsgFlashProgram = MsgFlashProgram
   { msgFlashProgramTarget     :: Word8
+    -- ^ Target flags
   , msgFlashProgramAddrStart  :: [Word8]
+    -- ^ Starting address offset to program
   , msgFlashProgramAddrLen    :: Word8
+    -- ^ Length of set of addresses to program, counting up from starting address
   , msgFlashProgramData       :: [Word8]
+    -- ^ Data to program addresses with, with length N=addr_len
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFlashProgram where
@@ -38,8 +63,15 @@
 msgFlashDone :: Word16
 msgFlashDone = 0x00E0
 
+-- | SBP class for message MSG_FLASH_DONE (0x00E0).
+--
+-- This message defines success or failure codes for a variety of flash memory
+-- requests from the host to the device. Flash read and write messages, such as
+-- MSG_FLASH_READ_REQ, or MSG_FLASH_PROGRAM, may return this message on
+-- failure.
 data MsgFlashDone = MsgFlashDone
   { msgFlashDoneResponse :: Word8
+    -- ^ Response flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFlashDone where
@@ -53,10 +85,21 @@
 msgFlashReadReq :: Word16
 msgFlashReadReq = 0x00E7
 
+-- | SBP class for message MSG_FLASH_READ_REQ (0x00E7).
+--
+-- The flash read message reads a set of addresses of either the STM or M25
+-- onboard flash. The device replies with a MSG_FLASH_READ_RESP message
+-- containing either the read data on success or a MSG_FLASH_DONE message
+-- containing the return code FLASH_INVALID_LEN (2) if the maximum read size is
+-- exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the allowed
+-- range.
 data MsgFlashReadReq = MsgFlashReadReq
   { msgFlashReadReqTarget     :: Word8
+    -- ^ Target flags
   , msgFlashReadReqAddrStart  :: [Word8]
+    -- ^ Starting address offset to read from
   , msgFlashReadReqAddrLen    :: Word8
+    -- ^ Length of set of addresses to read, counting up from starting address
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFlashReadReq where
@@ -74,10 +117,21 @@
 msgFlashReadResp :: Word16
 msgFlashReadResp = 0x00E1
 
+-- | SBP class for message MSG_FLASH_READ_RESP (0x00E1).
+--
+-- The flash read message reads a set of addresses of either the STM or M25
+-- onboard flash. The device replies with a MSG_FLASH_READ_RESP message
+-- containing either the read data on success or a MSG_FLASH_DONE message
+-- containing the return code FLASH_INVALID_LEN (2) if the maximum read size is
+-- exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the allowed
+-- range.
 data MsgFlashReadResp = MsgFlashReadResp
   { msgFlashReadRespTarget     :: Word8
+    -- ^ Target flags
   , msgFlashReadRespAddrStart  :: [Word8]
+    -- ^ Starting address offset to read from
   , msgFlashReadRespAddrLen    :: Word8
+    -- ^ Length of set of addresses to read, counting up from starting address
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFlashReadResp where
@@ -95,9 +149,17 @@
 msgFlashErase :: Word16
 msgFlashErase = 0x00E2
 
+-- | SBP class for message MSG_FLASH_ERASE (0x00E2).
+--
+-- The flash erase message from the host erases a sector of either the STM or
+-- M25 onboard flash memory. The device will reply with a MSG_FLASH_DONE
+-- message containing the return code - FLASH_OK (0) on success or
+-- FLASH_INVALID_FLASH (1) if the flash specified is invalid.
 data MsgFlashErase = MsgFlashErase
   { msgFlashEraseTarget     :: Word8
+    -- ^ Target flags
   , msgFlashEraseSectorNum  :: Word32
+    -- ^ Flash sector number to erase (0-11 for the STM, 0-15 for the M25)
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgFlashErase where
@@ -113,8 +175,13 @@
 msgStmFlashLockSector :: Word16
 msgStmFlashLockSector = 0x00E3
 
+-- | SBP class for message MSG_STM_FLASH_LOCK_SECTOR (0x00E3).
+--
+-- The flash lock message locks a sector of the STM flash memory. The device
+-- replies with a MSG_FLASH_DONE message.
 data MsgStmFlashLockSector = MsgStmFlashLockSector
   { msgStmFlashLockSectorSector :: Word32
+    -- ^ Flash sector number to lock
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgStmFlashLockSector where
@@ -128,8 +195,13 @@
 msgStmFlashUnlockSector :: Word16
 msgStmFlashUnlockSector = 0x00E4
 
+-- | SBP class for message MSG_STM_FLASH_UNLOCK_SECTOR (0x00E4).
+--
+-- The flash unlock message unlocks a sector of the STM flash memory. The
+-- device replies with a MSG_FLASH_DONE message.
 data MsgStmFlashUnlockSector = MsgStmFlashUnlockSector
   { msgStmFlashUnlockSectorSector :: Word32
+    -- ^ Flash sector number to unlock
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgStmFlashUnlockSector where
@@ -143,6 +215,11 @@
 msgStmUniqueIdReq :: Word16
 msgStmUniqueIdReq = 0x00E8
 
+-- | SBP class for message MSG_STM_UNIQUE_ID_REQ (0x00E8).
+--
+-- This message reads the device's hardcoded unique ID. The host requests the
+-- ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a
+-- MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload.
 data MsgStmUniqueIdReq = MsgStmUniqueIdReq
   deriving ( Show, Read, Eq )
 
@@ -156,8 +233,14 @@
 msgStmUniqueIdResp :: Word16
 msgStmUniqueIdResp = 0x00E5
 
+-- | SBP class for message MSG_STM_UNIQUE_ID_RESP (0x00E5).
+--
+-- This message reads the device's hardcoded unique ID. The host requests the
+-- ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a
+-- MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload..
 data MsgStmUniqueIdResp = MsgStmUniqueIdResp
   { msgStmUniqueIdRespStmId  :: [Word8]
+    -- ^ Device unique ID
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgStmUniqueIdResp where
@@ -171,8 +254,13 @@
 msgM25FlashWriteStatus :: Word16
 msgM25FlashWriteStatus = 0x00F3
 
+-- | SBP class for message MSG_M25_FLASH_WRITE_STATUS (0x00F3).
+--
+-- The flash status message writes to the 8-bit M25 flash status register. The
+-- device replies with a MSG_FLASH_DONE message.
 data MsgM25FlashWriteStatus = MsgM25FlashWriteStatus
   { msgM25FlashWriteStatusStatus :: [Word8]
+    -- ^ Byte to write to the M25 flash status register
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgM25FlashWriteStatus where
diff --git a/src/SwiftNav/SBP/Logging.hs b/src/SwiftNav/SBP/Logging.hs
--- a/src/SwiftNav/SBP/Logging.hs
+++ b/src/SwiftNav/SBP/Logging.hs
@@ -1,3 +1,14 @@
+-- |
+-- Module:      SwiftNav.SBP.Logging
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Logging and debugging messages from the device. These are in the
+-- implementation-defined range (0x0000-0x00FF).
+
 module SwiftNav.SBP.Logging where
 
 import Control.Monad
@@ -11,26 +22,40 @@
 import Data.Int
 import Data.Word
 
-msgPrint :: Word16
-msgPrint = 0x0010
+msgLog :: Word16
+msgLog = 0x0401
 
-data MsgPrint = MsgPrint
-  { msgPrintText :: ByteString
+-- | SBP class for message MSG_LOG (0x0401).
+--
+-- This message contains a human-readable payload string from the device
+-- containing errors, warnings and informational messages at ERROR, WARNING,
+-- DEBUG, INFO logging levels.
+data MsgLog = MsgLog
+  { msgLogLevel :: Word8
+    -- ^ Logging level
+  , msgLogText  :: ByteString
+    -- ^ Human-readable string
   } deriving ( Show, Read, Eq )
 
-instance Binary MsgPrint where
+instance Binary MsgLog where
   get = do
-    msgPrintText <- liftM toStrict getRemainingLazyByteString
-    return MsgPrint {..}
+    msgLogLevel <- getWord8
+    msgLogText <- liftM toStrict getRemainingLazyByteString
+    return MsgLog {..}
 
-  put MsgPrint {..} = do
-    putByteString msgPrintText
+  put MsgLog {..} = do
+    putWord8 msgLogLevel
+    putByteString msgLogText
 
 msgTweet :: Word16
 msgTweet = 0x0012
 
+-- | SBP class for message MSG_TWEET (0x0012).
+--
+-- All the news fit to tweet.
 data MsgTweet = MsgTweet
   { msgTweetTweet :: ByteString
+    -- ^ Human-readable string
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgTweet where
@@ -40,3 +65,22 @@
 
   put MsgTweet {..} = do
     putByteString msgTweetTweet
+
+msgPrintDep :: Word16
+msgPrintDep = 0x0010
+
+-- | SBP class for message MSG_PRINT_DEP (0x0010).
+--
+-- Deprecated.
+data MsgPrintDep = MsgPrintDep
+  { msgPrintDepText :: ByteString
+    -- ^ Human-readable string
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgPrintDep where
+  get = do
+    msgPrintDepText <- liftM toStrict getRemainingLazyByteString
+    return MsgPrintDep {..}
+
+  put MsgPrintDep {..} = do
+    putByteString msgPrintDepText
diff --git a/src/SwiftNav/SBP/Navigation.hs b/src/SwiftNav/SBP/Navigation.hs
--- a/src/SwiftNav/SBP/Navigation.hs
+++ b/src/SwiftNav/SBP/Navigation.hs
@@ -1,3 +1,21 @@
+-- |
+-- Module:      SwiftNav.SBP.Navigation
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Geodetic navigation messages reporting GPS time, position, velocity, and
+-- baseline position solutions. For position solutions, these messages define
+-- several different position solutions: single-point (SPP), RTK, and pseudo-
+-- absolute position solutions.  The SPP is the standalone, absolute GPS
+-- position solution using only a single receiver. The RTK solution is the
+-- differential GPS solution, which can use either a fixed/integer or floating
+-- carrier phase ambiguity. The pseudo-absolute position solution uses a user-
+-- provided, well-surveyed base station position (if available) and the RTK
+-- solution in tandem.
+
 module SwiftNav.SBP.Navigation where
 
 import Control.Monad
@@ -14,11 +32,27 @@
 msgGpsTime :: Word16
 msgGpsTime = 0x0100
 
+-- | SBP class for message MSG_GPS_TIME (0x0100).
+--
+-- This message reports the GPS time, representing the time since the GPS epoch
+-- began on midnight January 6, 1980 UTC. GPS time counts the weeks and seconds
+-- of the week. The weeks begin at the Saturday/Sunday transition. GPS week 0
+-- began at the beginning of the GPS time scale.  Within each week number, the
+-- GPS time of the week is between between 0 and 604800 seconds (=60*60*24*7).
+-- Note that GPS time does not accumulate leap seconds, and as of now, has a
+-- small offset from UTC. In a message stream, this message precedes a set of
+-- other navigation messages referenced to the same time (but lacking the ns
+-- field) and indicates a more precise time of these messages.
 data MsgGpsTime = MsgGpsTime
   { msgGpsTimeWn    :: Word16
+    -- ^ GPS week number
   , msgGpsTimeTow   :: Word32
+    -- ^ GPS time of week rounded to the nearest millisecond
   , msgGpsTimeNs    :: Int32
+    -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
+    -- 500000)
   , msgGpsTimeFlags :: Word8
+    -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgGpsTime where
@@ -38,13 +72,23 @@
 msgDops :: Word16
 msgDops = 0x0206
 
+-- | SBP class for message MSG_DOPS (0x0206).
+--
+-- This dilution of precision (DOP) message describes the effect of navigation
+-- satellite geometry on positional measurement precision.
 data MsgDops = MsgDops
   { msgDopsTow  :: Word32
+    -- ^ GPS Time of Week
   , msgDopsGdop :: Word16
+    -- ^ Geometric Dilution of Precision
   , msgDopsPdop :: Word16
+    -- ^ Position Dilution of Precision
   , msgDopsTdop :: Word16
+    -- ^ Time Dilution of Precision
   , msgDopsHdop :: Word16
+    -- ^ Horizontal Dilution of Precision
   , msgDopsVdop :: Word16
+    -- ^ Vertical Dilution of Precision
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgDops where
@@ -68,14 +112,30 @@
 msgPosEcef :: Word16
 msgPosEcef = 0x0200
 
+-- | SBP class for message MSG_POS_ECEF (0x0200).
+--
+-- The position solution message reports absolute Earth Centered Earth Fixed
+-- (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of
+-- the position solution. If the rover receiver knows the surveyed position of
+-- the base station and has an RTK solution, this reports a pseudo-absolute
+-- position solution using the base station position and the rover's RTK
+-- baseline vector. The full GPS time is given by the preceding MSG_GPS_TIME
+-- with the matching time-of-week (tow).
 data MsgPosEcef = MsgPosEcef
   { msgPosEcefTow      :: Word32
+    -- ^ GPS Time of Week
   , msgPosEcefX        :: Double
+    -- ^ ECEF X coordinate
   , msgPosEcefY        :: Double
+    -- ^ ECEF Y coordinate
   , msgPosEcefZ        :: Double
+    -- ^ ECEF Z coordinate
   , msgPosEcefAccuracy :: Word16
+    -- ^ Position accuracy estimate (not implemented). Defaults to 0.
   , msgPosEcefNSats    :: Word8
+    -- ^ Number of satellites used in solution
   , msgPosEcefFlags    :: Word8
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgPosEcef where
@@ -101,15 +161,32 @@
 msgPosLlh :: Word16
 msgPosLlh = 0x0201
 
+-- | SBP class for message MSG_POS_LLH (0x0201).
+--
+-- This position solution message reports the absolute geodetic coordinates and
+-- the status (single point vs pseudo-absolute RTK) of the position solution.
+-- If the rover receiver knows the surveyed position of the base station and
+-- has an RTK solution, this reports a pseudo-absolute position solution using
+-- the base station position and the rover's RTK baseline vector. The full GPS
+-- time is given by the preceding MSG_GPS_TIME with the matching time-of-week
+-- (tow).
 data MsgPosLlh = MsgPosLlh
   { msgPosLlhTow        :: Word32
+    -- ^ GPS Time of Week
   , msgPosLlhLat        :: Double
+    -- ^ Latitude
   , msgPosLlhLon        :: Double
+    -- ^ Longitude
   , msgPosLlhHeight     :: Double
+    -- ^ Height
   , msgPosLlhHAccuracy  :: Word16
+    -- ^ Horizontal position accuracy estimate (not implemented). Defaults to 0.
   , msgPosLlhVAccuracy  :: Word16
+    -- ^ Vertical position accuracy estimate (not implemented). Defaults to 0.
   , msgPosLlhNSats      :: Word8
+    -- ^ Number of satellites used in solution.
   , msgPosLlhFlags      :: Word8
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgPosLlh where
@@ -137,14 +214,27 @@
 msgBaselineEcef :: Word16
 msgBaselineEcef = 0x0202
 
+-- | SBP class for message MSG_BASELINE_ECEF (0x0202).
+--
+-- This message reports the baseline solution in Earth Centered Earth Fixed
+-- (ECEF) coordinates. This baseline is the relative vector distance from the
+-- base station to the rover receiver. The full GPS time is given by the
+-- preceding MSG_GPS_TIME with the matching time-of-week (tow).
 data MsgBaselineEcef = MsgBaselineEcef
   { msgBaselineEcefTow      :: Word32
+    -- ^ GPS Time of Week
   , msgBaselineEcefX        :: Int32
+    -- ^ Baseline ECEF X coordinate
   , msgBaselineEcefY        :: Int32
+    -- ^ Baseline ECEF Y coordinate
   , msgBaselineEcefZ        :: Int32
+    -- ^ Baseline ECEF Z coordinate
   , msgBaselineEcefAccuracy :: Word16
+    -- ^ Position accuracy estimate (not implemented). Defaults to 0.
   , msgBaselineEcefNSats    :: Word8
+    -- ^ Number of satellites used in solution
   , msgBaselineEcefFlags    :: Word8
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgBaselineEcef where
@@ -170,15 +260,31 @@
 msgBaselineNed :: Word16
 msgBaselineNed = 0x0203
 
+-- | SBP class for message MSG_BASELINE_NED (0x0203).
+--
+-- This message reports the baseline solution in North East Down (NED)
+-- coordinates. This baseline is the relative vector distance from the base
+-- station to the rover receiver, and NED coordinate system is defined at the
+-- local tangent plane centered at the base station position.  The full GPS
+-- time is given by the preceding MSG_GPS_TIME with the matching time-of-week
+-- (tow).
 data MsgBaselineNed = MsgBaselineNed
   { msgBaselineNedTow        :: Word32
+    -- ^ GPS Time of Week
   , msgBaselineNedN          :: Int32
+    -- ^ Baseline North coordinate
   , msgBaselineNedE          :: Int32
+    -- ^ Baseline East coordinate
   , msgBaselineNedD          :: Int32
+    -- ^ Baseline Down coordinate
   , msgBaselineNedHAccuracy  :: Word16
+    -- ^ Horizontal position accuracy estimate (not implemented). Defaults to 0.
   , msgBaselineNedVAccuracy  :: Word16
+    -- ^ Vertical position accuracy estimate (not implemented). Defaults to 0.
   , msgBaselineNedNSats      :: Word8
+    -- ^ Number of satellites used in solution
   , msgBaselineNedFlags      :: Word8
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgBaselineNed where
@@ -206,14 +312,26 @@
 msgVelEcef :: Word16
 msgVelEcef = 0x0204
 
+-- | SBP class for message MSG_VEL_ECEF (0x0204).
+--
+-- This message reports the velocity in Earth Centered Earth Fixed (ECEF)
+-- coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with
+-- the matching time-of-week (tow).
 data MsgVelEcef = MsgVelEcef
   { msgVelEcefTow      :: Word32
+    -- ^ GPS Time of Week
   , msgVelEcefX        :: Int32
+    -- ^ Velocity ECEF X coordinate
   , msgVelEcefY        :: Int32
+    -- ^ Velocity ECEF Y coordinate
   , msgVelEcefZ        :: Int32
+    -- ^ Velocity ECEF Z coordinate
   , msgVelEcefAccuracy :: Word16
+    -- ^ Velocity accuracy estimate (not implemented). Defaults to 0.
   , msgVelEcefNSats    :: Word8
+    -- ^ Number of satellites used in solution
   , msgVelEcefFlags    :: Word8
+    -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgVelEcef where
@@ -239,15 +357,28 @@
 msgVelNed :: Word16
 msgVelNed = 0x0205
 
+-- | SBP class for message MSG_VEL_NED (0x0205).
+--
+-- This message reports the velocity in local North East Down (NED)
+-- coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with
+-- the matching time-of-week (tow).
 data MsgVelNed = MsgVelNed
   { msgVelNedTow        :: Word32
+    -- ^ GPS Time of Week
   , msgVelNedN          :: Int32
+    -- ^ Velocity North coordinate
   , msgVelNedE          :: Int32
+    -- ^ Velocity East coordinate
   , msgVelNedD          :: Int32
+    -- ^ Velocity Down coordinate
   , msgVelNedHAccuracy  :: Word16
+    -- ^ Horizontal velocity accuracy estimate (not implemented). Defaults to 0.
   , msgVelNedVAccuracy  :: Word16
+    -- ^ Vertical velocity accuracy estimate (not implemented). Defaults to 0.
   , msgVelNedNSats      :: Word8
+    -- ^ Number of satellites used in solution
   , msgVelNedFlags      :: Word8
+    -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgVelNed where
diff --git a/src/SwiftNav/SBP/Observation.hs b/src/SwiftNav/SBP/Observation.hs
--- a/src/SwiftNav/SBP/Observation.hs
+++ b/src/SwiftNav/SBP/Observation.hs
@@ -1,3 +1,13 @@
+-- |
+-- Module:      SwiftNav.SBP.Observation
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Satellite observation messages from the device.
+
 module SwiftNav.SBP.Observation where
 
 import Control.Monad
@@ -11,9 +21,15 @@
 import Data.Int
 import Data.Word
 
+-- | ObsGPSTime.
+--
+-- A wire-appropriate GPS time, defined as the number of milliseconds since
+-- beginning of the week on the Saturday/Sunday transition.
 data ObsGPSTime = ObsGPSTime
   { obsGPSTimeTow :: Word32
+    -- ^ Milliseconds since start of GPS week
   , obsGPSTimeWn  :: Word16
+    -- ^ GPS week number
   } deriving ( Show, Read, Eq )
 
 instance Binary ObsGPSTime where
@@ -26,9 +42,16 @@
     putWord32le obsGPSTimeTow
     putWord16le obsGPSTimeWn
 
+-- | CarrierPhase.
+--
+-- Carrier phase measurement in cycles represented as a 40-bit fixed point
+-- number with Q32.8 layout, i.e. 32-bits of whole cycles and 8-bits of
+-- fractional cycles.
 data CarrierPhase = CarrierPhase
   { carrierPhaseI :: Int32
+    -- ^ Carrier phase whole cycles
   , carrierPhaseF :: Word8
+    -- ^ Carrier phase fractional part
   } deriving ( Show, Read, Eq )
 
 instance Binary CarrierPhase where
@@ -41,9 +64,15 @@
     putWord32le $ fromIntegral carrierPhaseI
     putWord8 carrierPhaseF
 
+-- | ObservationHeader.
+--
+-- Header of a GPS observation message.
 data ObservationHeader = ObservationHeader
   { observationHeaderT     :: ObsGPSTime
+    -- ^ GPS time of this observation
   , observationHeaderNObs  :: Word8
+    -- ^ Total number of observations. First nibble is the size of the sequence
+    -- (n), second nibble is the zero-indexed counter (ith packet of n)
   } deriving ( Show, Read, Eq )
 
 instance Binary ObservationHeader where
@@ -56,12 +85,24 @@
     put observationHeaderT
     putWord8 observationHeaderNObs
 
+-- | PackedObsContent.
+--
+-- Pseudorange and carrier phase observation for a satellite being tracked.
 data PackedObsContent = PackedObsContent
   { packedObsContentP    :: Word32
+    -- ^ Pseudorange observation
   , packedObsContentL    :: CarrierPhase
+    -- ^ Carrier phase observation
   , packedObsContentCn0  :: Word8
+    -- ^ Carrier-to-Noise density
   , packedObsContentLock :: Word16
+    -- ^ Lock indicator. This value changes whenever a satellite signal has lost
+    -- and regained lock, indicating that the carrier phase ambiguity may have
+    -- changed.
   , packedObsContentSid  :: Word32
+    -- ^ Signal identifier of the satellite signal - values 0x00 through 0x1F
+    -- represent GPS PRNs 1 through 32 respectively (PRN-1 notation); other
+    -- values reserved for future use.
   } deriving ( Show, Read, Eq )
 
 instance Binary PackedObsContent where
@@ -83,9 +124,17 @@
 msgObs :: Word16
 msgObs = 0x0043
 
+-- | SBP class for message MSG_OBS (0x0043).
+--
+-- The GPS observations message reports all the raw pseudorange and carrier
+-- phase observations for the satellites being tracked by the device. Carrier
+-- phase observation here is represented as a 40-bit fixed point number with
+-- Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional cycles).
 data MsgObs = MsgObs
   { msgObsHeader :: ObservationHeader
+    -- ^ Header of a GPS observation message
   , msgObsObs    :: [PackedObsContent]
+    -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgObs where
@@ -101,10 +150,19 @@
 msgBasePos :: Word16
 msgBasePos = 0x0044
 
+-- | SBP class for message MSG_BASE_POS (0x0044).
+--
+-- The base station position message is the position reported by the base
+-- station itself. It is used for pseudo-absolute RTK positioning, and is
+-- required to be a high-accuracy surveyed location of the base station. Any
+-- error here will result in an error in the pseudo-absolute position output.
 data MsgBasePos = MsgBasePos
   { msgBasePosLat    :: Double
+    -- ^ Latitude
   , msgBasePosLon    :: Double
+    -- ^ Longitude
   , msgBasePosHeight :: Double
+    -- ^ Height
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgBasePos where
@@ -122,36 +180,77 @@
 msgEphemeris :: Word16
 msgEphemeris = 0x0047
 
+-- | SBP class for message MSG_EPHEMERIS (0x0047).
+--
+-- The ephemeris message returns a set of satellite orbit parameters that is
+-- used to calculate GPS satellite position, velocity, and clock offset. Please
+-- see the Navstar GPS Space Segment/Navigation user interfaces (ICD-GPS-200,
+-- Table 20-III) for more details.
 data MsgEphemeris = MsgEphemeris
   { msgEphemerisTgd      :: Double
+    -- ^ Group delay differential between L1 and L2
   , msgEphemerisCRs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the orbit radius
   , msgEphemerisCRc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
   , msgEphemerisCUc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the argument of
+    -- latitude
   , msgEphemerisCUs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the argument of
+    -- latitude
   , msgEphemerisCIc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the angle of
+    -- inclination
   , msgEphemerisCIs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the angle of
+    -- inclination
   , msgEphemerisDn       :: Double
+    -- ^ Mean motion difference
   , msgEphemerisM0       :: Double
+    -- ^ Mean anomaly at reference time
   , msgEphemerisEcc      :: Double
+    -- ^ Eccentricity of satellite orbit
   , msgEphemerisSqrta    :: Double
+    -- ^ Square root of the semi-major axis of orbit
   , msgEphemerisOmega0   :: Double
+    -- ^ Longitude of ascending node of orbit plane at weekly epoch
   , msgEphemerisOmegadot :: Double
+    -- ^ Rate of right ascension
   , msgEphemerisW        :: Double
+    -- ^ Argument of perigee
   , msgEphemerisInc      :: Double
+    -- ^ Inclination
   , msgEphemerisIncDot   :: Double
+    -- ^ Inclination first derivative
   , msgEphemerisAf0      :: Double
+    -- ^ Polynomial clock correction coefficient (clock bias)
   , msgEphemerisAf1      :: Double
+    -- ^ Polynomial clock correction coefficient (clock drift)
   , msgEphemerisAf2      :: Double
+    -- ^ Polynomial clock correction coefficient (rate of clock drift)
   , msgEphemerisToeTow   :: Double
+    -- ^ Time of week
   , msgEphemerisToeWn    :: Word16
+    -- ^ Week number
   , msgEphemerisTocTow   :: Double
+    -- ^ Clock reference time of week
   , msgEphemerisTocWn    :: Word16
+    -- ^ Clock reference week number
   , msgEphemerisValid    :: Word8
+    -- ^ Is valid?
   , msgEphemerisHealthy  :: Word8
+    -- ^ Satellite is healthy?
   , msgEphemerisSid      :: Word32
+    -- ^ Signal identifier being tracked - values 0x00 through 0x1F represent GPS
+    -- PRNs 1 through 32 respectively (PRN-1 notation); other values reserved
+    -- for future use
   , msgEphemerisIode     :: Word8
+    -- ^ Issue of ephemeris data
   , msgEphemerisIodc     :: Word16
+    -- ^ Issue of clock data
   , msgEphemerisReserved :: Word32
+    -- ^ Reserved field
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgEphemeris where
@@ -221,33 +320,66 @@
 msgEphemerisDepA :: Word16
 msgEphemerisDepA = 0x001A
 
+-- | SBP class for message MSG_EPHEMERIS_DEP_A (0x001A).
+--
+-- Deprecated.
 data MsgEphemerisDepA = MsgEphemerisDepA
   { msgEphemerisDepATgd      :: Double
+    -- ^ Group delay differential between L1 and L2
   , msgEphemerisDepACRs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the orbit radius
   , msgEphemerisDepACRc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
   , msgEphemerisDepACUc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the argument of
+    -- latitude
   , msgEphemerisDepACUs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the argument of
+    -- latitude
   , msgEphemerisDepACIc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the angle of
+    -- inclination
   , msgEphemerisDepACIs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the angle of
+    -- inclination
   , msgEphemerisDepADn       :: Double
+    -- ^ Mean motion difference
   , msgEphemerisDepAM0       :: Double
+    -- ^ Mean anomaly at reference time
   , msgEphemerisDepAEcc      :: Double
+    -- ^ Eccentricity of satellite orbit
   , msgEphemerisDepASqrta    :: Double
+    -- ^ Square root of the semi-major axis of orbit
   , msgEphemerisDepAOmega0   :: Double
+    -- ^ Longitude of ascending node of orbit plane at weekly epoch
   , msgEphemerisDepAOmegadot :: Double
+    -- ^ Rate of right ascension
   , msgEphemerisDepAW        :: Double
+    -- ^ Argument of perigee
   , msgEphemerisDepAInc      :: Double
+    -- ^ Inclination
   , msgEphemerisDepAIncDot   :: Double
+    -- ^ Inclination first derivative
   , msgEphemerisDepAAf0      :: Double
+    -- ^ Polynomial clock correction coefficient (clock bias)
   , msgEphemerisDepAAf1      :: Double
+    -- ^ Polynomial clock correction coefficient (clock drift)
   , msgEphemerisDepAAf2      :: Double
+    -- ^ Polynomial clock correction coefficient (rate of clock drift)
   , msgEphemerisDepAToeTow   :: Double
+    -- ^ Time of week
   , msgEphemerisDepAToeWn    :: Word16
+    -- ^ Week number
   , msgEphemerisDepATocTow   :: Double
+    -- ^ Clock reference time of week
   , msgEphemerisDepATocWn    :: Word16
+    -- ^ Clock reference week number
   , msgEphemerisDepAValid    :: Word8
+    -- ^ Is valid?
   , msgEphemerisDepAHealthy  :: Word8
+    -- ^ Satellite is healthy?
   , msgEphemerisDepAPrn      :: Word8
+    -- ^ PRN being tracked
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgEphemerisDepA where
@@ -311,34 +443,68 @@
 msgEphemerisDepB :: Word16
 msgEphemerisDepB = 0x0046
 
+-- | SBP class for message MSG_EPHEMERIS_DEP_B (0x0046).
+--
+-- Deprecated.
 data MsgEphemerisDepB = MsgEphemerisDepB
   { msgEphemerisDepBTgd      :: Double
+    -- ^ Group delay differential between L1 and L2
   , msgEphemerisDepBCRs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the orbit radius
   , msgEphemerisDepBCRc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
   , msgEphemerisDepBCUc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the argument of
+    -- latitude
   , msgEphemerisDepBCUs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the argument of
+    -- latitude
   , msgEphemerisDepBCIc      :: Double
+    -- ^ Amplitude of the cosine harmonic correction term to the angle of
+    -- inclination
   , msgEphemerisDepBCIs      :: Double
+    -- ^ Amplitude of the sine harmonic correction term to the angle of
+    -- inclination
   , msgEphemerisDepBDn       :: Double
+    -- ^ Mean motion difference
   , msgEphemerisDepBM0       :: Double
+    -- ^ Mean anomaly at reference time
   , msgEphemerisDepBEcc      :: Double
+    -- ^ Eccentricity of satellite orbit
   , msgEphemerisDepBSqrta    :: Double
+    -- ^ Square root of the semi-major axis of orbit
   , msgEphemerisDepBOmega0   :: Double
+    -- ^ Longitude of ascending node of orbit plane at weekly epoch
   , msgEphemerisDepBOmegadot :: Double
+    -- ^ Rate of right ascension
   , msgEphemerisDepBW        :: Double
+    -- ^ Argument of perigee
   , msgEphemerisDepBInc      :: Double
+    -- ^ Inclination
   , msgEphemerisDepBIncDot   :: Double
+    -- ^ Inclination first derivative
   , msgEphemerisDepBAf0      :: Double
+    -- ^ Polynomial clock correction coefficient (clock bias)
   , msgEphemerisDepBAf1      :: Double
+    -- ^ Polynomial clock correction coefficient (clock drift)
   , msgEphemerisDepBAf2      :: Double
+    -- ^ Polynomial clock correction coefficient (rate of clock drift)
   , msgEphemerisDepBToeTow   :: Double
+    -- ^ Time of week
   , msgEphemerisDepBToeWn    :: Word16
+    -- ^ Week number
   , msgEphemerisDepBTocTow   :: Double
+    -- ^ Clock reference time of week
   , msgEphemerisDepBTocWn    :: Word16
+    -- ^ Clock reference week number
   , msgEphemerisDepBValid    :: Word8
+    -- ^ Is valid?
   , msgEphemerisDepBHealthy  :: Word8
+    -- ^ Satellite is healthy?
   , msgEphemerisDepBPrn      :: Word8
+    -- ^ PRN being tracked
   , msgEphemerisDepBIode     :: Word8
+    -- ^ Issue of ephemeris data
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgEphemerisDepB where
@@ -401,12 +567,22 @@
     putWord8 msgEphemerisDepBPrn
     putWord8 msgEphemerisDepBIode
 
+-- | PackedObsContentDepA.
+--
+-- Deprecated.
 data PackedObsContentDepA = PackedObsContentDepA
   { packedObsContentDepAP    :: Word32
+    -- ^ Pseudorange observation
   , packedObsContentDepAL    :: CarrierPhase
+    -- ^ Carrier phase observation
   , packedObsContentDepACn0  :: Word8
+    -- ^ Carrier-to-Noise density
   , packedObsContentDepALock :: Word16
+    -- ^ Lock indicator. This value changes whenever a satellite signal has lost
+    -- and regained lock, indicating that the carrier phase ambiguity may have
+    -- changed.
   , packedObsContentDepAPrn  :: Word8
+    -- ^ PRN-1 identifier of the satellite signal
   } deriving ( Show, Read, Eq )
 
 instance Binary PackedObsContentDepA where
@@ -428,9 +604,14 @@
 msgObsDepA :: Word16
 msgObsDepA = 0x0045
 
+-- | SBP class for message MSG_OBS_DEP_A (0x0045).
+--
+-- Deprecated.
 data MsgObsDepA = MsgObsDepA
   { msgObsDepAHeader :: ObservationHeader
+    -- ^ Header of a GPS observation message
   , msgObsDepAObs    :: [PackedObsContentDepA]
+    -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgObsDepA where
diff --git a/src/SwiftNav/SBP/Piksi.hs b/src/SwiftNav/SBP/Piksi.hs
--- a/src/SwiftNav/SBP/Piksi.hs
+++ b/src/SwiftNav/SBP/Piksi.hs
@@ -1,3 +1,16 @@
+-- |
+-- Module:      SwiftNav.SBP.Piksi
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- System health, configuration, and diagnostic messages specific to the Piksi
+-- L1 receiver, including a variety of legacy messages that may no longer be
+-- used.  These messages are in the implementation-defined range
+-- (0x0000-0x00FF), and largely intended for internal-use only.
+
 module SwiftNav.SBP.Piksi where
 
 import Control.Monad
@@ -14,6 +27,10 @@
 msgAlmanac :: Word16
 msgAlmanac = 0x0069
 
+-- | SBP class for message MSG_ALMANAC (0x0069).
+--
+-- This is a legacy message for sending and loading a satellite alamanac onto
+-- the Piksi's flash memory from the host.
 data MsgAlmanac = MsgAlmanac
   deriving ( Show, Read, Eq )
 
@@ -27,6 +44,10 @@
 msgSetTime :: Word16
 msgSetTime = 0x0068
 
+-- | SBP class for message MSG_SET_TIME (0x0068).
+--
+-- This message sets up timing functionality using a coarse GPS time estimate
+-- sent by the host.
 data MsgSetTime = MsgSetTime
   deriving ( Show, Read, Eq )
 
@@ -40,6 +61,9 @@
 msgReset :: Word16
 msgReset = 0x00B2
 
+-- | SBP class for message MSG_RESET (0x00B2).
+--
+-- This message from the host resets the Piksi back into the bootloader.
 data MsgReset = MsgReset
   deriving ( Show, Read, Eq )
 
@@ -53,6 +77,11 @@
 msgCwResults :: Word16
 msgCwResults = 0x00C0
 
+-- | SBP class for message MSG_CW_RESULTS (0x00C0).
+--
+-- This is an unused legacy message for result reporting from the CW
+-- interference channel on the SwiftNAP. This message will be removed in a
+-- future release.
 data MsgCwResults = MsgCwResults
   deriving ( Show, Read, Eq )
 
@@ -66,6 +95,11 @@
 msgCwStart :: Word16
 msgCwStart = 0x00C1
 
+-- | SBP class for message MSG_CW_START (0x00C1).
+--
+-- This is an unused legacy message from those host for starting the CW
+-- interference channel on the SwiftNAP. This message will be removed in a
+-- future release.
 data MsgCwStart = MsgCwStart
   deriving ( Show, Read, Eq )
 
@@ -79,8 +113,13 @@
 msgResetFilters :: Word16
 msgResetFilters = 0x0022
 
+-- | SBP class for message MSG_RESET_FILTERS (0x0022).
+--
+-- This message resets either the DGNSS Kalman filters or Integer Ambiguity
+-- Resolution (IAR) process.
 data MsgResetFilters = MsgResetFilters
   { msgResetFiltersFilter :: Word8
+    -- ^ Filter flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgResetFilters where
@@ -94,6 +133,12 @@
 msgInitBase :: Word16
 msgInitBase = 0x0023
 
+-- | SBP class for message MSG_INIT_BASE (0x0023).
+--
+-- This message initializes the integer ambiguity resolution (IAR) process on
+-- the Piksi to use an assumed baseline position between the base station and
+-- rover receivers. Warns via MSG_PRINT if there aren't a shared minimum number
+-- (4) of satellite observations between the two.
 data MsgInitBase = MsgInitBase
   deriving ( Show, Read, Eq )
 
@@ -107,10 +152,19 @@
 msgThreadState :: Word16
 msgThreadState = 0x0017
 
+-- | SBP class for message MSG_THREAD_STATE (0x0017).
+--
+-- The thread usage message from the device reports real-time operating system
+-- (RTOS) thread usage statistics for the named thread. The reported percentage
+-- values require to be normalized.
 data MsgThreadState = MsgThreadState
   { msgThreadStateName       :: ByteString
+    -- ^ Thread name (NULL terminated)
   , msgThreadStateCpu        :: Word16
+    -- ^ Percentage cpu use for this thread. Values range from 0 - 1000 and needs
+    -- to be renormalized to 100
   , msgThreadStateStackFree  :: Word32
+    -- ^ Free stack space for this thread
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgThreadState where
@@ -125,13 +179,23 @@
     putWord16le msgThreadStateCpu
     putWord32le msgThreadStateStackFree
 
+-- | UARTChannel.
+--
+-- Throughput, utilization, and error counts on the RX/TX buffers of this UART
+-- channel. The reported percentage values require to be normalized.
 data UARTChannel = UARTChannel
   { uARTChannelTxThroughput    :: Float
+    -- ^ UART transmit throughput
   , uARTChannelRxThroughput    :: Float
+    -- ^ UART receive throughput
   , uARTChannelCrcErrorCount   :: Word16
+    -- ^ UART CRC error count
   , uARTChannelIoErrorCount    :: Word16
+    -- ^ UART IO error count
   , uARTChannelTxBufferLevel   :: Word8
+    -- ^ UART transmit buffer percentage utilization (ranges from 0 - 255)
   , uARTChannelRxBufferLevel   :: Word8
+    -- ^ UART receive buffer percentage utilization (ranges from 0 to 255)
   } deriving ( Show, Read, Eq )
 
 instance Binary UARTChannel where
@@ -152,11 +216,21 @@
     putWord8 uARTChannelTxBufferLevel
     putWord8 uARTChannelRxBufferLevel
 
+-- | Latency.
+--
+-- Statistics on the latency of observations received from the base station. As
+-- observation packets are received their GPS time is compared to the current
+-- GPS time calculated locally by the receiver to give a precise measurement of
+-- the end-to-end communication latency in the system.
 data Latency = Latency
   { latencyAvg     :: Int32
+    -- ^ Average latency
   , latencyLmin    :: Int32
+    -- ^ Minimum latency
   , latencyLmax    :: Int32
+    -- ^ Maximum latency
   , latencyCurrent :: Int32
+    -- ^ Smoothed estimate of the current latency
   } deriving ( Show, Read, Eq )
 
 instance Binary Latency where
@@ -176,11 +250,22 @@
 msgUartState :: Word16
 msgUartState = 0x0018
 
+-- | SBP class for message MSG_UART_STATE (0x0018).
+--
+-- The UART message reports data latency and throughput of the UART channels
+-- providing SBP I/O. On the default Piksi configuration, UARTs A and B are
+-- used for telemetry radios, but can also be host access ports for embedded
+-- hosts, or other interfaces in future. The reported percentage values require
+-- to be normalized.
 data MsgUartState = MsgUartState
   { msgUartStateUartA     :: UARTChannel
+    -- ^ State of UART A
   , msgUartStateUartB     :: UARTChannel
+    -- ^ State of UART B
   , msgUartStateUartFtdi  :: UARTChannel
+    -- ^ State of UART FTDI (USB logger)
   , msgUartStateLatency   :: Latency
+    -- ^ UART communication latency
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgUartState where
@@ -200,8 +285,14 @@
 msgIarState :: Word16
 msgIarState = 0x0019
 
+-- | SBP class for message MSG_IAR_STATE (0x0019).
+--
+-- This message reports the state of the Integer Ambiguity Resolution (IAR)
+-- process, which resolves unknown integer ambiguities from double-differenced
+-- carrier-phase measurements from satellite observations.
 data MsgIarState = MsgIarState
   { msgIarStateNumHyps  :: Word32
+    -- ^ Number of integer ambiguity hypotheses remaining
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgIarState where
@@ -215,9 +306,15 @@
 msgMaskSatellite :: Word16
 msgMaskSatellite = 0x001B
 
+-- | SBP class for message MSG_MASK_SATELLITE (0x001B).
+--
+-- This message allows setting a mask to prevent a particular satellite from
+-- being used in various Piksi subsystems.
 data MsgMaskSatellite = MsgMaskSatellite
   { msgMaskSatelliteMask :: Word8
+    -- ^ Mask of systems that should ignore this satellite.
   , msgMaskSatelliteSid  :: Word32
+    -- ^ Signal identifier for which the mask is applied
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgMaskSatellite where
diff --git a/src/SwiftNav/SBP/Settings.hs b/src/SwiftNav/SBP/Settings.hs
--- a/src/SwiftNav/SBP/Settings.hs
+++ b/src/SwiftNav/SBP/Settings.hs
@@ -1,3 +1,18 @@
+-- |
+-- Module:      SwiftNav.SBP.Settings
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Messages for reading and writing the device's device settings.  These are in
+-- the implementation-defined range (0x0000-0x00FF). Note that some of these
+-- messages share the same message type ID for both the host request and the
+-- device response. See the accompanying document for descriptions of settings
+-- configurations and examples: https://github.com/swift-
+-- nav/piksi\_firmware/blob/master/docs/settings.pdf
+
 module SwiftNav.SBP.Settings where
 
 import Control.Monad
@@ -14,6 +29,10 @@
 msgSettingsSave :: Word16
 msgSettingsSave = 0x00A1
 
+-- | SBP class for message MSG_SETTINGS_SAVE (0x00A1).
+--
+-- The save settings message persists the device's current settings
+-- configuration to its onboard flash memory file system.
 data MsgSettingsSave = MsgSettingsSave
   deriving ( Show, Read, Eq )
 
@@ -27,8 +46,13 @@
 msgSettingsWrite :: Word16
 msgSettingsWrite = 0x00A0
 
+-- | SBP class for message MSG_SETTINGS_WRITE (0x00A0).
+--
+-- The setting message writes the device's configuration.
 data MsgSettingsWrite = MsgSettingsWrite
   { msgSettingsWriteSetting :: ByteString
+    -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
+    -- SETTING, VALUE].
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgSettingsWrite where
@@ -42,8 +66,13 @@
 msgSettingsReadReq :: Word16
 msgSettingsReadReq = 0x00A4
 
+-- | SBP class for message MSG_SETTINGS_READ_REQ (0x00A4).
+--
+-- The setting message reads the device's configuration.
 data MsgSettingsReadReq = MsgSettingsReadReq
   { msgSettingsReadReqSetting :: ByteString
+    -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
+    -- SETTING].
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgSettingsReadReq where
@@ -57,8 +86,13 @@
 msgSettingsReadResp :: Word16
 msgSettingsReadResp = 0x00A5
 
+-- | SBP class for message MSG_SETTINGS_READ_RESP (0x00A5).
+--
+-- The setting message reads the device's configuration.
 data MsgSettingsReadResp = MsgSettingsReadResp
   { msgSettingsReadRespSetting :: ByteString
+    -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
+    -- SETTING, VALUE].
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgSettingsReadResp where
@@ -72,8 +106,15 @@
 msgSettingsReadByIndexReq :: Word16
 msgSettingsReadByIndexReq = 0x00A2
 
+-- | SBP class for message MSG_SETTINGS_READ_BY_INDEX_REQ (0x00A2).
+--
+-- The settings message for iterating through the settings values. It will read
+-- the setting at an index, returning a NULL-terminated and delimited string
+-- with contents [SECTION_SETTING, SETTING, VALUE].
 data MsgSettingsReadByIndexReq = MsgSettingsReadByIndexReq
   { msgSettingsReadByIndexReqIndex :: Word16
+    -- ^ An index into the device settings, with values ranging from 0 to
+    -- length(settings)
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgSettingsReadByIndexReq where
@@ -87,9 +128,18 @@
 msgSettingsReadByIndexResp :: Word16
 msgSettingsReadByIndexResp = 0x00A7
 
+-- | SBP class for message MSG_SETTINGS_READ_BY_INDEX_RESP (0x00A7).
+--
+-- The settings message for iterating through the settings values. It will read
+-- the setting at an index, returning a NULL-terminated and delimited string
+-- with contents [SECTION_SETTING, SETTING, VALUE].
 data MsgSettingsReadByIndexResp = MsgSettingsReadByIndexResp
   { msgSettingsReadByIndexRespIndex   :: Word16
+    -- ^ An index into the device settings, with values ranging from 0 to
+    -- length(settings)
   , msgSettingsReadByIndexRespSetting :: ByteString
+    -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
+    -- SETTING, VALUE].
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgSettingsReadByIndexResp where
@@ -105,6 +155,9 @@
 msgSettingsReadByIndexDone :: Word16
 msgSettingsReadByIndexDone = 0x00A6
 
+-- | SBP class for message MSG_SETTINGS_READ_BY_INDEX_DONE (0x00A6).
+--
+-- The settings message for indicating end of the settings values.
 data MsgSettingsReadByIndexDone = MsgSettingsReadByIndexDone
   deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/System.hs b/src/SwiftNav/SBP/System.hs
--- a/src/SwiftNav/SBP/System.hs
+++ b/src/SwiftNav/SBP/System.hs
@@ -1,3 +1,13 @@
+-- |
+-- Module:      SwiftNav.SBP.System
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Standardized system messages from Swift Navigation devices.
+
 module SwiftNav.SBP.System where
 
 import Control.Monad
@@ -14,8 +24,14 @@
 msgStartup :: Word16
 msgStartup = 0xFF00
 
+-- | SBP class for message MSG_STARTUP (0xFF00).
+--
+-- The system start-up message is sent once on system start-up. It notifies the
+-- host or other attached devices that the system has started and is now ready
+-- to respond to commands or configuration requests.
 data MsgStartup = MsgStartup
   { msgStartupReserved :: Word32
+    -- ^ Reserved
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgStartup where
@@ -29,8 +45,18 @@
 msgHeartbeat :: Word16
 msgHeartbeat = 0xFFFF
 
+-- | SBP class for message MSG_HEARTBEAT (0xFFFF).
+--
+-- The heartbeat message is sent periodically to inform the host or other
+-- attached devices that the system is running. It is used to monitor system
+-- malfunctions. It also contains status flags that indicate to the host the
+-- status of the system and whether it is operating correctly. Currently, the
+-- expected heartbeat interval is 1 sec.  The system error flag is used to
+-- indicate that an error has occurred in the system. To determine the source
+-- of the error, the remaining error flags should be inspected.
 data MsgHeartbeat = MsgHeartbeat
   { msgHeartbeatFlags :: Word32
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgHeartbeat where
diff --git a/src/SwiftNav/SBP/Tracking.hs b/src/SwiftNav/SBP/Tracking.hs
--- a/src/SwiftNav/SBP/Tracking.hs
+++ b/src/SwiftNav/SBP/Tracking.hs
@@ -1,3 +1,13 @@
+-- |
+-- Module:      SwiftNav.SBP.Tracking
+-- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
+-- License:     LGPL-3
+-- Maintainer:  Mark Fine <dev@swiftnav.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Satellite code and carrier-phase tracking messages from the device.
+
 module SwiftNav.SBP.Tracking where
 
 import Control.Monad
@@ -11,10 +21,19 @@
 import Data.Int
 import Data.Word
 
+-- | TrackingChannelState.
+--
+-- Tracking channel state for a specific satellite PRN and measured signal
+-- power.
 data TrackingChannelState = TrackingChannelState
   { trackingChannelStateState :: Word8
+    -- ^ Status of tracking channel
   , trackingChannelStateSid   :: Word32
+    -- ^ Signal identifier being tracked - values 0x00 through 0x1F represent GPS
+    -- PRNs 1 through 32 respectively (PRN-1 notation); other values reserved
+    -- for future use
   , trackingChannelStateCn0   :: Float
+    -- ^ Carrier-to-noise density
   } deriving ( Show, Read, Eq )
 
 instance Binary TrackingChannelState where
@@ -32,8 +51,14 @@
 msgTrackingState :: Word16
 msgTrackingState = 0x0013
 
+-- | SBP class for message MSG_TRACKING_STATE (0x0013).
+--
+-- The tracking message returns a variable-length array of tracking channel
+-- states. It reports status and snr power measurements for all tracked
+-- satellites.
 data MsgTrackingState = MsgTrackingState
   { msgTrackingStateStates :: [TrackingChannelState]
+    -- ^ Satellite tracking channel state
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgTrackingState where
@@ -44,9 +69,14 @@
   put MsgTrackingState {..} = do
     mapM_ put msgTrackingStateStates
 
+-- | TrackingChannelCorrelation.
+--
+-- Structure containing in-phase and quadrature correlation components.
 data TrackingChannelCorrelation = TrackingChannelCorrelation
   { trackingChannelCorrelationI :: Int32
+    -- ^ In-phase correlation
   , trackingChannelCorrelationQ :: Int32
+    -- ^ Quadrature correlation
   } deriving ( Show, Read, Eq )
 
 instance Binary TrackingChannelCorrelation where
@@ -62,10 +92,19 @@
 msgTrackingIq :: Word16
 msgTrackingIq = 0x001C
 
+-- | SBP class for message MSG_TRACKING_IQ (0x001C).
+--
+-- When enabled, a tracking channel can output the correlations at each update
+-- interval.
 data MsgTrackingIq = MsgTrackingIq
   { msgTrackingIqChannel :: Word8
+    -- ^ Tracking channel of origin
   , msgTrackingIqSid     :: Word32
+    -- ^ Signal identifier being tracked - values 0x00 through 0x1F represent GPS
+    -- PRNs 1 through 32 respectively (PRN-1 notation); other values reserved
+    -- for future use
   , msgTrackingIqCorrs   :: [TrackingChannelCorrelation]
+    -- ^ Early, Prompt and Late correlations
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgTrackingIq where
@@ -80,10 +119,16 @@
     putWord32le msgTrackingIqSid
     mapM_ put msgTrackingIqCorrs
 
+-- | TrackingChannelStateDepA.
+--
+-- Deprecated.
 data TrackingChannelStateDepA = TrackingChannelStateDepA
   { trackingChannelStateDepAState :: Word8
+    -- ^ Status of tracking channel
   , trackingChannelStateDepAPrn   :: Word8
+    -- ^ PRN-1 being tracked
   , trackingChannelStateDepACn0   :: Float
+    -- ^ Carrier-to-noise density
   } deriving ( Show, Read, Eq )
 
 instance Binary TrackingChannelStateDepA where
@@ -101,8 +146,12 @@
 msgTrackingStateDepA :: Word16
 msgTrackingStateDepA = 0x0016
 
+-- | SBP class for message MSG_TRACKING_STATE_DEP_A (0x0016).
+--
+-- Deprecated.
 data MsgTrackingStateDepA = MsgTrackingStateDepA
   { msgTrackingStateDepAStates :: [TrackingChannelStateDepA]
+    -- ^ Satellite tracking channel state
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgTrackingStateDepA where
