diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+0.5.3 (26/09/2021)
+==================
+* Update package dependency constraints
+    * Win32 >= 2.11 && < 2.14
+* Add documentation and code samples
+
 0.5.2 (30/3/2021)
 =================
 * Update package dependency constraints
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,31 +1,60 @@
+# Serialport
+
 ![Haskell CI](https://github.com/standardsemiconductor/serialport/workflows/Haskell%20CI/badge.svg)
 [![Hackage][hackage-badge]][hackage]
 [![Hackage Dependencies][hackage-deps-badge]][hackage-deps]
 
-Objectives
-==========
-* Cross platform: at least Linux, Windows and Mac OS.
+Cross platform (Linux, Windows and Mac OS) [serial port](https://en.wikipedia.org/wiki/Serial_port) interface.
 
-Tests
-=====
+## Sample Usage
 
-Setup
------
+```haskell
+import System.IO
+import System.Hardware.Serialport
+import qualified Data.ByteString.Char8 as B
+
+let port = "COM3"         -- Windows
+let port = "/dev/ttyUSB0" -- Linux
+withSerial port defaultSerialSettings $ \s -> do
+  send s $ B.pack "AT\r"
+  recv s 10 >>= print
+```
+
+[Concurrently](https://hackage.haskell.org/package/async) read and write a serial port at 19200 [baud](https://learn.sparkfun.com/tutorials/serial-communication/rules-of-serial) using `hWithSerial`:
+```haskell
+import Control.Concurrent.Async ( concurrently_ )
+import Control.Monad            ( forever )
+import System.Hardware.Serialport
+import System.IO
+
+com :: String -> IO ()
+com portPath = hWithSerial portPath serialPortSettings $ \hndl -> do
+  hSetBuffering stdin NoBuffering
+  hSetBuffering stdout NoBuffering
+  concurrently_ (readUart hndl) (writeUart hndl)
+    where
+      readUart  hndl = forever $ putChar =<< hGetChar hndl
+      writeUart hndl = forever $ hPutChar hndl =<< getChar
+
+serialPortSettings :: SerialPortSettings
+serialPortSettings = defaultSerialSettings{ commSpeed = CS19200 }
+```
+
+## Tests
+
+### Setup
 * [Arduino Leonardo](http://arduino.cc/en/Main/arduinoBoardLeonardo) + [Sparkfun FTDI breakout board](https://www.sparkfun.com/products/718).
 * Connections: TX, RX and GND
 
-Prepare Arduino
----------------
+### Prepare Arduino
 * Upload arduino code using Arduino IDE or avrdude
 
-Prepare haskell test program
-----------------------------
-* Configure cabal to build the tests: cabal configure --enable-tests.
-* Build: cabal build
+### Prepare haskell test program
+* Configure cabal to build the tests: `cabal configure --enable-tests`.
+* Build: `cabal build`
 
-Running the tests
------------------
-* Run the tests: cabal test --test-options="/dev/ttyACM0 /dev/ttyUSB0"
+### Running the tests
+* Run the tests: `cabal test --test-options="/dev/ttyACM0 /dev/ttyUSB0"`
 
 [hackage]:            <https://hackage.haskell.org/package/serialport>
 [hackage-badge]:      <https://img.shields.io/hackage/v/serialport.svg?color=success>
diff --git a/System/Hardware/Serialport.hs b/System/Hardware/Serialport.hs
--- a/System/Hardware/Serialport.hs
+++ b/System/Hardware/Serialport.hs
@@ -6,22 +6,19 @@
 -- > import System.Hardware.Serialport
 -- > let port = "COM3"          -- Windows
 -- > let port = "/dev/ttyUSB0"  -- Linux
--- > s <- openSerial port defaultSerialSettings { commSpeed = CS2400 }
--- > send s $ B.pack "AT\r"
--- > recv s 10 >>= print
--- > closeSerial s
+-- > withSerial port defaultSerialSettings{ commSpeed = CS2400 } $ \s -> do
+-- >   send s $ B.pack "AT\r"
+-- >   recv s 10 >>= print
 --
--- Or use the experimental interface with standard handles:
+-- Alternatively, use handles to perform IO:
 --
 -- > import System.IO
 -- > import System.Hardware.Serialport
 -- > let port = "COM3"           -- Windows
 -- > let port = "/dev/ttyUSB0"   -- Linux
--- > h <- hOpenSerial port defaultSerialSettings
--- > hPutStr h "AT\r"
--- > hGetLine h >>= print
--- > hClose h
-
+-- > hWithSerial port defaultSerialSettings $ \h -> do
+-- >   hPutStr h "AT\r"
+-- >   hGetLine h >>= print
 
 module System.Hardware.Serialport (
   -- * Types
diff --git a/System/Hardware/Serialport/Windows.hs b/System/Hardware/Serialport/Windows.hs
--- a/System/Hardware/Serialport/Windows.hs
+++ b/System/Hardware/Serialport/Windows.hs
@@ -101,18 +101,17 @@
                   -> SerialPortSettings   -- ^ The new settings
                   -> IO SerialPort        -- ^ New serial port
 setSerialSettings port new_settings = do
-  let ct = Comm.COMMTIMEOUTS {
-                    Comm.readIntervalTimeout = maxBound :: DWORD,
-                    Comm.readTotalTimeoutMultiplier = maxBound :: DWORD,
-                    Comm.readTotalTimeoutConstant = fromIntegral (timeout new_settings) * 100,
-                    Comm.writeTotalTimeoutMultiplier = 0,
-                    Comm.writeTotalTimeoutConstant = 0 }
-  Comm.setCommTimeouts (handle port) ct
-
+  Comm.setCommTimeouts (handle port) commTimeouts
   Comm.setCommState (handle port) new_settings
-
   return $ SerialPort (handle port) new_settings
-
+  where
+    commTimeouts = Comm.COMMTIMEOUTS
+      { Comm.readIntervalTimeout = maxBound :: DWORD
+      , Comm.readTotalTimeoutMultiplier = maxBound :: DWORD
+      , Comm.readTotalTimeoutConstant = fromIntegral (timeout new_settings) * 100
+      , Comm.writeTotalTimeoutMultiplier = 0
+      , Comm.writeTotalTimeoutConstant = 0 
+      }
 
 -- |Get configuration from serial port
 getSerialSettings :: SerialPort -> SerialPortSettings
diff --git a/serialport.cabal b/serialport.cabal
--- a/serialport.cabal
+++ b/serialport.cabal
@@ -1,5 +1,5 @@
 Name:           serialport
-Version:        0.5.2
+Version:        0.5.3
 Cabal-Version:  >= 1.10
 Build-Type:     Simple
 license:        BSD3
@@ -33,7 +33,7 @@
     Build-Depends:    unix >= 2.7 && < 2.8
     Other-Modules:    System.Hardware.Serialport.Posix
   else
-    Build-Depends:    Win32 >= 2.11 && < 2.13
+    Build-Depends:    Win32 >= 2.11 && < 2.14
     Other-Modules:    System.Hardware.Serialport.Windows
                       System.Win32.Comm
 
