diff --git a/cc3200/mods/modmachine.c b/cc3200/mods/modmachine.c
index 228aff0cf9cc1767b261b493f58655aa4488abdb..ddf80e9ee4b714b8030a2b623c57b07123583f6e 100644
--- a/cc3200/mods/modmachine.c
+++ b/cc3200/mods/modmachine.c
@@ -40,18 +40,13 @@
 #include "rom_map.h"
 #include "prcm.h"
 #include "pyexec.h"
-#include "ff.h"
-#include "diskio.h"
-#include "sflash_diskio.h"
 #include "pybuart.h"
 #include "pybpin.h"
 #include "pybrtc.h"
-#include "mpsystick.h"
 #include "simplelink.h"
 #include "modnetwork.h"
 #include "modwlan.h"
 #include "moduos.h"
-#include "telnet.h"
 #include "FreeRTOS.h"
 #include "portable.h"
 #include "task.h"
@@ -67,7 +62,6 @@
 #include "utils.h"
 #include "gccollect.h"
 #include "mperror.h"
-#include "genhdr/mpversion.h"
 
 
 #ifdef DEBUG
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c
index 6e5287a3673a1377b11e1a0c23a2c064f2103274..351bc638990913b6d3149d3e6e371b71645e06cd 100644
--- a/cc3200/mods/pybuart.c
+++ b/cc3200/mods/pybuart.c
@@ -558,7 +558,7 @@ STATIC mp_obj_t pyb_uart_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
 invalid_args:
     nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_callback_obj, 1, pyb_uart_irq);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
 
 STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
     // instance methods
@@ -566,7 +566,7 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
     { MP_OBJ_NEW_QSTR(MP_QSTR_deinit),      (mp_obj_t)&pyb_uart_deinit_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_any),         (mp_obj_t)&pyb_uart_any_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak),   (mp_obj_t)&pyb_uart_sendbreak_obj },
-    { MP_OBJ_NEW_QSTR(MP_QSTR_irq),         (mp_obj_t)&pyb_uart_callback_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_irq),         (mp_obj_t)&pyb_uart_irq_obj },
 
     /// \method read([nbytes])
     { MP_OBJ_NEW_QSTR(MP_QSTR_read),        (mp_obj_t)&mp_stream_read_obj },
diff --git a/docs/conf.py b/docs/conf.py
index 9f3a25257838b97a342bc09cd4444f376a2876f6..aebf79d40f2c5ce0a7a5f677043fc43bf7157a50 100755
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -300,6 +300,11 @@ html_context = {
 
 # Append the other ports' specific folders/files to the exclude pattern
 exclude_patterns.extend([port + '*' for port in ports if port != micropy_port])
+# Exclude pyb module if the port is the WiPy
+if micropy_port == 'wipy':
+    exclude_patterns.append('library/pyb*')
+else: # exclude machine
+    exclude_patterns.append('library/machine*')
 
 # Specify a custom master document based on the port name
 master_doc = micropy_port + '_' + 'index'
diff --git a/docs/library/index.rst b/docs/library/index.rst
index 9c01d333e5cdc13c4536fa006171246888bd7088..b53a67ed1cf5a6952e2e3c57b29437dd778b1dcb 100644
--- a/docs/library/index.rst
+++ b/docs/library/index.rst
@@ -74,12 +74,12 @@ it will fallback to loading the built-in ``ujson`` module.
 
    Libraries specific to the pyboard
    ---------------------------------
-    
+
    The following libraries are specific to the pyboard.
-    
+
    .. toctree::
       :maxdepth: 2
-    
+
       pyb.rst
       network.rst
 
@@ -87,10 +87,8 @@ it will fallback to loading the built-in ``ujson`` module.
 
    .. toctree::
       :maxdepth: 1
-    
+
       ubinascii.rst
-      uhashlib.rst
-      uheapq.rst
       ujson.rst
       ure.rst
       usocket.rst
@@ -105,7 +103,7 @@ it will fallback to loading the built-in ``ujson`` module.
    .. toctree::
       :maxdepth: 2
 
-      pyb.rst
+      machine.rst
       network.rst
 
 
diff --git a/docs/library/machine.ADC.rst b/docs/library/machine.ADC.rst
new file mode 100644
index 0000000000000000000000000000000000000000..309d070b1b7df15cd7961cd68d6759dbc916b520
--- /dev/null
+++ b/docs/library/machine.ADC.rst
@@ -0,0 +1,73 @@
+.. _machine.ADC:
+
+class ADC -- analog to digital conversion
+=========================================
+
+Usage::
+
+   import machine
+
+   adc = machine.ADC()             # create an ADC object
+   apin = adc.channel(pin='GP3')   # create an analog pin on GP3
+   val = apin()                    # read an analog value
+
+Constructors
+------------
+
+.. class:: machine.ADC(id=0, \*, bits=12)
+
+   Create an ADC object associated with the given pin.
+   This allows you to then read analog values on that pin.
+   For more info check the `pinout and alternate functions
+   table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ 
+
+   .. warning:: 
+
+      ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it 
+      can withstand). When GP2, GP3, GP4 or GP5 are remapped to the 
+      ADC block, 1.8 V is the maximum. If these pins are used in digital mode, 
+      then the maximum allowed input is 3.6V.
+
+Methods
+-------
+
+.. method:: adc.channel(id, \*, pin)
+
+   Create an analog pin. If only channel ID is given, the correct pin will
+   be selected. Alternatively, only the pin can be passed and the correct
+   channel will be selected. Examples::
+
+      # all of these are equivalent and enable ADC channel 1 on GP3
+      apin = adc.channel(1)
+      apin = adc.channel(pin='GP3')
+      apin = adc.channel(id=1, pin='GP3')
+
+.. method:: adc.init()
+
+   Enable the ADC block.
+
+.. method:: adc.deinit()
+
+   Disable the ADC block.
+
+class ADCChannel --- read analog values from internal or external sources
+=========================================================================
+
+ADC channels can be connected to internal points of the MCU or to GPIO pins.
+ADC channels are created using the ADC.channel method.
+
+.. method:: adcchannel()
+
+   Fast method to read the channel value.
+
+.. method:: adcchannel.value()
+
+   Read the channel value.
+
+.. method:: adcchannel.init()
+
+   Re-init (and effectively enable) the ADC channel.
+
+.. method:: adcchannel.deinit()
+
+   Disable the ADC channel.
diff --git a/docs/library/pyb.HeartBeat.rst b/docs/library/machine.HeartBeat.rst
similarity index 76%
rename from docs/library/pyb.HeartBeat.rst
rename to docs/library/machine.HeartBeat.rst
index a50fc8a23ed9ec716ba3a0585ce2b14dc6d0476c..033d7311fbaee69c3725ca8940a81f447a52d381 100644
--- a/docs/library/pyb.HeartBeat.rst
+++ b/docs/library/machine.HeartBeat.rst
@@ -1,4 +1,4 @@
-.. _pyb.HeartBeat:
+.. _machine.HeartBeat:
 
 class HeartBeat -- heart beat LED
 =================================
@@ -11,14 +11,14 @@ can be used to control the light intesity of the heart beat LED.
 
 Example usage::
 
-    hb = pyb.HeartBeat()
+    hb = machine.HeartBeat()
     hb.disable()    # disable the heart beat
     hb.enable()     # enable the heart beat
 
 Constructors
 ------------
 
-.. class:: pyb.HeartBeat()
+.. class:: machine.HeartBeat()
 
    Create a HeartBeat object.
 
@@ -35,12 +35,13 @@ Methods
 
    Example::
    
-      import pyb
+      from machine import HeartBeat
+      from machine import Pin
    
       # disable the heart beat
-      pyb.HeartBeat().disable()
-      # get the GP25 pin object
-      hbl = pyb.Pin('GP25')
+      HeartBeat().disable()
+      # init GP25 as output
+      led = Pin('GP25', mode=Pin.OUT)
       # toggle the led
-      hbl.toggle()
+      led.toggle()
       ...
diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst
new file mode 100644
index 0000000000000000000000000000000000000000..aa1caed2090e57b13f68ef4123de49c0418a13e5
--- /dev/null
+++ b/docs/library/machine.I2C.rst
@@ -0,0 +1,117 @@
+.. _machine.I2C:
+
+class I2C -- a two-wire serial protocol
+=======================================
+
+I2C is a two-wire protocol for communicating between devices.  At the physical
+level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
+
+I2C objects are created attached to a specific bus.  They can be initialised
+when created, or initialised later on.
+
+.. only:: port_wipy
+
+    Example::
+
+        from machine import I2C
+
+        i2c = I2C(0)                         # create on bus 0
+        i2c = I2C(0, I2C.MASTER)             # create and init as a master
+        i2c.init(I2C.MASTER, baudrate=20000) # init as a master
+        i2c.deinit()                         # turn off the peripheral
+
+Printing the i2c object gives you information about its configuration.
+
+.. only:: port_wipy
+
+    A master must specify the recipient's address::
+
+        i2c.init(I2C.MASTER)
+        i2c.writeto(0x42, '123')        # send 3 bytes to slave with address 0x42
+        i2c.writeto(addr=0x42, b'456')  # keyword for address
+
+    Master also has other methods::
+
+        i2c.scan()                          # scan for slaves on the bus, returning
+                                            #   a list of valid addresses
+        i2c.readfrom_mem(0x42, 2, 3)        # read 3 bytes from memory of slave 0x42,
+                                            #   starting at address 2 in the slave
+        i2c.writeto_mem(0x42, 2, 'abc')     # write 'abc' (3 bytes) to memory of slave 0x42
+                                            # starting at address 2 in the slave, timeout after 1 second
+
+Constructors
+------------
+
+.. only:: port_wipy
+
+    .. class:: machine.I2C(bus, ...)
+
+       Construct an I2C object on the given bus.  `bus` can only be 0.
+       If the bus is not given, the default one will be selected (0).
+
+Methods
+-------
+
+.. method:: i2c.deinit()
+
+   Turn off the I2C bus.
+
+.. only:: port_wipy
+
+    .. method:: i2c.init(mode, \*, baudrate=100000, pins=(SDA, SCL))
+
+      Initialise the I2C bus with the given parameters:
+
+         - ``mode`` must be ``I2C.MASTER``
+         - ``baudrate`` is the SCL clock rate
+         - ``pins`` is an optional tuple with the pins to assign to the I2C bus.
+
+    .. method:: i2c.readfrom(addr, nbytes)
+
+        Read ``nbytes`` from the slave specified by ``addr``.
+        Returns a ``bytes`` object with the data read.
+
+    .. method:: i2c.readfrom_into(addr, buf)
+
+        Read into ``buf`` from the slave specified by ``addr``.
+        Returns the number of bytes read.
+
+    .. method:: i2c.writeto(addr, buf, \*, stop=True)
+
+        Write ``buf`` to the slave specified by ``addr``. Set ``stop`` to ``False``
+        if the transfer should be continued.
+        Returns the number of bytes written.
+
+    .. method:: i2c.readfrom_mem(addr, memaddr, nbytes, \*, addrsize=8)
+
+        Read ``nbytes`` from the slave specified by ``addr`` starting from the memory
+        address specified by ``memaddr``.
+        Param ``addrsize`` specifies the address size in bits.
+        Returns a ``bytes`` object with the data read.
+
+    .. method:: i2c.readfrom_mem_into(addr, memaddr, buf, \*, addrsize=8)
+
+        Read into ``buf`` from the slave specified by ``addr`` starting from the memory
+        address specified by ``memaddr``.
+        Param ``addrsize`` specifies the address size in bits.
+        Returns the number of bytes read.
+
+    .. method:: i2c.writeto_mem(addr, memaddr, buf, \*, addrsize=8)
+
+        Write ``buf`` to the slave specified by ``addr`` starting from the
+        memory address specified by ``memaddr``. Param ``addrsize`` specifies the 
+        address size in bits.
+        Set ``stop`` to ``False`` if the transfer should be continued.
+        Returns the number of bytes written.
+
+.. method:: i2c.scan()
+
+   Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
+   Only valid when in master mode.
+
+Constants
+---------
+
+.. data:: I2C.MASTER
+
+   for initialising the bus to master mode
diff --git a/docs/library/machine.Pin.rst b/docs/library/machine.Pin.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f7b783c19120c8d4d7e0fe32cdd2854f91a4ca6f
--- /dev/null
+++ b/docs/library/machine.Pin.rst
@@ -0,0 +1,206 @@
+.. _machine.Pin:
+
+class Pin -- control I/O pins
+=============================
+
+A pin is the basic object to control I/O pins.  It has methods to set
+the mode of the pin (input, output, etc) and methods to get and set the
+digital logic level. For analog control of a pin, see the ADC class.
+
+Usage Model:
+
+.. only:: port_wipy
+
+    Board pins are identified by their string id::
+
+        g = machine.Pin('GP9', mode=machine.Pin.OUT, pull=None, drive=machine.Pin.MED_POWER, alt=-1)
+
+    You can also configure the Pin to generate interrupts. For instance::
+
+        def pincb(pin):
+            print(pin.id())
+
+        pin_int = machine.Pin('GP10', mode=Pin.IN, pull=machine.Pin.PULL_DOWN)
+        pin_int.irq(mode=machine.Pin.IRQ_RISING, handler=pincb)
+        # the callback can be triggered manually
+        pin_int.irq()()
+        # to disable the callback
+        pin_int.irq().disable()
+
+    Now every time a falling edge is seen on the gpio pin, the callback will be
+    executed. Caution: mechanical push buttons have "bounce" and pushing or
+    releasing a switch will often generate multiple edges.
+    See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
+    explanation, along with various techniques for debouncing.
+
+    All pin objects go through the pin mapper to come up with one of the
+    gpio pins.
+
+Constructors
+------------
+
+.. class:: machine.Pin(id, ...)
+
+   Create a new Pin object associated with the id.  If additional arguments are given,
+   they are used to initialise the pin.  See :meth:`pin.init`.
+
+Methods
+-------
+
+.. only:: port_wipy
+
+    .. method:: pin.init(mode, pull, \*, drive, alt)
+    
+       Initialise the pin:
+
+         - ``mode`` can be one of:
+
+            - ``Pin.IN``  - input pin.
+            - ``Pin.OUT`` - output pin in push-pull mode.
+            - ``Pin.OPEN_DRAIN`` - output pin in open-drain mode.
+            - ``Pin.ALT`` - pin mapped to an alternate function.
+            - ``Pin.ALT_OPEN_DRAIN`` - pin mapped to an alternate function in open-drain mode.
+
+         - ``pull`` can be one of:
+
+            - ``None`` - no pull up or down resistor.
+            - ``Pin.PULL_UP`` - pull up resistor enabled.
+            - ``Pin.PULL_DOWN`` - pull down resitor enabled.
+
+         - ``drive`` can be one of:
+
+            - ``Pin.LOW_POWER`` - 2mA drive capability.
+            - ``Pin.MED_POWER`` - 4mA drive capability.
+            - ``Pin.HIGH_POWER`` - 6mA drive capability.
+
+         - ``alt`` is the number of the alternate function. Please refer to the
+           `pinout and alternate functions table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
+           for the specific alternate functions that each pin supports.
+
+       Returns: ``None``.
+
+    .. method:: pin.id()
+
+       Get the pin id.
+
+.. method:: pin.value([value])
+
+   Get or set the digital logic level of the pin:
+
+     - With no argument, return 0 or 1 depending on the logic level of the pin.
+     - With ``value`` given, set the logic level of the pin.  ``value`` can be
+       anything that converts to a boolean.  If it converts to ``True``, the pin
+       is set high, otherwise it is set low.
+
+.. method:: pin.alt_list()
+
+    Returns a list of the alternate functions supported by the pin. List items are
+    a tuple of the form: ``('ALT_FUN_NAME', ALT_FUN_INDEX)``
+
+.. only:: port_wipy
+
+    .. method:: pin([value])
+
+       Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin.
+       See **pin.value** for more details.
+
+    .. method:: pin.toggle()
+
+        Toggle the value of the pin.
+
+    .. method:: pin.mode([mode])
+
+        Get or set the pin mode.
+
+    .. method:: pin.pull([pull])
+
+        Get or set the pin pull.
+
+    .. method:: pin.drive([drive])
+
+        Get or set the pin drive strength.
+
+    .. method:: pin.irq(\*, trigger, priority=1, handler=None, wake=None)
+
+        Create a callback to be triggered when the input level at the pin changes.
+
+            - ``trigger`` configures the pin level which can generate an interrupt. Possible values are:
+
+                - ``Pin.IRQ_FALLING`` interrupt on falling edge.
+                - ``Pin.IRQ_RISING`` interrupt on rising edge.
+                - ``Pin.IRQ_LOW_LEVEL`` interrupt on low level.
+                - ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level.
+              
+              The values can be *ORed* together, for instance mode=Pin.IRQ_FALLING | Pin.IRQ_RISING
+
+            - ``priority`` level of the interrupt. Can take values in the range 1-7.
+              Higher values represent higher priorities.
+            - ``handler`` is an optional function to be called when new characters arrive.
+            - ``wakes`` selects the power mode in which this interrupt can wake up the
+              board. Please note:
+
+              - If ``wake_from=machine.Sleep.ACTIVE`` any pin can wake the board.
+              - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``,
+                ``GP11``, GP17`` or ``GP24`` can wake the board. Note that only 1
+                of this pins can be enabled as a wake source at the same time, so, only
+                the last enabled pin as a ``machine.Sleep.SUSPENDED`` wake source will have effect.
+              - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``,
+                ``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the
+                6 pins can be enabled as a ``machine.Sleep.HIBERNATE`` wake source at the same time.
+              - Values can be ORed to make a pin generate interrupts in more than one power
+                mode.
+
+            Returns a callback object.
+
+Attributes
+----------
+
+.. class:: Pin.board
+
+    Contains all ``Pin`` objects supported by the board. Examples::
+
+        Pin.board.GP25
+        led = Pin(Pin.board.GP25, mode=Pin.OUT)
+        Pin.board.GP2.alt_list()
+
+
+Constants
+---------
+
+.. only:: port_wipy
+
+    .. data:: Pin.IN
+
+    .. data:: Pin.OUT
+    
+    .. data:: Pin.OPEN_DRAIN
+
+    .. data:: Pin.ALT
+
+    .. data:: Pin.ALT_OPEN_DRAIN
+
+       Selects the pin mode.
+
+    .. data:: Pin.PULL_UP
+
+    .. data:: Pin.PULL_DOWN
+    
+       Selectes the wether there's pull up/down resistor.
+
+    .. data:: Pin.LOW_POWER
+
+    .. data:: Pin.MED_POWER
+
+    .. data:: Pin.HIGH_POWER
+
+        Selects the drive strength.
+
+    .. data:: Pin.IRQ_FALLING
+
+    .. data:: Pin.IRQ_RISING
+
+    .. data:: Pin.IRQ_LOW_LEVEL
+
+    .. data:: Pin.IRQ_HIGH_LEVEL
+
+        Selects the IRQ trigger type.
diff --git a/docs/library/machine.RTC.rst b/docs/library/machine.RTC.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fcfc14f5001a6f041444cb7e3094d60a3f039780
--- /dev/null
+++ b/docs/library/machine.RTC.rst
@@ -0,0 +1,68 @@
+.. _machine.RTC:
+
+class RTC -- real time clock
+============================
+
+The RTC is and independent clock that keeps track of the date
+and time.
+
+Example usage::
+
+    rtc = machine.RTC()
+    rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
+    print(rtc.datetime())
+
+
+Constructors
+------------
+
+.. class:: machine.RTC(id=0, ...)
+
+   Create an RTC object. See init for parameters of initialization.
+
+Methods
+-------
+
+.. method:: rtc.init(id, datetime)
+
+   Initialise the RTC. Datetime is a tuple of the form:
+   
+      ``(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])``
+
+.. method:: rtc.now()
+
+   Get get the current datetime tuple.
+
+.. method:: rtc.deinit()
+
+   Resets the RTC to the time of January 1, 2015 and starts running it again.
+
+.. method:: rtc.alarm(id, time, /*, repeat=False)
+
+   Set the RTC alarm. Time might be either a milllisecond value to program the alarm to
+   current time + time_in_ms in the future, or a datetimetuple. If the time passed is in
+   milliseconds, repeat can be set to ``True`` to make the alarm periodic.
+
+.. method:: rtc.alarm_left(alarm_id=0)
+
+   Get the number of milliseconds left before the alarm expires.
+
+.. method:: rtc.cancel(alarm_id=0)
+
+   Cancel a running alarm.
+
+.. method:: rtc.irq(\*, trigger, handler=None, wake=machine.IDLE)
+
+   Create an irq object triggered by a real time clock alarm.
+
+      - ``trigger`` must be ``RTC.ALARM0``
+      - ``handler`` is the function to be called when the callback is triggered.
+      - ``wake`` specifies the sleep mode from where this interrupt can wake
+        up the system.
+
+Constants
+---------
+
+.. data:: RTC.ALARM0
+
+    irq trigger source
diff --git a/docs/library/pyb.SD.rst b/docs/library/machine.SD.rst
similarity index 54%
rename from docs/library/pyb.SD.rst
rename to docs/library/machine.SD.rst
index 9b3d95dac4a05d9c5017ab487d3d699d6d10029e..19d8d655bdfc779eaa3588af15bab0fa512e94c4 100644
--- a/docs/library/pyb.SD.rst
+++ b/docs/library/machine.SD.rst
@@ -1,4 +1,4 @@
-.. _pyb.SD:
+.. _machine.SD:
 
 class SD -- secure digital memory card
 ======================================
@@ -13,36 +13,30 @@ more info regarding the pins which can be remapped to be used with a SD card.
 
 Example usage::
 
-    # data, clk and cmd pins must be passed along with
+    from machine import SD
+    import os
+    # clk cmd and dat0 pins must be passed along with
     # their respective alternate functions
-    sd = pyb.SD(('GP15', 8, 'GP10', 6, 'GP11', 6))
-    sd.mount()
+    sd = machine.SD(pins=('GP10', 'GP11', 'GP15'))
+    os.mount(sd, '/sd')
     # do normal file operations
 
 Constructors
 ------------
 
-.. class:: pyb.SD([pins_tuple])
+.. class:: machine.SD(id,... )
 
-   Create a SD card object. In order to initalize the card, give it a 6-tuple
-   ``(dat_pin, dat_af, clk_pin, clk_af, cmd_pin, cmd_af)`` with the data, clock
-   and cmd pins together their respective alternate functions.
+   Create a SD card object. See init for parameters if initialization. 
 
 Methods
 -------
 
-.. method:: sd.init([pins_tuple])
+.. method:: sd.init(id, pins=('GP10', 'GP11', 'GP15'))
 
    Enable the SD card.
+   In order to initalize the card, give it a 3-tuple ``(clk_pin, cmd_pin, dat0_pin)``
+   ID defaults to zero.
 
 .. method:: sd.deinit()
 
-   Disable the SD card (also unmounts it to avoid file system crashes).
-
-.. method:: sd.mount()
-
-   Mount the SD card on the file system. Accesible as ``/sd``.
-
-.. method:: sd.unmount()
-
-   Unmount the SD card from the file system.
+   Disable the SD card.
diff --git a/docs/library/machine.SPI.rst b/docs/library/machine.SPI.rst
new file mode 100644
index 0000000000000000000000000000000000000000..eddd62dbdc73278f5db3913fada202dc29310502
--- /dev/null
+++ b/docs/library/machine.SPI.rst
@@ -0,0 +1,85 @@
+.. _machine.SPI:
+
+class SPI -- a master-driven serial protocol
+============================================
+
+SPI is a serial protocol that is driven by a master.  At the physical level
+there are 3 lines: SCK, MOSI, MISO.
+
+.. only:: port_wipy
+
+    See usage model of I2C; SPI is very similar.  Main difference is
+    parameters to init the SPI bus::
+
+        from machine import SPI
+        spi = SPI(0, mode=SPI.MASTER, baudrate=1000000, polarity=0, phase=0, firstbit=SPI.MSB)
+
+    Only required parameter is mode, must be SPI.MASTER.  Polarity can be 0 or 
+    1, and is the level the idle clock line sits at.  Phase can be 0 or 1 to 
+    sample data on the first or second clock edge respectively.
+
+Constructors
+------------
+
+.. only:: port_wipy
+
+    .. class:: machine.SPI(id, ...)
+
+       Construct an SPI object on the given bus.  ``id`` can be only 0.
+       With no additional parameters, the SPI object is created but not
+       initialised (it has the settings from the last initialisation of
+       the bus, if any).  If extra arguments are given, the bus is initialised.
+       See ``init`` for parameters of initialisation.
+
+Methods
+-------
+
+.. method:: spi.init(mode, baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, pins=(CLK, MOSI, MISO))
+
+   Initialise the SPI bus with the given parameters:
+
+     - ``mode`` must be ``SPI.MASTER``.
+     - ``baudrate`` is the SCK clock rate.
+     - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
+     - ``phase`` can be 0 or 1 to sample data on the first or second clock edge
+       respectively.
+     - ``bits`` is the width of each transfer, accepted values are 8, 16 and 32.
+     - ``firstbit`` can be ``SPI.MSB`` only.
+     - ``pins`` is an optional tupple with the pins to assign to the SPI bus.
+
+.. method:: spi.deinit()
+
+   Turn off the SPI bus.
+
+.. method:: spi.write(buf)
+
+    Write the data contained in ``buf``. 
+    Returns the number of bytes written.
+
+.. method:: spi.read(nbytes, *, write=0x00)
+
+    Read the ``nbytes`` while writing the data specified by ``write``.
+    Return the number of bytes read.
+
+.. method:: spi.readinto(buf, *, write=0x00)
+
+    Read into the buffer specified by ``buf`` while writing the data specified by
+    ``write``.
+    Return the number of bytes read.
+
+.. method:: spi.write_readinto(write_buf, read_buf)
+
+    Write from ``write_buf`` and read into ``read_buf``. Both buffers must have the
+    same length.
+    Returns the number of bytes written
+
+Constants
+---------
+
+.. data:: SPI.MASTER
+
+   for initialising the SPI bus to master
+
+.. data:: SPI.MSB
+
+   set the first bit to be the most significant bit
diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4814da8603897372c027d100cf59f9d7b9168caa
--- /dev/null
+++ b/docs/library/machine.Timer.rst
@@ -0,0 +1,193 @@
+.. _machine.Timer:
+
+class Timer -- control internal timers
+======================================
+
+.. only:: port_wipy
+
+    .. note::
+
+        Contrary with the rest of the API, timer IDs start at 1, not a t zero. This is because
+        the ``Timer`` API is still provisional. A new MicroPython wide API will come soon.
+
+    Timers can be used for a great variety of tasks, calling a function periodically,
+    counting events, and generating a PWM signal are among the most common use cases.
+    Each timer consists of 2 16-bit channels and this channels can be tied together to
+    form 1 32-bit timer. The operating mode needs to be configured per timer, but then
+    the period (or the frequency) can be independently configured on each channel. 
+    By using the callback method, the timer event can call a Python function.
+
+    Example usage to toggle an LED at a fixed frequency::
+
+        tim = machine.Timer(4)                                              # create a timer object using timer 4
+        tim.init(mode=Timer.PERIODIC)                                   # initialize it in periodic mode
+        tim_ch = tim.channel(Timer.A, freq=2)                           # configure channel A at a frequency of 2Hz
+        tim_ch.callback(handler=lambda t:led.toggle())                  # toggle a LED on every cycle of the timer
+
+    Example using named function for the callback::
+
+        tim = Timer(1, mode=Timer.PERIODIC)
+        tim_a = tim.channel(Timer.A, freq=1000)
+
+        led = Pin('GPIO2', af=0, mode=Pin.OUT)
+
+        def tick(timer):                # we will receive the timer object when being called
+            print(timer.time())         # show current timer's time value (is microseconds)
+            led.toggle()                # toggle the LED
+
+        tim_a.callback(handler=tick)
+
+    Further examples::
+
+        tim1 = machine.Timer(2, mode=Timer.EVENT_COUNT)                     # initialize it capture mode
+        tim2 = machine.Timer(1, mode=Timer.PWM)                             # initialize it in PWM mode
+        tim_ch = tim1.channel(Timer.A, freq=1, polarity=Timer.POSITIVE) # start the event counter with a frequency of 1Hz and triggered by positive edges
+        tim_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=50)       # start the PWM on channel B with a 50% duty cycle
+        tim_ch.time()                                                   # get the current time in usec (can also be set)
+        tim_ch.freq(20)                                                 # set the frequency (can also get)
+        tim_ch.duty_cycle(30)                                           # set the duty cycle to 30% (can also get)
+        tim_ch.duty_cycle(30, Timer.NEGATIVE)                           # set the duty cycle to 30% and change the polarity to negative
+        tim_ch.event_count()                                            # get the number of captured events
+        tim_ch.event_time()                                             # get the the time of the last captured event
+        tim_ch.period(2000000)                                          # change the period to 2 seconds
+
+
+.. note::
+
+    Memory can't be allocated during a callback (an interrupt) and so
+    exceptions raised within a callback don't give much information.  See
+    :func:`micropython.alloc_emergency_exception_buf` for how to get around this
+    limitation.
+
+Constructors
+------------
+
+.. class:: machine.Timer(id, ...)
+
+    .. only:: port_wipy
+
+       Construct a new timer object of the given id.  If additional
+       arguments are given, then the timer is initialised by ``init(...)``.
+       ``id`` can be 1 to 4.
+
+
+Methods
+-------
+
+.. only:: port_wipy
+
+    .. method:: timer.init(mode, \*, width=16)
+
+       Initialise the timer. Example::
+
+           tim.init(Timer.PERIODIC)             # periodic 16-bit timer
+           tim.init(Timer.ONE_SHOT, width=32)   # one shot 32-bit timer
+
+       Keyword arguments:
+       
+         - ``mode`` can be one of:
+         
+           - ``Timer.ONE_SHOT`` - The timer runs once until the configured 
+             period of the channel expires.
+           - ``Timer.PERIODIC`` - The timer runs periodically at the configured 
+             frequency of the channel.
+           - ``Timer.EDGE_TIME`` - Meaure the time pin level changes.
+           - ``Timer.EDGE_COUNT`` - Count the number of pin level changes.
+
+         - ``width`` must be either 16 or 32 (bits). For really low frequencies <= ~1Hz
+           (or large periods), 32-bit timers should be used. 32-bit mode is only available
+           for ``ONE_SHOT`` AND ``PERIODIC`` modes.
+
+.. method:: timer.deinit()
+
+   Deinitialises the timer. Disables all channels and associated IRQs.
+   Stops the timer, and disables the timer peripheral.
+
+.. only:: port_wipy
+
+    .. method:: timer.channel(channel, \**, freq, period, polarity=Timer.POSITIVE, duty_cycle=0)
+    
+       If only a channel identifier passed, then a previously initialized channel
+       object is returned (or ``None`` if there is no previous channel).
+       
+       Othwerwise, a TimerChannel object is initialized and returned.
+       
+       The operating mode is is the one configured to the Timer object that was used to
+       create the channel.
+
+       - ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``. 
+         If the width is 32-bit then it **must be** ``TIMER.A | TIMER.B``.
+
+       Keyword only arguments:
+
+         - ``freq`` sets the frequency in Hz.
+         - ``period`` sets the period in microseconds.
+
+         .. note::
+
+            Either ``freq`` or ``period`` must be given, never both.
+
+         - ``polarity`` this is applicable for:
+           
+           - ``PWM``, defines the polarity of the duty cycle
+           - ``EDGE_TIME`` and ``EDGE_COUNT``, defines the polarity of the pin level change to detect.
+             To detect both rising and falling edges, make ``polarity=Timer.POSITIVE | Timer.NEGATIVE``.
+         - ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0-100)
+
+class TimerChannel --- setup a channel for a timer
+==================================================
+
+Timer channels are used to generate/capture a signal using a timer.
+
+TimerChannel objects are created using the Timer.channel() method.
+
+Methods
+-------
+
+.. only:: port_wipy
+
+    .. method:: timerchannel.irq(\*, trigger, priority=1, handler=None)
+
+        The behavior of this callback is heaviliy dependent on the operating
+        mode of the timer channel:
+
+            - If mode is ``Timer.PERIODIC`` the callback is executed periodically
+              with the configured frequency or period.
+            - If mode is ``Timer.ONE_SHOT`` the callback is executed once when
+              the configured timer expires.
+            - If mode is ``Timer.PWM`` the callback is executed when reaching the duty
+              cycle value.
+
+        The accepted params are:
+
+            - ``priority`` level of the interrupt. Can take values in the range 1-7.
+              Higher values represent higher priorities.
+            - ``handler`` is an optional function to be called when the interrupt is triggered.
+
+        Returns a callback object.
+
+.. only:: port_wipy
+
+    .. method:: timerchannel.freq([value])
+    
+       Get or set the timer channel frequency (in Hz).
+
+    .. method:: timerchannel.period([value])
+
+       Get or set the timer channel period (in microseconds).
+       
+    .. method:: timerchannel.time([value])
+
+       Get or set the timer channel current **time** value (in microseconds).
+    
+    .. method:: timerchannel.event_count()
+
+       Get the number of edge events counted.
+
+    .. method:: timerchannel.event_time()
+
+       Get the time of ocurrance of the last event.
+
+    .. method:: timerchannel.duty_cycle([value])
+     
+       Get or set the duty cycle of the PWM signal (in the range of 0-100).
diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst
new file mode 100644
index 0000000000000000000000000000000000000000..034492717c68575dbd3f9ca0adfc22c4f08a1e2b
--- /dev/null
+++ b/docs/library/machine.UART.rst
@@ -0,0 +1,170 @@
+.. _machine.UART:
+
+class UART -- duplex serial communication bus
+=============================================
+
+UART implements the standard UART/USART duplex serial communications protocol.  At
+the physical level it consists of 2 lines: RX and TX.  The unit of communication
+is a character (not to be confused with a string character) which can be 8 or 9
+bits wide.
+
+UART objects can be created and initialised using::
+
+    from machine import UART
+
+    uart = UART(1, 9600)                         # init with given baudrate
+    uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
+
+.. only:: port_machineoard
+
+    Bits can be 7, 8 or 9.  Parity can be None, 0 (even) or 1 (odd).  Stop can be 1 or 2.
+    
+    *Note:* with parity=None, only 8 and 9 bits are supported.  With parity enabled,
+    only 7 and 8 bits are supported.
+
+.. only:: port_wipy
+
+    Bits can be 5, 6, 7, 8.  Parity can be ``None``, ``UART.EVEN`` or ``UART.ODD``.  Stop can be 1 or 2.
+
+
+A UART object acts like a stream object and reading and writing is done
+using the standard stream methods::
+
+    uart.read(10)       # read 10 characters, returns a bytes object
+    uart.readall()      # read all available characters
+    uart.readline()     # read a line
+    uart.readinto(buf)  # read and store into the given buffer
+    uart.write('abc')   # write the 3 characters
+
+.. only:: port_machineoard
+
+    Individual characters can be read/written using::
+
+        uart.readchar()     # read 1 character and returns it as an integer
+        uart.writechar(42)  # write 1 character
+
+    To check if there is anything to be read, use::
+
+        uart.any()               # returns True if any characters waiting
+
+    *Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
+    Earlier versions use ``uart.send`` and ``uart.recv``.
+
+.. only:: port_wipy
+
+    To check if there is anything to be read, use::
+
+        uart.any()               # returns the number of characters available for reading
+
+Constructors
+------------
+
+.. only:: port_wipy
+
+    .. class:: machine.UART(bus, ...)
+    
+       Construct a UART object on the given bus.  ``bus`` can be 0 or 1.
+       If the bus is not given, the default one will be selected (0) or the selection
+       will be made based on the given pins.
+
+Methods
+-------
+
+.. only:: port_wipy
+
+    .. method:: uart.init(baudrate=9600, bits=8, parity=None, stop=1, \*, pins=(TX, RX, RTS, CTS))
+    
+       Initialise the UART bus with the given parameters:
+    
+         - ``baudrate`` is the clock rate.
+         - ``bits`` is the number of bits per character, 7, 8 or 9.
+         - ``parity`` is the parity, ``None``, ``UART.EVEN`` or ``UART.ODD``.
+         - ``stop`` is the number of stop bits, 1 or 2.
+         - ``pins`` is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
+           Any of the pins can be None if one wants the UART to operate with limited functionality.
+           If the RTS pin is given the the RX pin must be given as well. The same applies to CTS. 
+           When no pins are given, then the default set of TX and RX pins is taken, and hardware 
+           flow control will be disabled. If pins=None, no pin assignment will be made.
+
+.. method:: uart.deinit()
+
+   Turn off the UART bus.
+
+.. method:: uart.any()
+
+   Return the number of characters available for reading.
+
+.. method:: uart.read([nbytes])
+
+   Read characters.  If ``nbytes`` is specified then read at most that many bytes.
+
+   Return value: a bytes object containing the bytes read in.  Returns ``b''``
+   on timeout.
+
+.. method:: uart.readall()
+
+   Read as much data as possible.
+
+   Return value: a bytes object.
+
+.. method:: uart.readinto(buf[, nbytes])
+
+   Read bytes into the ``buf``.  If ``nbytes`` is specified then read at most
+   that many bytes.  Otherwise, read at most ``len(buf)`` bytes.
+
+   Return value: number of bytes read and stored into ``buf``.
+
+.. method:: uart.readline()
+
+   Read a line, ending in a newline character.
+
+   Return value: the line read.
+
+.. method:: uart.write(buf)
+
+   Write the buffer of bytes to the bus.
+
+   Return value: number of bytes written.
+
+.. method:: uart.sendbreak()
+
+   Send a break condition on the bus.  This drives the bus low for a duration
+   of 13 bits.
+   Return value: ``None``.
+
+.. only:: port_wipy
+
+    .. method:: uart.irq(trigger, priority=1, handler=None, wake=machine.IDLE)
+
+       Create a callback to be triggered when data is received on the UART.
+
+           - ``trigger`` can only be ``UART.RX_ANY``
+           - ``priority`` level of the interrupt. Can take values in the range 1-7.
+             Higher values represent higher priorities.
+           - ``handler`` an optional function to be called when new characters arrive.
+           - ``wake`` can only be ``machine.IDLE``.
+
+       .. note::
+
+          The handler will be called whenever any of the following two conditions are met:
+
+              - 8 new characters have been received.
+              - At least 1 new character is waiting in the Rx buffer and the Rx line has been
+                silent for the duration of 1 complete frame.
+
+          This means that when the handler function is called there will be between 1 to 8 
+          characters waiting.
+
+       Returns a irq object.
+
+Constants
+---------
+
+.. data:: UART.EVEN
+.. data:: UART.ODD
+
+    parity types (anlong with ``None``)
+
+.. data:: UART.RX_ANY
+
+    IRQ trigger sources
diff --git a/docs/library/pyb.WDT.rst b/docs/library/machine.WDT.rst
similarity index 80%
rename from docs/library/pyb.WDT.rst
rename to docs/library/machine.WDT.rst
index 867026b322c7a18f877456837aa85cfc4790e24a..9ce0a96ac37f4418251cd0db3f07ecb4f2312ee0 100644
--- a/docs/library/pyb.WDT.rst
+++ b/docs/library/machine.WDT.rst
@@ -1,22 +1,22 @@
-.. _pyb.WDT:
+.. _machine.WDT:
 
 class WDT -- watchdog timer
 ===========================
 
 The WDT is used to restart the system when the application crashes and ends
 up into a non recoverable state. Once started it cannot be stopped or
-reconfigured in any way. After enabling, the application must "kick" the
+reconfigured in any way. After enabling, the application must "feed" the
 watchdog periodically to prevent it from expiring and resetting the system.
 
 Example usage::
 
-    wdt = pyb.WDT(timeout=2000) # enable with a timeout of 2s
+    wdt = machine.WDT(timeout=2000) # enable with a timeout of 2s
     wdt.feed()
 
 Constructors
 ------------
 
-.. class:: pyb.WDT(id=0, timeout=5000)
+.. class:: machine.WDT(id=0, timeout=5000)
 
    Create a WDT object and start it. The timeout must be given in seconds and
    the minimum value that is accepted is 1 second. Once it is running the timeout
diff --git a/docs/library/machine.rst b/docs/library/machine.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f94454359b5651cc1eeafba0b7eb7c99edb2e6ef
--- /dev/null
+++ b/docs/library/machine.rst
@@ -0,0 +1,132 @@
+:mod:`machine` --- functions related to the board
+=================================================
+
+.. module:: machine
+   :synopsis: functions related to the board
+
+The ``machine`` module contains specific functions related to the board.
+
+Reset related functions
+-----------------------
+
+.. function:: reset()
+
+   Resets the WiPy in a manner similar to pushing the external RESET
+   button.
+
+.. function:: reset_cause()
+
+   Get the reset cause. See :ref:`constants <machine_constants>` for the possible return values.
+
+Interrupt related functions
+---------------------------
+
+.. function:: disable_irq()
+
+   Disable interrupt requests.
+   Returns the previous IRQ state: ``False``/``True`` for disabled/enabled IRQs
+   respectively.  This return value can be passed to enable_irq to restore
+   the IRQ to its original state.
+
+.. function:: enable_irq(state=True)
+
+   Enable interrupt requests.
+   If ``state`` is ``True`` (the default value) then IRQs are enabled.
+   If ``state`` is ``False`` then IRQs are disabled.  The most common use of
+   this function is to pass it the value returned by ``disable_irq`` to
+   exit a critical section.
+
+Power related functions
+-----------------------
+
+.. function:: freq()
+
+   Returns a tuple of clock frequencies: ``(sysclk,)``
+   These correspond to:
+
+      - sysclk: frequency of the CPU
+
+.. function:: idle()
+
+   Gates the clock to the CPU, useful to reduce power consumption at any time during
+   short or long periods. Peripherals continue working and execution resumes as soon
+   as any interrupt is triggered (including the systick which has a period of 1ms).
+   Current consumption is reduced to ~12mA (in WLAN STA mode)
+
+.. function:: sleep()
+
+   Stops the CPU and disables all peripherals except for WLAN. Execution is resumed from
+   the point where the sleep was requested. Wake sources are ``Pin``, ``RTC`` and ``WLAN``.
+   Current consumption is reduced to 950uA (in WLAN STA mode).
+
+.. function:: deepsleep()
+
+   Stops the CPU and all peripherals including WLAN. Execution is resumed from main, just
+   as with a reset. The reset cause can be checked to know that we are coming from
+   from ``machine.DEEPSLEEP``. Wake sources are ``Pin`` and ``RTC``. Current consumption 
+   is reduced to ~5uA.
+
+.. function:: wake_reason()
+
+   Get the wake reason. See :ref:`constants <machine_constants>` for the possible return values.
+
+Miscellaneous functions
+-----------------------
+
+.. function:: main(filename)
+
+   Set the filename of the main script to run after boot.py is finished.  If
+   this function is not called then the default file main.py will be executed.
+
+   It only makes sense to call this function from within boot.py.
+
+.. function:: rng()
+
+   Return a 24-bit software generated random number.
+
+.. function:: unique_id()
+
+   Returns a string of 6 bytes (48 bits), which is the unique ID of the MCU.
+   This also corresponds to the ``MAC address`` of the WiPy.
+
+.. _machine_constants:
+
+Constants
+---------
+
+.. data:: machine.IDLE
+.. data:: machine.SLEEP
+.. data:: machine.DEEPSLEEP
+
+    irq wake values
+
+.. data:: machine.POWER_ON
+.. data:: machine.HARD_RESET
+.. data:: machine.WDT_RESET
+.. data:: machine.DEEPSLEEP_RESET
+.. data:: machine.SOFT_RESET
+
+    reset causes
+
+.. data:: machine.WLAN_WAKE
+.. data:: machine.PIN_WAKE
+.. data:: machine.RTC_WAKE
+
+    wake reasons
+
+Classes
+-------
+
+.. toctree::
+   :maxdepth: 1
+
+   machine.ADC.rst
+   machine.HeartBeat.rst
+   machine.I2C.rst
+   machine.Pin.rst
+   machine.RTC.rst
+   machine.SD.rst
+   machine.SPI.rst
+   machine.Timer.rst
+   machine.UART.rst
+   machine.WDT.rst
diff --git a/docs/library/network.rst b/docs/library/network.rst
index 1044814ffaca5945a446f8fa31a2faa7ffdbfbe8..cee65491c6aa8bd1b3f16750d290f3d2b2e2f0d9 100644
--- a/docs/library/network.rst
+++ b/docs/library/network.rst
@@ -259,14 +259,15 @@ class WLAN
 .. only:: port_wipy
 
     This class provides a driver for WiFi network processor in the WiPy.  Example usage::
-    
+
         import network
+        import time
         # setup as a station
-        nic = network.WLAN(mode=WLAN.STA)
-        nic.connect('your-ssid', security=WLAN.WPA2, key='your-key')
-        while not nic.isconnected():
-            pyb.delay(50)
-        print(nic.ifconfig())
+        wlan = network.WLAN(mode=WLAN.STA)
+        wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
+        while not wlan.isconnected():
+            time.sleep_ms(50)
+        print(wlan.ifconfig())
 
         # now use socket as usual
         ...
@@ -276,12 +277,12 @@ class WLAN
     
     .. class:: WLAN(..)
 
-       Create a WLAN object, and optionally configure it. See ``iwconfig`` for params of configuration.
+       Create a WLAN object, and optionally configure it. See ``init`` for params of configuration.
 
     Methods
     -------
 
-    .. method:: iwconfig(\*, mode, ssid, security, key, channel, antenna)
+    .. method:: init(mode, \*, ssid, security, key, channel, antenna)
     
        Set or get the WiFi network processor configuration.
     
@@ -289,14 +290,13 @@ class WLAN
     
          - ``mode`` can be either ``WLAN.STA`` or ``WLAN.AP``.
          - ``ssid`` is a string with the ssid name. Only needed when mode is ``WLAN.AP``.
-         - ``security`` can be ``WLAN.OPEN``, ``WLAN.WEP``, ``WLAN.WPA`` or ``WLAN.WPA2``. 
-           Only needed when mode is ``WLAN.AP``.
-         - ``key`` is a string with the network password. Not needed when mode is ``WLAN.STA``
-           or security is ``WLAN.OPEN``. If ``security`` is ``WLAN.WEP`` the key must be a
-           string representing hexadecimal values (e.g. 'ABC1DE45BF').
+         - ``auth`` is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``,
+           ``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password.
+           If ``security`` is ``WLAN.WEP`` the key must be a string representing hexadecimal
+           values (e.g. 'ABC1DE45BF'). Only needed when mode is ``WLAN.AP``.
          - ``channel`` a number in the range 1-11. Only needed when mode is ``WLAN.AP``.
          - ``antenna`` selects between the internal and the external antenna. Can be either
-           ``WLAN.INTERNAL`` or ``WLAN.EXTERNAL``.
+           ``WLAN.INT_ANT`` or ``WLAN.EXTERNAL``.
     
        For example, you can do::
 
@@ -311,57 +311,53 @@ class WLAN
        With no arguments given, the current configuration is returned as a namedtuple that looks like this:
        ``(mode=2, ssid='wipy-wlan', security=2, key='www.wipy.io', channel=5, antenna=0)``
 
-    .. method:: wlan.connect(ssid, \*, security=WLAN.OPEN, key=None, bssid=None, timeout=5000)
-    
+    .. method:: wlan.connect(ssid, \*, auth=None, key=None, bssid=None, timeout=5000)
+
        Connect to a wifi access point using the given SSID, and other security
        parameters.
-          
+
           - ``key`` is always a string, but if ``security`` is ``WLAN.WEP`` the key must be a string
             representing hexadecimal values (e.g. 'ABC1DE45BF').
           - ``bssid`` is the MAC address of the AP to connect to. Useful when there are several APs
             with the same ssid.
           - ``timeout`` is the maximum time in milliseconds to wait for the connection to succeed.
-    
+
     .. method:: wlan.scan()
-    
-       Performs a network scan and returns a list of named tuples with (ssid, bssid, security, channel, rssi).
+
+       Performs a network scan and returns a list of named tuples with (ssid, bssid, sec, channel, rssi).
        Note that channel is always ``None`` since this info is not provided by the WiPy.
-    
+
     .. method:: wlan.disconnect()
-    
+
        Disconnect from the wifi access point.
-    
+
     .. method:: wlan.isconnected()
-    
+
        In case of STA mode, returns ``True`` if connected to a wifi access point and has a valid IP address.
        In AP mode returns ``True`` when a station is connected. Returns ``False`` otherwise.
-    
-    .. method:: wlan.ifconfig(['dhcp' or configtuple])
-    
+
+    .. method:: wlan.ifconfig(if_id, config=['dhcp' or configtuple])
+
        With no parameters given eturns a 4-tuple of ``(ip, subnet mask, gateway, DNS server)``.
        
        if ``'dhcp'`` is passed as a parameter then the DHCP client is enabled and the IP params
        are negotiated with the AP.
        
        if the 4-tuple config is given then a static IP is configured. For example::
-    
-          nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
-    
-    .. method:: wlan.mac()
-    
-       Returns a 6-byte long bytes object with the MAC address.
 
-    .. method:: wlan.connections()
-    
-       Returns a list of the devices currently connected. Each item in the list is a
-       tuple of ``(ssid, mac)``.
+          nic.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
+
+    .. method:: wlan.mac([mac_addr])
+
+       Get or set a 6-byte long bytes object with the MAC address.
 
-    .. method:: wlan.callback(wake_from)
+    .. method:: wlan.irq(\*, handler, wake)
 
-        Create a callback to be triggered when a WLAN event occurs during ``pyb.Sleep.SUSPENDED``
+        Create a callback to be triggered when a WLAN event occurs during ``machine.SLEEP``
         mode. Events are triggered by socket activity or by WLAN connection/disconnection.
 
-            - ``wake_from`` must be ``pyb.Sleep.SUSPENDED``.
+            - ``handler`` is the function that gets called when the irq is triggered.
+            - ``wake`` must be ``machine.SLEEP``.
 
         Returns a callback object.
 
@@ -376,14 +372,13 @@ class WLAN
 
        WiFi access point mode
 
-    .. data:: WLAN.OPEN
     .. data:: WLAN.WEP
     .. data:: WLAN.WPA
     .. data:: WLAN.WPA2
 
        selects the network security
 
-    .. data:: WLAN.INTERNAL
-    .. data:: WLAN.EXTERNAL
+    .. data:: WLAN.INT_ANT
+    .. data:: WLAN.EXT_ANT
 
        selects the antenna type
diff --git a/docs/library/os.rst b/docs/library/os.rst
index e32a409f531d24f4aeb19e81bd1f0f3d03d480ec..302d71fd5d2e40b23743b21e2586159830b0b47a 100644
--- a/docs/library/os.rst
+++ b/docs/library/os.rst
@@ -71,9 +71,27 @@ Functions
 
 .. only:: port_wipy
 
-    .. function:: mkfs(drive)
-    
-       Formats the specified drive, must be either ``/flash`` or ``/sd``.
+    .. function:: mount(block_device, mount_point, \*, readonly=False)
+
+       Mounts a block device (like an ``SD`` object) in the specified mount
+       point. Example::
+
+          os.mount(sd, '/sd')
+
+    .. function:: unmount(path)
+
+       Unmounts a prevoulsy mounted block device from the given path.
+
+    .. function:: mkfs(block_device or path)
+
+       Formats the specified path, must be either ``/flash`` or ``/sd``.
+       A block device can also be passed like an ``SD`` object before
+       being mounted.
+
+    .. function:: dupterm(stream_object)
+
+       Duplicate the terminal (the REPL) on the passed stream-like object.
+       The given object must at least implement the ``.read()`` and ``.write()`` methods.
 
 Constants
 ---------
diff --git a/docs/library/pyb.ADC.rst b/docs/library/pyb.ADC.rst
index 8623dfc438aded1d6a1c874f4cba4b0c60399eb8..af4dc3d779a7aa54c2786b273d43611b068681e1 100644
--- a/docs/library/pyb.ADC.rst
+++ b/docs/library/pyb.ADC.rst
@@ -18,16 +18,6 @@ class ADC -- analog to digital conversion
         val = adc.read_core_vbat()      # read MCU VBAT
         val = adc.read_core_vref()      # read MCU VREF
 
-.. only:: port_wipy
-
-    Usage::
-    
-       import pyb
-
-       adc = pyb.ADC()                 # create an ADC object
-       apin = adc.channel(pin='GP3')   # create an analog pin on GP3
-       val = apin()                    # read an analog value
-
 Constructors
 ------------
 
@@ -39,22 +29,6 @@ Constructors
        Create an ADC object associated with the given pin.
        This allows you to then read analog values on that pin.
 
-.. only:: port_wipy
-
-    .. class:: pyb.ADC(id=0, \*, bits=12)
-
-       Create an ADC object associated with the given pin.
-       This allows you to then read analog values on that pin.
-       For more info check the `pinout and alternate functions
-       table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ 
-
-       .. warning:: 
-
-          ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it 
-          can withstand). When GP2, GP3, GP4 or GP5 are remapped to the 
-          ADC block, 1.8 V is the maximum. If these pins are used in digital mode, 
-          then the maximum allowed input is 3.6V.
-
 Methods
 -------
 
@@ -100,48 +74,3 @@ Methods
 
        This function does not allocate any memory.
 
-.. only:: port_wipy
-
-   .. method:: adc.channel(id, *, pin)
-
-      Create an analog pin. If only channel ID is given, the correct pin will be selected. Alternatively,
-      only the pin can be passed and the correct channel will be selected. Examples::
-
-        # all of these are equivalent and enable ADC channel 1 on GP3
-        apin = adc.channel(1)
-        apin = adc.channel(pin='GP3')
-        apin = adc.channel(id=1, pin='GP3')
-
-   .. method:: adc.init()
-
-      Enable the ADC block.
-
-   .. method:: adc.deinit()
-
-      Disable the ADC block.
-
-.. only:: port_wipy
-
-    class ADCChannel --- read analog values from internal or external sources
-    =========================================================================
-
-    .. only:: port_wipy
-
-        ADC channels can be connected to internal points of the MCU or to GPIO pins.
-        ADC channels are created using the ADC.channel method.
-
-       .. method:: adcchannel()
-
-          Fast method to read the channel value.
-
-       .. method:: adcchannel.value()
-
-          Read the channel value.
-
-       .. method:: adcchannel.init()
-
-          Re-init (and effectively enable) the ADC channel.
-
-       .. method:: adcchannel.deinit()
-
-          Disable the ADC channel.
diff --git a/docs/library/pyb.I2C.rst b/docs/library/pyb.I2C.rst
index eb60f22ffaa013e0400494693899695e01fb189b..0d00b1f753c304a0252f006df38b62cf67bf082e 100644
--- a/docs/library/pyb.I2C.rst
+++ b/docs/library/pyb.I2C.rst
@@ -21,17 +21,6 @@ when created, or initialised later on.
         i2c.init(I2C.SLAVE, addr=0x42)       # init as a slave with given address
         i2c.deinit()                         # turn off the peripheral
 
-.. only:: port_wipy
-
-    Example::
-
-        from pyb import I2C
-
-        i2c = I2C(0)                         # create on bus 0
-        i2c = I2C(0, I2C.MASTER)             # create and init as a master
-        i2c.init(I2C.MASTER, baudrate=20000) # init as a master
-        i2c.deinit()                         # turn off the peripheral
-
 Printing the i2c object gives you information about its configuration.
 
 .. only:: port_pyboard
@@ -67,23 +56,6 @@ Printing the i2c object gives you information about its configuration.
         i2c.mem_write('abc', 0x42, 2, timeout=1000) # write 'abc' (3 bytes) to memory of slave 0x42
                                                     # starting at address 2 in the slave, timeout after 1 second
 
-.. only:: port_wipy
-
-    A master must specify the recipient's address::
-
-        i2c.init(I2C.MASTER)
-        i2c.writeto(0x42, '123')        # send 3 bytes to slave with address 0x42
-        i2c.writeto(addr=0x42, b'456')  # keyword for address
-
-    Master also has other methods::
-
-        i2c.scan()                          # scan for slaves on the bus, returning
-                                            #   a list of valid addresses
-        i2c.readfrom_mem(0x42, 2, 3)        # read 3 bytes from memory of slave 0x42,
-                                            #   starting at address 2 in the slave
-        i2c.writeto_mem(0x42, 2, 'abc')     # write 'abc' (3 bytes) to memory of slave 0x42
-                                            # starting at address 2 in the slave, timeout after 1 second
-
 Constructors
 ------------
 
@@ -102,13 +74,6 @@ Constructors
          - ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)``
          - ``I2C(2)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PB10, PB11)``
 
-.. only:: port_wipy
-
-    .. class:: pyb.I2C(bus, ...)
-
-       Construct an I2C object on the given bus.  `bus` can only be 0.
-       If the bus is not given, the default one will be selected (0).
-
 Methods
 -------
 
@@ -179,54 +144,6 @@ Methods
 
        Return value: ``None``.
 
-.. only:: port_wipy
-
-    .. method:: i2c.init(mode, \*, baudrate=100000, pins=(SDA, SCL))
-
-      Initialise the I2C bus with the given parameters:
-
-         - ``mode`` must be ``I2C.MASTER``
-         - ``baudrate`` is the SCL clock rate
-         - ``pins`` is an optional tuple with the pins to assign to the I2C bus.
-
-    .. method:: i2c.readfrom(addr, nbytes)
-
-        Read ``nbytes`` from the slave specified by ``addr``.
-        Returns a ``bytes`` object with the data read.
-
-    .. method:: i2c.readfrom_into(addr, buf)
-
-        Read into ``buf`` from the slave specified by ``addr``.
-        Returns the number of bytes read.
-
-    .. method:: i2c.writeto(addr, buf, \*, stop=True)
-
-        Write ``buf`` to the slave specified by ``addr``. Set ``stop`` to ``False``
-        if the transfer should be continued.
-        Returns the number of bytes written.
-
-    .. method:: i2c.readfrom_mem(addr, memaddr, nbytes, \*, addrsize=8)
-
-        Read ``nbytes`` from the slave specified by ``addr`` starting from the memory
-        address specified by ``memaddr``.
-        Param ``addrsize`` specifies the address size in bits.
-        Returns a ``bytes`` object with the data read.
-
-    .. method:: i2c.readfrom_mem_into(addr, memaddr, buf, \*, addrsize=8)
-
-        Read into ``buf`` from the slave specified by ``addr`` starting from the memory
-        address specified by ``memaddr``.
-        Param ``addrsize`` specifies the address size in bits.
-        Returns the number of bytes read.
-
-    .. method:: i2c.writeto_mem(addr, memaddr, buf, \*, addrsize=8)
-
-        Write ``buf`` to the slave specified by ``addr`` starting from the
-        memory address specified by ``memaddr``. Param ``addrsize`` specifies the 
-        address size in bits.
-        Set ``stop`` to ``False`` if the transfer should be continued.
-        Returns the number of bytes written.
-
 .. method:: i2c.scan()
 
    Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst
index 01bd54fceece9eb845f80512e9f3bc672cc67499..30440f5025b7d2e5e8dd8de4f74a019230c4f783 100644
--- a/docs/library/pyb.Pin.rst
+++ b/docs/library/pyb.Pin.rst
@@ -63,24 +63,6 @@ Usage Model:
     that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND
     respectively (except pin Y5 which has 11k Ohm resistors).
 
-.. only:: port_wipy
-
-    Board pins are identified by their string id::
-
-        g = pyb.Pin('GP9', mode=pyb.Pin.OUT, pull=None, drive=pyb.Pin.MED_POWER, alt=-1)
-
-    You can also configure the Pin to generate interrupts. For instance::
-
-        def pincb(pin):
-            print(pin.id())
-
-        pin_int = pyb.Pin('GP10', mode=Pin.IN, pull=pyb.Pin.PULL_DOWN)
-        pin_int.irq(mode=pyb.Pin.IRQ_RISING, handler=pincb)
-        # the callback can be triggered manually
-        pin_int.irq()()
-        # to disable the callback
-        pin_int.irq().disable()
-
     Now every time a falling edge is seen on the gpio pin, the callback will be
     executed. Caution: mechanical push buttons have "bounce" and pushing or
     releasing a switch will often generate multiple edges.
@@ -149,42 +131,6 @@ Methods
        
        Returns: ``None``.
 
-.. only:: port_wipy
-
-    .. method:: pin.init(mode, pull, \*, drive, alt)
-    
-       Initialise the pin:
-
-         - ``mode`` can be one of:
-
-            - ``Pin.IN``  - input pin.
-            - ``Pin.OUT`` - output pin in push-pull mode.
-            - ``Pin.OPEN_DRAIN`` - output pin in open-drain mode.
-            - ``Pin.ALT`` - pin mapped to an alternate function.
-            - ``Pin.ALT_OPEN_DRAIN`` - pin mapped to an alternate function in open-drain mode.
-
-         - ``pull`` can be one of:
-
-            - ``None`` - no pull up or down resistor.
-            - ``Pin.PULL_UP`` - pull up resistor enabled.
-            - ``Pin.PULL_DOWN`` - pull down resitor enabled.
-
-         - ``drive`` can be one of:
-
-            - ``Pin.LOW_POWER`` - 2mA drive capability.
-            - ``Pin.MED_POWER`` - 4mA drive capability.
-            - ``Pin.HIGH_POWER`` - 6mA drive capability.
-
-         - ``alt`` is the number of the alternate function. Please refer to the
-           `pinout and alternate functions table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
-           for the specific alternate functions that each pin supports.
-
-       Returns: ``None``.
-
-    .. method:: pin.id()
-
-       Get the pin id.
-
 .. method:: pin.value([value])
 
    Get or set the digital logic level of the pin:
@@ -238,62 +184,6 @@ Methods
     will match one of the allowed constants for the pull argument to the init
     function.
 
-.. only:: port_wipy
-
-    .. method:: pin([value])
-
-       Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin.
-       See **pin.value** for more details.
-
-    .. method:: pin.toggle()
-
-        Toggle the value of the pin.
-
-    .. method:: pin.mode([mode])
-
-        Get or set the pin mode.
-
-    .. method:: pin.pull([pull])
-
-        Get or set the pin pull.
-
-    .. method:: pin.drive([drive])
-
-        Get or set the pin drive strength.
-
-    .. method:: pin.irq(\*, trigger, priority=1, handler=None, wake=None)
-
-        Create a callback to be triggered when the input level at the pin changes.
-
-            - ``trigger`` configures the pin level which can generate an interrupt. Possible values are:
-
-                - ``Pin.IRQ_FALLING`` interrupt on falling edge.
-                - ``Pin.IRQ_RISING`` interrupt on rising edge.
-                - ``Pin.IRQ_LOW_LEVEL`` interrupt on low level.
-                - ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level.
-              
-              The values can be *ORed* together, for instance mode=Pin.IRQ_FALLING | Pin.IRQ_RISING
-
-            - ``priority`` level of the interrupt. Can take values in the range 1-7.
-              Higher values represent higher priorities.
-            - ``handler`` is an optional function to be called when new characters arrive.
-            - ``wakes`` selects the power mode in which this interrupt can wake up the
-              board. Please note:
-
-              - If ``wake_from=pyb.Sleep.ACTIVE`` any pin can wake the board.
-              - If ``wake_from=pyb.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``,
-                ``GP11``, GP17`` or ``GP24`` can wake the board. Note that only 1
-                of this pins can be enabled as a wake source at the same time, so, only
-                the last enabled pin as a ``pyb.Sleep.SUSPENDED`` wake source will have effect.
-              - If ``wake_from=pyb.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``,
-                ``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the
-                6 pins can be enabled as a ``pyb.Sleep.HIBERNATE`` wake source at the same time.
-              - Values can be ORed to make a pin generate interrupts in more than one power
-                mode.
-
-            Returns a callback object.
-
-
 Constants
 ---------
 
@@ -335,44 +225,6 @@ Constants
     
        enable the pull-up resistor on the pin
 
-.. only:: port_wipy
-
-    .. data:: Pin.IN
-
-    .. data:: Pin.OUT
-    
-    .. data:: Pin.OPEN_DRAIN
-
-    .. data:: Pin.ALT
-
-    .. data:: Pin.ALT_OPEN_DRAIN
-
-       Selects the pin mode.
-
-    .. data:: Pin.PULL_UP
-
-    .. data:: Pin.PULL_DOWN
-    
-       Selectes the wether there's pull up/down resistor.
-
-    .. data:: Pin.LOW_POWER
-
-    .. data:: Pin.MED_POWER
-
-    .. data:: Pin.HIGH_POWER
-
-        Selects the drive strength.
-
-    .. data:: Pin.IRQ_FALLING
-
-    .. data:: Pin.IRQ_RISING
-
-    .. data:: Pin.IRQ_LOW_LEVEL
-
-    .. data:: Pin.IRQ_HIGH_LEVEL
-
-        Selects the IRQ trigger type.
-
 .. only:: port_pyboard
 
     class PinAF -- Pin Alternate Functions
diff --git a/docs/library/pyb.RTC.rst b/docs/library/pyb.RTC.rst
index 4b5f4e6b405f10a07dfb5867ae9f66f0662d4589..51b17deccf7d0631862a42cbf9aeba0a2f154b60 100644
--- a/docs/library/pyb.RTC.rst
+++ b/docs/library/pyb.RTC.rst
@@ -41,14 +41,6 @@ Methods
        ``weekday`` is 1-7 for Monday through Sunday.
        
        ``subseconds`` counts down from 255 to 0
-       
-   .. only:: port_wipy
-   
-       The 8-tuple has the following format:
-       
-           ``(year, month, day, weekday, hours, minutes, seconds, milliseconds)``
-       
-       ``weekday`` is 0-6 for Monday through Sunday.
 
 .. only:: port_pyboard
 
@@ -88,14 +80,3 @@ Methods
        usable calibration range is:
        (-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm
 
-.. only:: port_wipy
-
-    .. method:: rtc.callback(\*, value, handler=None, wake_from=pyb.Sleep.ACTIVE)
-    
-       Create a callback object triggered by a real time clock alarm.
-    
-          - ``value`` is the alarm timeout in milliseconds. This parameter is required.
-          - ``handler`` is the function to be called when the callback is triggered.
-          - ``wake_from`` specifies the power mode from where this interrupt can wake
-            up the system.
-
diff --git a/docs/library/pyb.SPI.rst b/docs/library/pyb.SPI.rst
index 3c540b2799ac2aff853f4f307f6d504f3e90ff74..73783c7d574b2cdc76b1de811d495e2412bb2b1e 100644
--- a/docs/library/pyb.SPI.rst
+++ b/docs/library/pyb.SPI.rst
@@ -26,18 +26,6 @@ there are 3 lines: SCK, MOSI, MISO.
         spi.send_recv(b'1234', buf)          # send 4 bytes and receive 4 into buf
         spi.send_recv(buf, buf)              # send/recv 4 bytes from/to buf
 
-.. only:: port_wipy
-
-    See usage model of I2C; SPI is very similar.  Main difference is
-    parameters to init the SPI bus::
-
-        from pyb import SPI
-        spi = SPI(1, SPI.MASTER, baudrate=1000000, polarity=0, phase=0, firstbit=SPI.MSB)
-
-    Only required parameter is mode, must be SPI.MASTER.  Polarity can be 0 or 
-    1, and is the level the idle clock line sits at.  Phase can be 0 or 1 to 
-    sample data on the first or second clock edge respectively.
-
 Constructors
 ------------
 
@@ -59,16 +47,6 @@ Constructors
        At the moment, the NSS pin is not used by the SPI driver and is free
        for other use.
 
-.. only:: port_wipy
-
-    .. class:: pyb.SPI(bus, ...)
-
-       Construct an SPI object on the given bus.  ``bus`` can be only 1.
-       With no additional parameters, the SPI object is created but not
-       initialised (it has the settings from the last initialisation of
-       the bus, if any).  If extra arguments are given, the bus is initialised.
-       See ``init`` for parameters of initialisation.
-
 Methods
 -------
 
@@ -102,43 +80,6 @@ Methods
        Printing the SPI object will show you the computed baudrate and the chosen
        prescaler.
 
-.. only:: port_wipy
-
-    .. method:: spi.init(mode, baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, pins=(CLK, MOSI, MISO))
-
-       Initialise the SPI bus with the given parameters:
-
-         - ``mode`` must be ``SPI.MASTER``.
-         - ``baudrate`` is the SCK clock rate.
-         - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
-         - ``phase`` can be 0 or 1 to sample data on the first or second clock edge
-           respectively.
-         - ``bits`` is the width of each transfer, accepted values are 8, 16 and 32.
-         - ``firstbit`` can be ``SPI.MSB`` only.
-         - ``pins`` is an optional tupple with the pins to assign to the SPI bus.
-
-    .. method:: spi.write(buf)
-
-        Write the data contained in ``buf``. 
-        Returns the number of bytes written.
-
-    .. method:: spi.read(nbytes, *, write=0x00)
-
-        Read the ``nbytes`` while writing the data specified by ``write``.
-        Return the number of bytes read.
-
-    .. method:: spi.readinto(buf, *, write=0x00)
-
-        Read into the buffer specified by ``buf`` while writing the data specified by
-        ``write``.
-        Return the number of bytes read.
-
-    .. method:: spi.write_readinto(write_buf, read_buf)
-
-        Write from ``write_buf`` and read into ``read_buf``. Both buffers must have the
-        same length.
-        Returns the number of bytes written
-
 .. only:: port_pyboard
 
     .. method:: spi.recv(recv, \*, timeout=5000)
@@ -187,13 +128,3 @@ Constants
     .. data:: SPI.MSB
     
        set the first bit to be the least or most significant bit
-
-.. only:: port_wipy
-
-    .. data:: SPI.MASTER
-
-       for initialising the SPI bus to master
-    
-    .. data:: SPI.MSB
-
-    set the first bit to be the most significant bit
diff --git a/docs/library/pyb.Timer.rst b/docs/library/pyb.Timer.rst
index ca1d4702e595b607828268879e32d113eddd3754..af28fb6787e8e279ac66e43728c3e4d3376a3f4a 100644
--- a/docs/library/pyb.Timer.rst
+++ b/docs/library/pyb.Timer.rst
@@ -41,50 +41,6 @@ class Timer -- control internal timers
     the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing.
     It is recommended to use the other timers in your programs.
 
-.. only:: port_wipy
-
-    Timers can be used for a great variety of tasks, calling a function periodically,
-    counting events, and generating a PWM signal are among the most common use cases.
-    Each timer consists of 2 16-bit channels and this channels can be tied together to
-    form 1 32-bit timer. The operating mode needs to be configured per timer, but then
-    the period (or the frequency) can be independently configured on each channel. 
-    By using the callback method, the timer event can call a Python function.
-
-    Example usage to toggle an LED at a fixed frequency::
-
-        tim = pyb.Timer(4)                                              # create a timer object using timer 4
-        tim.init(mode=Timer.PERIODIC)                                   # initialize it in periodic mode
-        tim_ch = tim.channel(Timer.A, freq=2)                           # configure channel A at a frequency of 2Hz
-        tim_ch.callback(handler=lambda t:led.toggle())                  # toggle a LED on every cycle of the timer
-
-    Example using named function for the callback::
-
-        tim = Timer(1, mode=Timer.PERIODIC)
-        tim_a = tim.channel(Timer.A, freq=1000)
-
-        led = Pin('GPIO2', af=0, mode=Pin.OUT)
-
-        def tick(timer):                # we will receive the timer object when being called
-            print(timer.time())         # show current timer's time value (is microseconds)
-            led.toggle()                # toggle the LED
-
-        tim_a.callback(handler=tick)
-
-    Further examples::
-
-        tim1 = pyb.Timer(2, mode=Timer.EVENT_COUNT)                     # initialize it capture mode
-        tim2 = pyb.Timer(1, mode=Timer.PWM)                             # initialize it in PWM mode
-        tim_ch = tim1.channel(Timer.A, freq=1, polarity=Timer.POSITIVE) # start the event counter with a frequency of 1Hz and triggered by positive edges
-        tim_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=50)       # start the PWM on channel B with a 50% duty cycle
-        tim_ch.time()                                                   # get the current time in usec (can also be set)
-        tim_ch.freq(20)                                                 # set the frequency (can also get)
-        tim_ch.duty_cycle(30)                                           # set the duty cycle to 30% (can also get)
-        tim_ch.duty_cycle(30, Timer.NEGATIVE)                           # set the duty cycle to 30% and change the polarity to negative
-        tim_ch.event_count()                                            # get the number of captured events
-        tim_ch.event_time()                                             # get the the time of the last captured event
-        tim_ch.period(2000000)                                          # change the period to 2 seconds
-
-
 *Note:* Memory can't be allocated during a callback (an interrupt) and so
 exceptions raised within a callback don't give much information.  See
 :func:`micropython.alloc_emergency_exception_buf` for how to get around this
@@ -102,13 +58,6 @@ Constructors
        arguments are given, then the timer is initialised by ``init(...)``.
        ``id`` can be 1 to 14, excluding 3.
 
-    .. only:: port_wipy
-    
-       Construct a new timer object of the given id.  If additional
-       arguments are given, then the timer is initialised by ``init(...)``.
-       ``id`` can be 1 to 4.
-
-
 Methods
 -------
 
@@ -161,30 +110,6 @@ Methods
        
         You must either specify freq or both of period and prescaler.
 
-.. only:: port_wipy
-
-    .. method:: timer.init(mode, \*, width=16)
-    
-       Initialise the timer. Example::
-       
-           tim.init(Timer.PERIODIC)             # periodic 16-bit timer
-           tim.init(Timer.ONE_SHOT, width=32)   # one shot 32-bit timer
-
-       Keyword arguments:
-       
-         - ``mode`` can be one of:
-         
-           - ``Timer.ONE_SHOT`` - The timer runs once until the configured 
-             period of the channel expires.
-           - ``Timer.PERIODIC`` - The timer runs periodically at the configured 
-             frequency of the channel.
-           - ``Timer.EDGE_TIME`` - Meaure the time pin level changes.
-           - ``Timer.EDGE_COUNT`` - Count the number of pin level changes.
-
-         - ``width`` must be either 16 or 32 (bits). For really low frequencies <= ~1Hz
-           (or large periods), 32-bit timers should be used. 32-bit mode is only available
-           for ``ONE_SHOT`` AND ``PERIODIC`` modes.
-
 .. method:: timer.deinit()
 
    Deinitialises the timer.
@@ -280,37 +205,6 @@ Methods
            ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=8000)
            ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=16000)
 
-.. only:: port_wipy
-
-    .. method:: timer.channel(channel, \**, freq, period, polarity=Timer.POSITIVE, duty_cycle=0)
-    
-       If only a channel identifier passed, then a previously initialized channel
-       object is returned (or ``None`` if there is no previous channel).
-       
-       Othwerwise, a TimerChannel object is initialized and returned.
-       
-       The operating mode is is the one configured to the Timer object that was used to
-       create the channel.
-
-       - ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``. 
-         If the width is 32-bit then it **must be** ``TIMER.A | TIMER.B``.
-
-       Keyword only arguments:
-
-         - ``freq`` sets the frequency in Hz.
-         - ``period`` sets the period in microseconds.
-
-         .. note::
-
-            Either ``freq`` or ``period`` must be given, never both.
-
-         - ``polarity`` this is applicable for:
-           
-           - ``PWM``, defines the polarity of the duty cycle
-           - ``EDGE_TIME`` and ``EDGE_COUNT``, defines the polarity of the pin level change to detect.
-             To detect both rising and falling edges, make ``polarity=Timer.POSITIVE | Timer.NEGATIVE``.
-         - ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0-100)
-
 .. only:: port_pyboard
 
     .. method:: timer.counter([value])
@@ -355,32 +249,6 @@ Methods
        ``fun`` is passed 1 argument, the timer object.
        If ``fun`` is ``None`` then the callback will be disabled.
 
-.. only:: port_wipy
-
-    .. method:: timerchannel.callback(\**, value, priority=1, handler=None)
-
-        The behavior of this callback is heaviliy dependent on the operating
-        mode of the timer channel:
-
-            - If mode is ``Timer.PERIODIC`` the callback is executed periodically
-              with the configured frequency or period.
-            - If mode is ``Timer.ONE_SHOT`` the callback is executed once when
-              the configured timer expires.
-            - If mode is ``Timer.EDGE_COUNT`` the callback is executed when reaching
-              the configured number of events (see ``value`` param below).
-            - If mode is ``Timer.PWM`` the callback is executed when reaching the duty
-              cycle value.
-
-        The accepted params are:
-
-            - ``priority`` level of the interrupt. Can take values in the range 1-7.
-              Higher values represent higher priorities.
-            - ``handler`` is an optional function to be called when the interrupt is triggered.
-            - ``value`` is **only valid** when in ``Timer.EDGE_COUNT`` mode and is used to set
-              the number of edge events that will trigger the interrupt.
-
-        Returns a callback object.
-
 .. only:: port_pyboard
 
     .. method:: timerchannel.capture([value])
@@ -411,29 +279,3 @@ Methods
        for which the pulse is active.  The value can be an integer or
        floating-point number for more accuracy.  For example, a value of 25 gives
        a duty cycle of 25%.
-
-.. only:: port_wipy
-
-    .. method:: timerchannel.freq([value])
-    
-       Get or set the timer channel frequency (in Hz).
-
-    .. method:: timerchannel.period([value])
-
-       Get or set the timer channel period (in microseconds).
-       
-    .. method:: timerchannel.time([value])
-
-       Get or set the timer channel current **time** value (in microseconds).
-    
-    .. method:: timerchannel.event_count()
-
-       Get the number of edge events counted.
-
-    .. method:: timerchannel.event_time()
-
-       Get the time of ocurrance of the last event.
-
-    .. method:: timerchannel.duty_cycle([value])
-     
-       Get or set the duty cycle of the PWM signal (in the range of 0-100).
diff --git a/docs/library/pyb.UART.rst b/docs/library/pyb.UART.rst
index ca1912ef3bfa3dc72b5f98bf1a770a870fb2a608..16b1a5b16cab71b50276eae52d378d364cae80e2 100644
--- a/docs/library/pyb.UART.rst
+++ b/docs/library/pyb.UART.rst
@@ -22,11 +22,6 @@ UART objects can be created and initialised using::
     *Note:* with parity=None, only 8 and 9 bits are supported.  With parity enabled,
     only 7 and 8 bits are supported.
 
-.. only:: port_wipy
-
-    Bits can be 5, 6, 7, 8.  Parity can be ``None``, ``UART.EVEN`` or ``UART.ODD``.  Stop can be 1 or 2.
-
-
 A UART object acts like a stream object and reading and writing is done
 using the standard stream methods::
 
@@ -50,12 +45,6 @@ using the standard stream methods::
     *Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
     Earlier versions use ``uart.send`` and ``uart.recv``.
 
-.. only:: port_wipy
-
-    To check if there is anything to be read, use::
-
-        uart.any()               # returns the number of characters available for reading
-
 Constructors
 ------------
 
@@ -77,14 +66,6 @@ Constructors
          - ``UART(3)`` is on ``YB``: ``(TX, RX) = (Y9, Y10) = (PB10, PB11)``
          - ``UART(2)`` is on: ``(TX, RX) = (X3, X4) = (PA2, PA3)``
 
-.. only:: port_wipy
-
-    .. class:: pyb.UART(bus, ...)
-    
-       Construct a UART object on the given bus.  ``bus`` can be 0 or 1.
-       If the bus is not given, the default one will be selected (0) or the selection
-       will be made based on the given pins.
-
 Methods
 -------
 
@@ -114,22 +95,6 @@ Methods
        *Note:* with parity=None, only 8 and 9 bits are supported.  With parity enabled,
        only 7 and 8 bits are supported.
 
-.. only:: port_wipy
-
-    .. method:: uart.init(baudrate=9600, bits=8, parity=None, stop=1, \*, pins=(TX, RX, RTS, CTS))
-    
-       Initialise the UART bus with the given parameters:
-    
-         - ``baudrate`` is the clock rate.
-         - ``bits`` is the number of bits per character, 7, 8 or 9.
-         - ``parity`` is the parity, ``None``, ``UART.EVEN`` or ``UART.ODD``.
-         - ``stop`` is the number of stop bits, 1 or 2.
-         - ``pins`` is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
-           Any of the pins can be None if one wants the UART to operate with limited functionality.
-           If the RTS pin is given the the RX pin must be given as well. The same applies to CTS. 
-           When no pins are given, then the default set of TX and RX pins is taken, and hardware 
-           flow control will be disabled. If pins=None, no pin assignment will be made.
-
 .. method:: uart.deinit()
 
    Turn off the UART bus.
@@ -145,12 +110,6 @@ Methods
       Write a single character on the bus.  ``char`` is an integer to write.
       Return value: ``None``.
 
-.. only:: port_wipy
-
-    .. method:: uart.any()
-
-       Return the number of characters available for reading.
-
 .. method:: uart.read([nbytes])
 
    Read characters.  If ``nbytes`` is specified then read at most that many bytes.
@@ -163,11 +122,6 @@ Methods
       Return value: a bytes object containing the bytes read in.  Returns ``b''``
       on timeout.
 
-   .. only:: port_wipy
-
-      Return value: a bytes object containing the bytes read in.  Returns ``b''``
-      on timeout.
-
 .. method:: uart.readall()
 
    Read as much data as possible.
@@ -204,43 +158,12 @@ Methods
 
       Return value: number of bytes written.
 
-   .. only:: port_wipy
-
-      Write the buffer of bytes to the bus.
-
-      Return value: number of bytes written.
-
 .. method:: uart.sendbreak()
 
    Send a break condition on the bus.  This drives the bus low for a duration
    of 13 bits.
    Return value: ``None``.
 
-.. only:: port_wipy
-
-    .. method:: uart.callback(value, priority=1, handler=None)
-
-       Create a callback to be triggered when data is received on the UART.
-
-           - ``value`` sets the size in bytes of the Rx buffer. Every character
-             received is put into this buffer as long as there's space free.
-           - ``priority`` level of the interrupt. Can take values in the range 1-7.
-             Higher values represent higher priorities.
-           - ``handler`` an optional function to be called when new characters arrive.
-
-       .. note::
-
-          The handler will be called whenever any of the following two conditions are met:
-          
-              - 4 new characters have been received.
-              - At least 1 new character is waiting in the Rx buffer and the Rx line has been
-                silent for the duration of 1 complete frame.
-
-          This means that when the handler function is called there might be 1, 2, 3 or 4
-          characters waiting.
-
-       Return a callback object.
-
 Constants
 ---------
 
@@ -250,9 +173,3 @@ Constants
     .. data:: UART.CTS
 
        to select the flow control type
-
-.. only:: port_wipy
-
-   .. data:: UART.RX_ANY
-
-       IRQ trigger sources
diff --git a/docs/library/pyb.rst b/docs/library/pyb.rst
index 98cb763ee362e0417701c433d4cd0d284a5c3b47..546e7e5787d7f9e782c9b97bc7dd696658ce0f5a 100644
--- a/docs/library/pyb.rst
+++ b/docs/library/pyb.rst
@@ -63,25 +63,14 @@ Time related functions
 Reset related functions
 -----------------------
 
-.. only:: port_pyboard
-
-    .. function:: hard_reset()
-    
-       Resets the pyboard in a manner similar to pushing the external RESET
-       button.
-
-.. only:: port_wipy
+.. function:: hard_reset()
 
-    .. function:: reset()
-    
-       Resets the WiPy in a manner similar to pushing the external RESET
-       button.
+   Resets the pyboard in a manner similar to pushing the external RESET
+   button.
 
-.. only:: port_pyboard
+.. function:: bootloader()
 
-    .. function:: bootloader()
-    
-       Activate the bootloader without BOOT\* pins.
+   Activate the bootloader without BOOT\* pins.
 
 Interrupt related functions
 ---------------------------
@@ -175,15 +164,6 @@ Power related functions
     
        See :meth:`rtc.wakeup` to configure a real-time-clock wakeup event.
 
-.. only:: port_wipy
-
-    .. function:: freq([sysclk])
-
-       Returns a tuple of clock frequencies: ``(sysclk)``
-       These correspond to:
-
-          - sysclk: frequency of the CPU
-
 Miscellaneous functions
 -----------------------
 
@@ -256,12 +236,6 @@ Miscellaneous functions
     
        Return a 30-bit hardware generated random number.
 
-.. only:: port_wipy
-
-    .. function:: rng()
-    
-       Return a 24-bit software generated random number.
-
 .. function:: sync()
 
    Sync all file systems.
@@ -272,13 +246,6 @@ Miscellaneous functions
     
        Returns a string of 12 bytes (96 bits), which is the unique ID of the MCU.
 
-.. only:: port_wipy
-
-    .. function:: unique_id()
-    
-       Returns a string of 6 bytes (48 bits), which is the unique ID of the MCU.
-       This also corresponds to the ``MAC address`` of the WiPy.
-
 Classes
 -------
 
@@ -303,19 +270,3 @@ Classes
        pyb.Timer.rst
        pyb.UART.rst
        pyb.USB_VCP.rst
-
-.. only:: port_wipy
-
-    .. toctree::
-       :maxdepth: 1
-    
-       pyb.ADC.rst
-       pyb.HeartBeat.rst
-       pyb.I2C.rst
-       pyb.Pin.rst
-       pyb.RTC.rst
-       pyb.SD.rst
-       pyb.SPI.rst
-       pyb.Timer.rst
-       pyb.UART.rst
-       pyb.WDT.rst
diff --git a/docs/library/time.rst b/docs/library/time.rst
index 8af8e37ba82655aa7da34d7fd71fc1cfffb8c7b1..0dc18afb434da0370a7bb608d62cdb757937bad6 100644
--- a/docs/library/time.rst
+++ b/docs/library/time.rst
@@ -44,6 +44,46 @@ Functions
     
        Sleep for the given number of seconds.
 
+.. only:: port_wipy
+
+    .. function::  sleep_ms(ms)
+
+       Delay for given number of milliseconds, should be positive or 0.
+
+    .. function::  sleep_us(us)
+
+       Delay for given number of microseconds, should be positive or 0
+
+    .. function::  ticks_ms()
+
+        Returns an increasing millisecond counter with arbitrary reference point, 
+        that wraps after some (unspecified) value. The value should be treated as 
+        opaque, suitable for use only with ticks_diff().
+
+    .. function::  ticks_us()
+
+       Just like ``ticks_ms`` above, but in microseconds.
+
+    .. function::  ticks_cpu()
+
+       Similar to ``ticks_ms`` and ``ticks_us``, but with higher resolution (usually CPU clocks).
+
+    .. function::  ticks_diff(old, new)
+
+       Measure period between consecutive calls to ticks_ms(), ticks_us(), or ticks_cpu(). 
+       The value returned by these functions may wrap around at any time, so directly 
+       subtracting them is not supported. ticks_diff() should be used instead. "old" value should 
+       actually precede "new" value in time, or result is undefined. This function should not be
+       used to measure arbitrarily long periods of time (because ticks_*() functions wrap around 
+       and usually would have short period). The expected usage pattern is implementing event 
+       polling with timeout::
+
+            # Wait for GPIO pin to be asserted, but at most 500us
+            start = time.ticks_us()
+            while pin.value() == 0:
+                if time.ticks_diff(start, time.ticks_us()) > 500:
+                    raise TimeoutError
+
 .. function:: time()
 
    Returns the number of seconds, as an integer, since 1/1/2000.
diff --git a/docs/wipy/general.rst b/docs/wipy/general.rst
index d3d2f66aca377e64a7aa2f87759f2bd227162660..b1f78da529a2ccc0372daf96c7a4151cab68a700 100644
--- a/docs/wipy/general.rst
+++ b/docs/wipy/general.rst
@@ -1,6 +1,28 @@
 General information about the WiPy
 ==================================
 
+No floating point support
+-------------------------
+
+Due to space reasons, there's no floating point support, and no math module. This
+means that floating point numbers cannot be used anywhere in the code, and that
+all divisions must be performed using '//' instead of '/'. Example::
+
+    r = 4 // 2  # this will work
+    r = 4 / 2   # this WON'T
+
+Before applying power
+---------------------
+
+.. warning:: 
+
+   The GPIO pins of the WiPy are NOT 5V tolerant, connecting them to voltages higer
+   than 3.6V will cause irreparable damage to the board. ADC pins, when configured 
+   in analog mode cannot withstand volatges above 1.8V. Keep these considerations in
+   mind when wiring your electronics.
+
+
+
 WLAN default behaviour
 ----------------------
 
@@ -28,6 +50,14 @@ Open your FTP client of choice and connect to:
 
 ``ftp://192.168.1.1``, ``user: micro``, ``password: python``
 
+The FTP server on the WiPy doesn't support active mode, only passive, so for instance
+if using the native unix ftp client, just after logging in::
+
+    ftp> passive
+
+Besides that, the FTP server only supports onw data connection at a time. Check out
+the Filezilla settings section below for more info.
+
 FileZilla settings
 ------------------
 Do not use the quick connect button, instead, open the site manager and create a new
@@ -46,8 +76,8 @@ inside ``/flash/sys/`` because it's actually saved bypassing the user file syste
 assured that it was successfully transferred, and it has been signed with a MD5 checksum to
 verify its integrity. Now, reset the MCU by pressing the switch on the board, or by typing::
 
-    import pyb
-    pyb.reset()
+    import machine
+    machine.reset()
 
 Boot modes
 ----------
@@ -91,7 +121,7 @@ The heart beat LED
 By default the heart beat LED flashes once every 4s to signal that the system is
 alive. This can be overridden through the HeartBeat class:
 
-``pyb.HeartBeat().disable()``
+``machine.HeartBeat().disable()``
 
 There are currently 2 kinds of errors that you might see:
 
diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst
index eb8a12e8be806e3291d982b69fadb784afe3d0ca..c99671752d6dc5b207927f542e26fe5f4ecab8bf 100644
--- a/docs/wipy/quickref.rst
+++ b/docs/wipy/quickref.rst
@@ -7,25 +7,28 @@ Quick reference for the WiPy
     :alt: WiPy pinout and alternate functions table
     :width: 800px
 
-General board control
----------------------
+General board control (including sleep modes)
+---------------------------------------------
+
+See :mod:`machine`. ::
 
-See :mod:`pyb`. ::
+    import machine
 
-    import pyb
+    help(machine) # display all members from the machine module
+    machine.freq() # get the CPU frequency
+    machine.unique_id() # return the 6-byte unique id of the board (the WiPy's MAC address)
 
-    help(pyb) # display all members from the pyb module
-    pyb.delay(50) # wait 50 milliseconds
-    pyb.millis() # number of milliseconds since boot-up
-    pyb.freq() # get the CPU frequency
-    pyb.unique_id() # return the 6-byte unique id of the board (the WiPy's MAC address)
+    machine.idle()        # average curernt decreases to (~12mA), any interrupts wakes it up
+    machine.sleep()       # everything except for WLAN is powered down (~950uA avg. current)
+                          # wakes from Pin, RTC or WLAN
+    machine.deepsleep()   # deepest sleep mode, MCU starts from reset. Wakes from Pin and RTC.
 
 Pins and GPIO
 -------------
 
-See :ref:`pyb.Pin <pyb.Pin>`. ::
+See :ref:`machine.Pin <machine.Pin>`. ::
 
-    from pyb import Pin
+    from machine import Pin
 
     # initialize GP2 in gpio mode (af=0) and make it an output
     p_out = Pin('GP2', mode=Pin.OUT)
@@ -35,16 +38,16 @@ See :ref:`pyb.Pin <pyb.Pin>`. ::
     p_out(True)
 
     # make GP1 an input with the pull-up enabled
-    p_in = Pin('GP1', mode=Pin.IN, pull = Pin.PULL_UP)
+    p_in = Pin('GP1', mode=Pin.IN, pull=Pin.PULL_UP)
     p_in() # get value, 0 or 1
 
 Timers
 ------
 
-See :ref:`pyb.Timer <pyb.Timer>` and :ref:`pyb.Pin <pyb.Pin>`. ::
+See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`. ::
 
-    from pyb import Timer
-    from pyb import Pin
+    from machine import Timer
+    from machine import Pin
 
     tim = Timer(1, mode=Timer.PERIODIC)
     tim_a = tim.channel(Timer.A, freq=1000)
@@ -52,18 +55,18 @@ See :ref:`pyb.Timer <pyb.Timer>` and :ref:`pyb.Pin <pyb.Pin>`. ::
     tim_a.freq(1) # 1 Hz
     
     p_out = Pin('GP2', af=0, mode=Pin.OUT)
-    tim_a.callback(handler=lambda t: p_out.toggle())
+    tim_a.irq(handler=lambda t: p_out.toggle())
 
 PWM (pulse width modulation)
 ----------------------------
 
-See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.Timer <pyb.Timer>`. ::
+See :ref:`machine.Pin <machine.Pin>` and :ref:`machine.Timer <machine.Timer>`. ::
 
-    from pyb import Timer
-    from pyb import Pin
+    from machine import Timer
+    from machine import Pin
 
-    # assign GP25 to alternate function 5 (PWM)
-    p_out = Pin('GP25', af=9, type=Pin.STD)
+    # assign GP25 to alternate function 9 (PWM)
+    p_out = Pin('GP25', mode=Pin.AF, af=9)
 
     # timer 2 in PWM mode and width must be 16 buts
     tim = Timer(2, mode=Timer.PWM, width=16)
@@ -74,9 +77,9 @@ See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.Timer <pyb.Timer>`. ::
 ADC (analog to digital conversion)
 ----------------------------------
 
-See :ref:`pyb.ADC <pyb.ADC>`. ::
+See :ref:`machine.ADC <machine.ADC>`. ::
 
-    from pyb import ADC
+    from machine import ADC
 
     adc = ADC()
     apin = adc.channel(pin='GP3')
@@ -85,19 +88,19 @@ See :ref:`pyb.ADC <pyb.ADC>`. ::
 UART (serial bus)
 -----------------
 
-See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.UART <pyb.UART>`. ::
+See :ref:`machine.Pin <machine.Pin>` and :ref:`machine.UART <machine.UART>`. ::
 
-    from pyb import Pin, UART
-    uart = UART(0, 9600)
+    from machine import Pin, UART
+    uart = UART(0, baudrate=9600)
     uart.write('hello')
     uart.read(5) # read up to 5 bytes
 
 SPI bus
 -------
 
-See :ref:`pyb.SPI <pyb.SPI>`. ::
+See :ref:`machine.SPI <machine.SPI>`. ::
 
-    from pyb SPI
+    from machine SPI
 
     # configure the SPI master @ 2MHz
     spi = SPI(0, SPI.MASTER, baudrate=200000, polarity=0, phase=0)
@@ -109,9 +112,9 @@ See :ref:`pyb.SPI <pyb.SPI>`. ::
 I2C bus
 -------
 
-See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.I2C <pyb.I2C>`. ::
+See :ref:`machine.Pin <machine.Pin>` and :ref:`machine.I2C <machine.I2C>`. ::
 
-    from pyb import Pin, I2C
+    from machine import Pin, I2C
     # configure the I2C bus
     i2c = I2C(0, I2C.MASTER, baudrate=100000)
     i2c.scan() # returns list of slave addresses
@@ -123,9 +126,9 @@ See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.I2C <pyb.I2C>`. ::
 Watchdog timer (WDT)
 --------------------
 
-See :ref:`pyb.WDT <pyb.WDT>`. ::
+See :ref:`machine.WDT <machine.WDT>`. ::
 
-    from pyb import WDT
+    from machine import WDT
 
     # enable the WDT with a timeout of 5s (1s is the minimum)
     wdt = WDT(timeout=5000)
@@ -134,79 +137,73 @@ See :ref:`pyb.WDT <pyb.WDT>`. ::
 Real time clock (RTC)
 ---------------------
 
-See :ref:`pyb.RTC <pyb.RTC>` and ``pyb.Sleep``. ::
+See :ref:`machine.RTC <machine.RTC>` ::
 
-    from pyb import RTC, Sleep
+    import machine
+    from machine import RTC
 
-    rtc = pyb.RTC()
-    rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
-    print(rtc.datetime())
+    rtc = machine.RTC() # init with default time and date
+    rtc = RTC(datetime=(2015, 8, 29, 9, 0, 0, 0, None)) # init with a specific time and date
+    print(rtc.now())
 
-    def some_handler (rtc_obj):
-        # trigger the callback again in 30s
-        rtc_obj.callback(value=30000, handler=some_handler)
+    def alarm_handler (rtc_o):
+        pass
+        # do some non blocking operations
+        # warning printing on an irq via telnet is not
+        # possible, only via UART 
 
-    # create a RTC alarm that expires in 30s
-    rtc.callback(value=30000, handler=some_handler, wake_from=Sleep.SUSPENDED)
+    # create a RTC alarm that expires after 5 seconds
+    rtc.alarm(time=5000, repeat=False)
+
+    # enable RTC interrupts
+    rtc_i = rtc.irq(trigger=RTC.ALARM0, handler=alarm_handler, wake=machine.SLEEP)
 
     # go into suspended mode waiting for the RTC alarm to expire and wake us up
-    Sleep.suspend()
+    machine.sleep()
 
 SD card
 -------
 
-See :ref:`pyb.SD <pyb.SD>`. ::
+See :ref:`machine.SD <machine.SD>`. ::
 
-    from pyb import SD
+    from machine import SD
     import os
 
-    # SD card pins need special configuration so we pass them to the constructor
     # clock pin, cmd pin, data0 pin
     sd = SD(pins=('GP10', 'GP11', 'GP15'))
+    # or use default ones for the expansion board
+    sd = SD()
     os.mount(sd, '/sd')
 
 WLAN (WiFi) 
 -----------
 
-See :ref:`network.WLAN <network.WLAN>` and ``pyb.Sleep``. ::
+See :ref:`network.WLAN <network.WLAN>` and :mod:`machine`. ::
 
+    import machine
     from network import WLAN
-    from pyb import Sleep
 
     # configure the WLAN subsystem in station mode (the default is AP)
-    wifi = WLAN(WLAN.STA)
+    wifi = WLAN(mode=WLAN.STA)
     # go for fixed IP settings
-    wifi.ifconfig(('192.168.0.107', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
+    wifi.ifconfig(config=('192.168.0.107', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
     wifi.scan()     # scan for available netrworks
-    wifi.connect(ssid='mynetwork', security=2, key='mynetworkkey')
+    wifi.connect(ssid='mynetwork', auth=(WLAN.WPA2, 'mynetworkkey'))
     while not wifi.isconnected():
         pass
     print(wifi.ifconfig())
     # enable wake on WLAN
-    wifi.callback(wake_from=Sleep.SUSPENDED)
+    wifi.irq(wake=machine.SLEEP)
     # go to sleep
-    Sleep.suspend()
+    machine.sleep()
     # now, connect to the FTP or the Telnet server and the WiPy will wake-up
 
-Sleep and power modes control
------------------------------
-
-See ``pyb.Sleep``. ::
-
-    from pyb import Sleep
-
-    Sleep.idle()        # lowest sleep mode (~12mA), any interrupts wakes it up
-    Sleep.suspend()     # everything except for WLAN is powered down (~950uA)
-                        # wakes from Pin, RTC or WLAN
-
-    Sleep.hibernate()   # deepest sleep mode, MCU starts from reset. Wakes from Pin and RTC.
-
 Heart beat LED
 --------------
 
-See :ref:`pyb.HeartBeat <pyb.HeartBeat>`. ::
+See :ref:`machine.HeartBeat <machine.HeartBeat>`. ::
 
-    from pyb import HeartBeat
+    from machine import HeartBeat
 
     # disable the heart beat indication (you are free to use this LED connected to GP25)
     HeartBeat().disable()