diff options
Diffstat (limited to 'docs/wipy')
-rw-r--r-- | docs/wipy/general.rst | 144 | ||||
-rw-r--r-- | docs/wipy/quickref.rst | 7 | ||||
-rw-r--r-- | docs/wipy/tutorial/index.rst | 1 | ||||
-rw-r--r-- | docs/wipy/tutorial/timer.rst | 70 |
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. |