summaryrefslogtreecommitdiffstatshomepage
path: root/docs/wipy
diff options
context:
space:
mode:
Diffstat (limited to 'docs/wipy')
-rw-r--r--docs/wipy/general.rst144
-rw-r--r--docs/wipy/quickref.rst7
-rw-r--r--docs/wipy/tutorial/index.rst1
-rw-r--r--docs/wipy/tutorial/timer.rst70
4 files changed, 219 insertions, 3 deletions
diff --git a/docs/wipy/general.rst b/docs/wipy/general.rst
index 0991dbaeaf..8b9b91c534 100644
--- a/docs/wipy/general.rst
+++ b/docs/wipy/general.rst
@@ -179,3 +179,147 @@ Details on sleep modes
* ``machine.sleep()``: 950uA (in WLAN STA mode). Wake sources are ``Pin``, ``RTC``
and ``WLAN``
* ``machine.deepsleep()``: ~350uA. Wake sources are ``Pin`` and ``RTC``.
+
+Additional details for machine.Pin
+----------------------------------
+
+On the WiPy board the pins are identified by their string id::
+
+ from machine import Pin
+ g = machine.Pin('GP9', mode=Pin.OUT, pull=None, drive=Pin.MED_POWER, alt=-1)
+
+You can also configure the Pin to generate interrupts. For instance::
+
+ from machine import Pin
+
+ def pincb(pin):
+ print(pin.id())
+
+ pin_int = Pin('GP10', mode=Pin.IN, pull=Pin.PULL_DOWN)
+ pin_int.irq(trigger=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.
+
+For the ``drive`` parameter the strengths are:
+
+ - ``Pin.LOW_POWER`` - 2mA drive capability.
+ - ``Pin.MED_POWER`` - 4mA drive capability.
+ - ``Pin.HIGH_POWER`` - 6mA drive capability.
+
+For the ``alt`` parameter please refer to the pinout and alternate functions
+table at <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
+for the specific alternate functions that each pin supports.
+
+For interrupts, the ``priority`` can take values in the range 1-7. And the
+``wake`` parameter has the following properties:
+
+ - 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.
+
+Additional Pin methods:
+
+.. method:: machine.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)``
+
+Additional details for machine.I2C
+----------------------------------
+
+On the WiPy there is a single hardware I2C peripheral, identified by "0". By
+default this is the peripheral that is used when constructing an I2C instance.
+The default pins are GP23 for SCL and GP13 for SDA, and one can create the
+default I2C peripheral simply by doing::
+
+ i2c = machine.I2C()
+
+The pins and frequency can be specified as::
+
+ i2c = machine.I2C(freq=400000, scl='GP23', sda='GP13')
+
+Only certain pins can be used as SCL/SDA. Please refer to the pinout for further
+information.
+
+Known issues
+------------
+
+Incompatible way to create SSL sockets
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SSL sockets need to be created the following way before wrapping them with.
+``ssl.wrap_socket``::
+
+ import socket
+ import ssl
+ s = socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC)
+ ss = ssl.wrap_socket(s)
+
+Certificates must be used in order to validate the other side of the connection, and also to
+authenticate ourselves with the other end. Such certificates must be stored as files using the
+FTP server, and they must be placed in specific paths with specific names.
+
+- The certificate to validate the other side goes in: **'/flash/cert/ca.pem'**
+- The certificate to authenticate ourselves goes in: **'/flash/cert/cert.pem'**
+- The key for our own certificate goes in: **'/flash/cert/private.key'**
+
+.. note::
+
+ When these files are stored, they are placed inside the internal **hidden** file system
+ (just like firmware updates), and therefore they are never visible.
+
+For instance to connect to the Blynk servers using certificates, take the file ``ca.pem`` located
+in the `blynk examples folder <https://github.com/wipy/wipy/tree/master/examples/blynk>`_.
+and put it in '/flash/cert/'. Then do::
+
+ import socket
+ import ssl
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC)
+ ss = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs='/flash/cert/ca.pem')
+ ss.connect(socket.getaddrinfo('cloud.blynk.cc', 8441)[0][-1])
+
+Incompatibilities in uhashlib module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Due to hardware implementation details of the WiPy, data must be buffered before being
+digested, which would make it impossible to calculate the hash of big blocks of data that
+do not fit in RAM. In this case, since most likely the total size of the data is known
+in advance, the size can be passed to the constructor and hence the HASH hardware engine
+of the WiPy can be properly initialized without needing buffering. If ``block_size`` is
+to be given, an initial chunk of ``data`` must be passed as well. **When using this extension,
+care must be taken to make sure that the length of all intermediate chunks (including the
+initial one) is a multiple of 4 bytes.** The last chunk may be of any length.
+
+Example::
+
+ hash = uhashlib.sha1('abcd1234', 1001) # length of the initial piece is multiple of 4 bytes
+ hash.update('1234') # also multiple of 4 bytes
+ ...
+ hash.update('12345') # last chunk may be of any length
+ hash.digest()
+
+Unrelated function in machine module
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. 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.
diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst
index ac7eec1328..f60c81f5fe 100644
--- a/docs/wipy/quickref.rst
+++ b/docs/wipy/quickref.rst
@@ -44,7 +44,8 @@ See :ref:`machine.Pin <machine.Pin>`. ::
Timers
------
-See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`. ::
+See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`.
+Timer ``id``'s take values from 0 to 3.::
from machine import Timer
from machine import Pin
@@ -102,7 +103,7 @@ See :ref:`machine.SPI <machine.SPI>`. ::
spi.write('hello')
spi.read(5) # receive 5 bytes on the bus
rbuf = bytearray(5)
- spi.write_readinto('hello', rbuf) # send a receive 5 bytes
+ spi.write_readinto('hello', rbuf) # send and receive 5 bytes
I2C bus
-------
@@ -111,7 +112,7 @@ See :ref:`machine.I2C <machine.I2C>`. ::
from machine import I2C
# configure the I2C bus
- i2c = I2C(0, I2C.MASTER, baudrate=100000)
+ i2c = I2C(baudrate=100000)
i2c.scan() # returns list of slave addresses
i2c.writeto(0x42, 'hello') # send 5 bytes to slave with address 0x42
i2c.readfrom(0x42, 5) # receive 5 bytes from slave
diff --git a/docs/wipy/tutorial/index.rst b/docs/wipy/tutorial/index.rst
index c3d51e2e5d..816de27b5a 100644
--- a/docs/wipy/tutorial/index.rst
+++ b/docs/wipy/tutorial/index.rst
@@ -14,4 +14,5 @@ for instructions see :ref:`OTA How-To <wipy_firmware_upgrade>`.
repl.rst
blynk.rst
wlan.rst
+ timer.rst
reset.rst
diff --git a/docs/wipy/tutorial/timer.rst b/docs/wipy/tutorial/timer.rst
new file mode 100644
index 0000000000..c87ac44959
--- /dev/null
+++ b/docs/wipy/tutorial/timer.rst
@@ -0,0 +1,70 @@
+Hardware timers
+===============
+
+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 two 16-bit channels and this channels can be tied together to
+form one 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::
+
+ from machine import Timer
+ from machine import Pin
+ led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
+ tim = Timer(3) # create a timer object using timer 3
+ tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode
+ tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz
+ tim_ch.irq(handler=lambda t:led.toggle(), trigger=Timer.TIMEOUT) # toggle a LED on every cycle of the timer
+
+Example using named function for the callback::
+
+ from machine import Timer
+ from machine import Pin
+ tim = Timer(1, mode=Timer.PERIODIC, width=32)
+ tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer
+
+ led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
+
+ def tick(timer): # we will receive the timer object when being called
+ global led
+ led.toggle() # toggle the LED
+
+ tim_a.irq(handler=tick, trigger=Timer.TIMEOUT) # create the interrupt
+
+Further examples::
+
+ from machine import Timer
+ tim1 = Timer(1, mode=Timer.ONE_SHOT) # initialize it in one shot mode
+ tim2 = Timer(2, mode=Timer.PWM) # initialize it in PWM mode
+ tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges
+ tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=5000) # start the PWM on channel B with a 50% duty cycle
+ tim2_ch.freq(20) # set the frequency (can also get)
+ tim2_ch.duty_cycle(3010) # set the duty cycle to 30.1% (can also get)
+ tim2_ch.duty_cycle(3020, Timer.NEGATIVE) # set the duty cycle to 30.2% and change the polarity to negative
+ tim2_ch.period(2000000) # change the period to 2 seconds
+
+
+Additional constants for Timer class
+------------------------------------
+
+.. data:: Timer.PWM
+
+ PWM timer operating mode.
+
+.. data:: Timer.A
+.. data:: Timer.B
+
+ Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when
+ using a 32-bit timer.
+
+.. data:: Timer.POSITIVE
+.. data:: Timer.NEGATIVE
+
+ Timer channel polarity selection (only relevant in PWM mode).
+
+.. data:: Timer.TIMEOUT
+.. data:: Timer.MATCH
+
+ Timer channel IRQ triggers.