Merge tag 'v1.9.3'

Introduction of ports subdirectory where all ports are moved to

The main change in this release is the introduction of a "ports/"
subdirectory at the top-level of the repository, and all of the ports are
moved here.  In the process the "stmhal" port is renamed to "stm32" to
better reflect the MCU that it targets.  In addition, the STM32 CMSIS and
HAL sources are moved to a new submodule called "stm32lib".

The bytecode has changed in this release, compared to the previous release,
and as a consequence the .mpy version number has increased to version 3.
This means that scripts compiled with the previous mpy-cross must be
recompiled to work with this new version.

There have also been various enhancements and optimisations, such as:
check for valid UTF-8 when creating str objects, support for reverse
special binary operations like __radd__, full domain checking in the math
module, support for floor-division and modulo in the viper emitter,
and addition of stack overflow checking when executing a regex.

The stm32 port sees improved support for F7 MCUs, addition of a new board
B_L475E_IOT01A based on the STM32L475, and support for the Wiznet W5500
chipset along with improved socket behaviour.

A detailed list of changes follows.

py core:
- objstr: startswith, endswith: check arg to be a string
- nlrx86,x64: replace #define of defined() with portable macro usage
- objtype: handle NotImplemented return from binary special methods
- objtype: mp_obj_class_lookup: improve debug logging
- map: remove unused new/free functions
- make m_malloc_fail() have void return type, since it doesn't return
- modstruct: in struct.pack, stop converting if there are no args left
- modstruct: check and prevent buffer-read overflow in struct unpacking
- modstruct: check and prevent buffer-write overflow in struct packing
- nlrthumb: get working again on standard Thumb arch (ie not Thumb2)
- objfloat: fix binary ops with incompatible objects
- obj: fix comparison of float/complex NaN with itself
- objtype: implement fallback for instance inplace special methods
- objtuple: properly implement comparison with incompatible types
- objstr: add check for valid UTF-8 when making a str from bytes
- objlist: properly implement comparison with incompatible types
- runtime0.h: move relational ops to the beginning of mp_binary_op_t
- runtime0.h: move MP_BINARY_OP_DIVMOD to the end of mp_binary_op_t
- objtype: make sure mp_binary_op_method_name has full size again
- runtime0.h: put inplace arith ops in front of normal operations
- builtinhelp: simplify code slightly by extracting object type
- runtime: implement dispatch for "reverse op" special methods
- nlrx86: fix building for Android/x86
- builtinhelp: change signature of help text var from pointer to array
- runtime.h: change empty mp_warning macro so var-args are non empty
- modbuiltins: implement abs() by dispatching to MP_UNARY_OP_ABS
- {objfloat,objcomplex}: optimise MP_UNARY_OP_ABS by reusing variables
- mpconfig.h: add note that using computed gotos in VM is not C99
- objstr: strip: don't strip "\0" by default
- objexcept: prevent infinite recursion when allocating exceptions
- stream: remove unnecessary checks for NULL return from vstr_add_len
- vstr: raise a RuntimeError if fixed vstr buffer overflows
- vm: use lowercase letter at start of exception message
- persistentcode: define mp_raw_code_save_file() for any unix target
- add config option to print warnings/errors to stderr
- objfloat: support raising a negative number to a fractional power
- objset: simplify set and frozenset by separating their locals dicts
- objset: check that RHS of a binary op is a set/frozenset
- objset: include the failed key in a KeyError raised from set.remove
- objtype: change type of enum-to-qstr table to uint16_t to save space
- objstr: make empty bytes object have a null-terminating byte
- mpprint: only check for null string printing when NDEBUG not defined
- objtype: clean up unary- and binary-op enum-to-qstr mapping tables
- persistentcode: bump .mpy version number to version 3
- bc: update opcode_format_table to match the bytecode
- modmath: add full checks for math domain errors
- modmath: convert log2 macro into a function
- formatfloat: don't print the negative sign of a NaN value
- formatfloat: use standard isinf, isnan funcs instead of custom ones
- modbuiltins: use existing utf8_get_char helper in builtin ord func
- emitnative: implement floor-division and modulo for viper emitter
- objtype: use CPython compatible method name for sizeof
- objtype: fit qstrs for special methods in byte type
- objtype: define all special methods if requested
- objtype: introduce MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS

extmod:
- modubinascii: only include uzlib/tinf.h when it's really needed
- modussl_mbedtls: allow to compile with MBEDTLS_DEBUG_C disabled
- machine_pinbase: put PinBase singleton in ROM
- re1.5: upgrade to v0.8.2, adds hook for stack overflow checking
- modure: add stack overflow checking when executing a regex
- uos_dupterm: update uos.dupterm() and helper funcs to have index
- uos_dupterm: swallow any errors from dupterm closing the stream
- vfs: replace VLA in proxy func with small, static sized array
- modussl: add finaliser support for ussl objects
- modussl_mbedtls: allow to compile with unix coverage build

lib:
- add new submodule, stm32lib containing STM32 CMSIS and HAL source
- embed/abort_: use mp_raise_msg helper function
- libm: fix tanhf so that it correctly handles +/- infinity args
- libm: remove implementation of log2f, use MP_NEED_LOG2 instead
- axtls: update, support for SSL_EAGAIN return code
- berkeley-db-1.xx: update, allow to override MINCACHE, DEFPSIZE

drivers:
- memory/spiflash: change from hard-coded soft SPI to generic SPI
- display/ssd1306.py: improve performance of graphics methods
- nrf24l01: make nRF24L01 test script more portable
- display/ssd1306: implement SSD1306_I2C poweron method
- display/ssd1306: make poweron() work the same with SSD1306_SPI
- wiznet5k: improve the performance of socket ops with threading
- wiznet5k: get low-level W5500 driver working

tools:
- upip: upgrade to 1.2.2
- pyboard: use repr() when quoting data in error messages
- pyboard: update docstring for additional device support

tests:
- object_new: better messages, check user __new__() method
- class_new: add checks for __init__ being called and other improvements
- class_new: add another testcase for __new__/__init__ interaction
- class_inplace_op: test for inplace op fallback to normal one
- run-bench-tests: update locations of executables, now in ports/
- class_reverse_op: test for reverse arith ops special methods
- run-tests: skip class_inplace_op for minimal profile
- run-tests: fix copy-paste mistake in var name
- cpydiff: add cases for locals() discrepancies
- extmod: add test for ure regexes leading to infinite recursion
- extmod: add test for '-' in character class in regex
- run-tests: close device under test using "finally"
- net_inet: update tls test to work with CPython and incl new site

unix port:
- rename modsocket.c to modusocket.c
- modusocket: remove #if MICROPY_SOCKET_EXTRA code blocks
- enable MICROPY_PY_REVERSE_SPECIAL_METHODS

stm32 port:
- modmachine: make machine.bootloader() work when MPU is enabled
- modmachine: improve support for sleep/deepsleep on F7 MCUs
- compute PLL freq table during build instead of at run time
- modmachine: for F7 MCU, save power by reducing internal volt reg
- boards/pllvalues.py: make script work with both Python 2 and 3
- Makefile: use lib/stm32lib instead of local cmsis and hal files
- remove cmsis and hal files, they are now a submodule
- Makefile: automatically fetch stm32lib submodule if needed
- update to new STM Cube HAL library
- fix clock initialisation of L4 MCUs
- rename stmhal port directory to stm32
- remove unused usbd_msc.c file
- boards: change remaining stm32f4xx_hal_conf.h to unix line ending
- boards: change linker scripts to use "K" instead of hex byte size
- boards: fix I2C1 pin mapping on NUCLEO_F401RE/F411RE boards
- i2c: when scanning for I2C devices only do 1 probe per address
- modnwwiznet5k: release the GIL on blocking network operations
- boards: add new board B_L475E_IOT01A based on STM32L475
- make-stmconst.py: make sure mpz const data lives in ROM
- timer: make pyb.Timer() instances persistent
- mpconfigport.h: add configuration for max periphs on L4 series
- usbdev: make the USBD callback struct const so it can go in ROM
- usbdev: change static function variable to non-static
- usbdev: put all CDC state in a struct
- usbdev: put all HID state in a struct
- usbdev: simplify CDC tx/rx buffer passing
- usbdev: simplify HID tx/rx buffer passing
- usbdev/core: add state parameter to all callback functions
- usbdev: put all state for the USB device driver in a struct
- usbdev: simplify pointers to MSC state and block dev operations
- usbdev: merge all global USB device state into a single struct
- usbdev: make device descriptor callbacks take a state pointer
- usbdev: move all the USB device descriptor state into its struct
- timer: enable ARPE so that timer freq can be changed smoothly
- modnwwiznet5k: get the IP address of an established socket
- boards: fix typos in stm32f767_af.csv table
- usbd_cdc_interface: don't reset CDC output buf on initialisation
- modnwwiznet5k: implement WIZNET5K.isconnected() method
- modusocket: make getaddrinfo() work when passed an IP address
- modusocket: return OSError(-2) if getaddrinfo fails
- mpconfigport.h: add MICROPY_THREAD_YIELD() macro
- modnwwiznet5k: add support for W5500 Ethernet chip
- modnwwiznet5k: increase SPI bus speed to 42MHz
- modnwwiznet5k: implement stream ioctl for the Wiznet driver
- mphalport: improve efficiency of mp_hal_stdout_tx_strn_cooked
- make uos.dupterm() conform to specs by using extmod version

cc3200 port:
- enable micropython.kbd_intr() method
- use standard implementation of keyboard interrupt

esp8266 port:
- rename axtls_helpers.c to posix_helpers.c
- posix_helpers: set ENOMEM on memory alloc failure
- set DEFPSIZE=1024, MINCACHE=3 for "btree" module
- esp_mphal: send data in chunks to mp_uos_dupterm_tx_strn
- modnetwork: add "bssid" keyword arg to WLAN.connect() method
- modules/webrepl_setup: add info about allowed password length

zephyr port:
- Makefile: revamp "test" target after ports were moved to ports/
- use CONFIG_NET_APP_SETTINGS to setup initial network addresses
- switch to interrupt-driven pull-style console

pic16bit port:
- add definition of SEEK_SET to unistd.h

docs:
- pyboard/tutorial: add "timeout=0" to UART in pass-through example
- more xrefs to "MicroPython port" in glossary
- library/network: fix ref to "socket" module (should be "usocket")
- machine.Signal: improve style/grammar and add usage example
- library: add description of "index" parameter to uos.dupterm()
- library/micropython: fix typo in RST formatting
- library/framebuf.rst: generalise constructor to all colour formats
- btree: describe page caching policy of the underlying implementation
- esp8266/tutorial: update neopixel with example of using 4 bbp
- library/network: clarify usage of "bssid" arg in connect() method
- pyboard/quickref: add info for Switch, RTC, CAN, Accel classes
- pyboard/tutorial: update now that yellow LED also supports PWM
- esp8266/quickref: add quickref info for RTC class
- library: add missing cross-ref links for classes in pyb module
- library/network: update docs to state that W5500 is supported
- uselect: document one-shot polling mode
- usocket: elaborate descriptions
- usocket: document inet_ntop(), inet_pton()
- library/network: add dhcp_hostname parameter
- reference/isr_rules: minor typo correction
- ussl: fix module name refs and use "MicroPython port" term
- esp8266/general: add section on TLS limitations
- usocket: document that settimeout() isn't supported by all ports
- ure: add "|" (alternative) to the list of supported operators
- reference/isr_rules.rst: add tutorial on use of micropython.schedule()

travis:
- use --upgrade when pip is installing cpp-coveralls
- update build command now that stm32 Wiznet config has changed

examples:
- hwconfig_console: add .on()/.off() methods

all:
- convert mp_uint_t to mp_unary_op_t/mp_binary_op_t where appropriate
- convert remaining "mp_uint_t n_args" to "size_t n_args"
- make new ports/ sub-directory and move all ports there
- update Makefiles and others to build with new ports/ dir layout
- remove inclusion of internal py header files
- use NULL instead of "" when calling mp_raise exception helpers

README:
- update "Dependencies" section
- add explicit section on contributing
- add gcc and arm-none-eabi-newlib to list of required components

.gitattributes:
- remove obsolete entries for stmhal/hal, stmhal/cmsis
- add entries for files that will move to ports/ dir
This commit is contained in:
Scott Shawcroft 2017-11-02 12:41:50 -07:00
commit 7b393bc406
105 changed files with 1011 additions and 481 deletions

View File

@ -145,3 +145,43 @@ or by an exeption, for example using try/finally::
# Use sock # Use sock
finally: finally:
sock.close() sock.close()
SSL/TLS limitations
~~~~~~~~~~~~~~~~~~~
ESP8266 uses `axTLS <http://axtls.sourceforge.net/>`_ library, which is one
of the smallest TLS libraries with the compatible licensing. However, it
also has some known issues/limitations:
1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve
cryptography (ECC). This means it can't work with sites which force
the use of these features (it works ok with classic RSA certifactes).
2. Half-duplex communication nature. axTLS uses a single buffer for both
sending and receiving, which leads to considerable memory saving and
works well with protocols like HTTP. But there may be problems with
protocols which don't follow classic request-response model.
Besides axTLS own limitations, the configuration used for MicroPython is
highly optimized for code size, which leads to additional limitations
(these may be lifted in the future):
3. Optimized RSA algorithms are not enabled, which may lead to slow
SSL handshakes.
4. Stored sessions are not supported (may allow faster repeated connections
to the same site in some circumstances).
Besides axTLS specific limitations described above, there's another generic
limitation with usage of TLS on the low-memory devices:
5. The TLS standard specifies the maximum length of the TLS record (unit
of TLS communication, the entire record must be buffered before it can
be processed) as 16KB. That's almost half of the available ESP8266 memory,
and inside a more or less advanced application would be hard to allocate
due to memory fragmentation issues. As a compromise, a smaller buffer is
used, with the idea that the most interesting usage for SSL would be
accessing various REST APIs, which usually require much smaller messages.
The buffers size is on the order of 5KB, and is adjusted from time to
time, taking as a reference being able to access https://google.com .
The smaller buffer hower means that some sites can't be accessed using
it, and it's not possible to stream large amounts of data.

View File

@ -223,6 +223,17 @@ and is accessed via the :ref:`machine.I2C <machine.I2C>` class::
buf = bytearray(10) # create a buffer with 10 bytes buf = bytearray(10) # create a buffer with 10 bytes
i2c.writeto(0x3a, buf) # write the given buffer to the slave i2c.writeto(0x3a, buf) # write the given buffer to the slave
Real time clock (RTC)
---------------------
See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
Deep-sleep mode Deep-sleep mode
--------------- ---------------

View File

@ -72,8 +72,7 @@ parameter should be `id`.
connection parameters. For various medium types, there are different connection parameters. For various medium types, there are different
sets of predefined/recommended parameters, among them: sets of predefined/recommended parameters, among them:
* WiFi: *bssid* keyword to connect by BSSID (MAC address) instead * WiFi: *bssid* keyword to connect to a specific BSSID (MAC address)
of access point name
.. method:: disconnect() .. method:: disconnect()
@ -225,7 +224,9 @@ parameter should be `id`.
============== ==============
This class allows you to control WIZnet5x00 Ethernet adaptors based on This class allows you to control WIZnet5x00 Ethernet adaptors based on
the W5200 and W5500 chipsets (only W5200 tested). the W5200 and W5500 chipsets. The particular chipset that is supported
by the firmware is selected at compile-time via the MICROPY_PY_WIZNET5K
option.
Example usage:: Example usage::
@ -269,6 +270,11 @@ parameter should be `id`.
Methods Methods
------- -------
.. method:: wiznet5k.isconnected()
Returns ``True`` if the physical Ethernet link is connected and up.
Returns ``False`` otherwise.
.. method:: wiznet5k.ifconfig([(ip, subnet, gateway, dns)]) .. method:: wiznet5k.ifconfig([(ip, subnet, gateway, dns)])
Get/set IP address, subnet mask, gateway and DNS. Get/set IP address, subnet mask, gateway and DNS.
@ -333,9 +339,12 @@ parameter should be `id`.
argument is passed. Otherwise, query current state if no argument is argument is passed. Otherwise, query current state if no argument is
provided. Most other methods require active interface. provided. Most other methods require active interface.
.. method:: wlan.connect(ssid, password) .. method:: wlan.connect(ssid=None, password=None, \*, bssid=None)
Connect to the specified wireless network, using the specified password. Connect to the specified wireless network, using the specified password.
If *bssid* is given then the connection will be restricted to the
access-point with that MAC address (the *ssid* must also be specified
in this case).
.. method:: wlan.disconnect() .. method:: wlan.disconnect()
@ -413,16 +422,17 @@ parameter should be `id`.
Following are commonly supported parameters (availability of a specific parameter Following are commonly supported parameters (availability of a specific parameter
depends on network technology type, driver, and `MicroPython port`). depends on network technology type, driver, and `MicroPython port`).
========= =========== ============= ===========
Parameter Description Parameter Description
========= =========== ============= ===========
mac MAC address (bytes) mac MAC address (bytes)
essid WiFi access point name (string) essid WiFi access point name (string)
channel WiFi channel (integer) channel WiFi channel (integer)
hidden Whether ESSID is hidden (boolean) hidden Whether ESSID is hidden (boolean)
authmode Authentication mode supported (enumeration, see module constants) authmode Authentication mode supported (enumeration, see module constants)
password Access password (string) password Access password (string)
========= =========== dhcp_hostname The DHCP hostname to use
============= ===========

View File

@ -1,4 +1,5 @@
.. currentmodule:: pyb .. currentmodule:: pyb
.. _pyb.Accel:
class Accel -- accelerometer control class Accel -- accelerometer control
==================================== ====================================

View File

@ -1,4 +1,5 @@
.. currentmodule:: pyb .. currentmodule:: pyb
.. _pyb.CAN:
class CAN -- controller area network communication bus class CAN -- controller area network communication bus
====================================================== ======================================================

View File

@ -1,4 +1,5 @@
.. currentmodule:: pyb .. currentmodule:: pyb
.. _pyb.LCD:
class LCD -- LCD control for the LCD touch-sensor pyskin class LCD -- LCD control for the LCD touch-sensor pyskin
======================================================== ========================================================

View File

@ -1,4 +1,5 @@
.. currentmodule:: pyb .. currentmodule:: pyb
.. _pyb.Switch:
class Switch -- switch object class Switch -- switch object
============================= =============================

View File

@ -1,4 +1,5 @@
.. currentmodule:: pyb .. currentmodule:: pyb
.. _pyb.USB_HID:
class USB_HID -- USB Human Interface Device (HID) class USB_HID -- USB Human Interface Device (HID)
================================================= =================================================

View File

@ -1,4 +1,5 @@
.. currentmodule:: pyb .. currentmodule:: pyb
.. _pyb.USB_VCP:
class USB_VCP -- USB virtual comm port class USB_VCP -- USB virtual comm port
====================================== ======================================

View File

@ -34,6 +34,8 @@ Supported operators are:
``'+?'`` ``'+?'``
``'|'``
``'()'`` ``'()'``
Grouping. Each group is capturing (a substring it captures can be accessed Grouping. Each group is capturing (a substring it captures can be accessed
with `match.group()` method). with `match.group()` method).

View File

@ -66,12 +66,18 @@ Methods
Tuples returned may contain more than 2 elements as described above. Tuples returned may contain more than 2 elements as described above.
.. method:: poll.ipoll([timeout]) .. method:: poll.ipoll(timeout=-1, flags=0)
Like :meth:`poll.poll`, but instead returns an iterator which yields Like :meth:`poll.poll`, but instead returns an iterator which yields
callee-owned tuples. This function provides efficient, allocation-free `callee-owned tuples`. This function provides efficient, allocation-free
way to poll on streams. way to poll on streams.
If *flags* is 1, one-shot behavior for events is employed: streams for
which events happened, event mask will be automatically reset (equivalent
to ``poll.modify(obj, 0)``), so new events for such a stream won't be
processed until new mask is set with `poll.modify()`. This behavior is
useful for asynchronous I/O schedulers.
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
:class: attention :class: attention

View File

@ -68,7 +68,16 @@ Functions
.. function:: socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP) .. function:: socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP)
Create a new socket using the given address family, socket type and protocol number. Create a new socket using the given address family, socket type and
protocol number. Note that specifying *proto* in most cases is not
required (and not recommended, as some MicroPython ports may omit
``IPPROTO_*`` constants). Instead, *type* argument will select needed
protocol automatically::
# Create STREAM TCP socket
socket(AF_INET, SOCK_STREAM)
# Create DGRAM UDP socket
socket(AF_INET, SOCK_DGRAM)
.. function:: getaddrinfo(host, port) .. function:: getaddrinfo(host, port)
@ -80,8 +89,8 @@ Functions
The following example shows how to connect to a given url:: The following example shows how to connect to a given url::
s = socket.socket() s = usocket.socket()
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1]) s.connect(usocket.getaddrinfo('www.micropython.org', 80)[0][-1])
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
:class: attention :class: attention
@ -96,13 +105,29 @@ Functions
from an exception object). The use of negative values is a provisional from an exception object). The use of negative values is a provisional
detail which may change in the future. detail which may change in the future.
.. function:: inet_ntop(af, bin_addr)
Convert a binary network address *bin_addr* of the given address family *af*
to a textual representation::
>>> usocket.inet_ntop(usocket.AF_INET, b"\x7f\0\0\1")
'127.0.0.1'
.. function:: inet_pton(af, txt_addr)
Convert a textual network address *txt_addr* of the given address family *af*
to a binary representation::
>>> usocket.inet_pton(usocket.AF_INET, "1.2.3.4")
b'\x01\x02\x03\x04'
Constants Constants
--------- ---------
.. data:: AF_INET .. data:: AF_INET
AF_INET6 AF_INET6
Address family types. Availability depends on a particular board. Address family types. Availability depends on a particular `MicroPython port`.
.. data:: SOCK_STREAM .. data:: SOCK_STREAM
SOCK_DGRAM SOCK_DGRAM
@ -112,7 +137,11 @@ Constants
.. data:: IPPROTO_UDP .. data:: IPPROTO_UDP
IPPROTO_TCP IPPROTO_TCP
IP protocol numbers. IP protocol numbers. Availability depends on a particular `MicroPython port`.
Note that you don't need to specify these in a call to `usocket.socket()`,
because `SOCK_STREAM` socket type automatically selects `IPPROTO_TCP`, and
`SOCK_DGRAM` - `IPPROTO_UDP`. Thus, the only real use of these constants
is as an argument to `setsockopt()`.
.. data:: usocket.SOL_* .. data:: usocket.SOL_*
@ -208,12 +237,30 @@ Methods
.. method:: socket.settimeout(value) .. method:: socket.settimeout(value)
**Note**: Not every port supports this method, see below.
Set a timeout on blocking socket operations. The value argument can be a nonnegative floating Set a timeout on blocking socket operations. The value argument can be a nonnegative floating
point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations
will raise an `OSError` exception if the timeout period value has elapsed before the operation has will raise an `OSError` exception if the timeout period value has elapsed before the operation has
completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket
is put in blocking mode. is put in blocking mode.
Not every `MicroPython port` supports this method. A more portable and
generic solution is to use `uselect.poll` object. This allows to wait on
multiple objects at the same time (and not just on sockets, but on generic
stream objects which support polling). Example::
# Instead of:
s.settimeout(1.0) # time in seconds
s.read(10) # may timeout
# Use:
poller = uselect.poll()
poller.register(s, uselect.POLLIN)
res = poller.poll(1000) # time in milliseconds
if not res:
# s is still not ready for input, i.e. operation timed out
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
:class: attention :class: attention
@ -281,7 +328,7 @@ Methods
Return value: number of bytes written. Return value: number of bytes written.
.. exception:: socket.error .. exception:: usocket.error
MicroPython does NOT have this exception. MicroPython does NOT have this exception.

View File

@ -13,7 +13,7 @@ facilities for network sockets, both client-side and server-side.
Functions Functions
--------- ---------
.. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None) .. function:: ussl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None)
Takes a stream *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type), Takes a stream *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type),
and returns an instance of ssl.SSLSocket, which wraps the underlying stream in and returns an instance of ssl.SSLSocket, which wraps the underlying stream in
@ -23,12 +23,12 @@ Functions
server-side SSL socket should be created from a normal socket returned from server-side SSL socket should be created from a normal socket returned from
`accept()` on a non-SSL listening server socket. `accept()` on a non-SSL listening server socket.
Depending on the underlying module implementation for a particular board, Depending on the underlying module implementation in a particular
some or all keyword arguments above may be not supported. `MicroPython port`, some or all keyword arguments above may be not supported.
.. warning:: .. warning::
Some implementations of ``ssl`` module do NOT validate server certificates, Some implementations of ``ussl`` module do NOT validate server certificates,
which makes an SSL connection established prone to man-in-the-middle attacks. which makes an SSL connection established prone to man-in-the-middle attacks.
Exceptions Exceptions
@ -41,8 +41,8 @@ Exceptions
Constants Constants
--------- ---------
.. data:: ssl.CERT_NONE .. data:: ussl.CERT_NONE
ssl.CERT_OPTIONAL ussl.CERT_OPTIONAL
ssl.CERT_REQUIRED ussl.CERT_REQUIRED
Supported values for *cert_reqs* parameter. Supported values for *cert_reqs* parameter.

View File

@ -39,17 +39,32 @@ Use the :mod:`time <utime>` module::
start = time.ticks_ms() # get value of millisecond counter start = time.ticks_ms() # get value of millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
LEDs Internal LEDs
---- -------------
See :ref:`pyb.LED <pyb.LED>`. :: See :ref:`pyb.LED <pyb.LED>`. ::
from pyb import LED from pyb import LED
led = LED(1) # red led led = LED(1) # 1=red, 2=green, 3=yellow, 4=blue
led.toggle() led.toggle()
led.on() led.on()
led.off() led.off()
# LEDs 3 and 4 support PWM intensity (0-255)
LED(4).intensity() # get intensity
LED(4).intensity(128) # set intensity to half
Internal switch
---------------
See :ref:`pyb.Switch <pyb.Switch>`. ::
from pyb import Switch
sw = Switch()
sw.value() # returns True or False
sw.callback(lambda: pyb.LED(1).toggle())
Pins and GPIO Pins and GPIO
------------- -------------
@ -99,6 +114,17 @@ See :ref:`pyb.Timer <pyb.Timer>`. ::
tim.freq(0.5) # 0.5 Hz tim.freq(0.5) # 0.5 Hz
tim.callback(lambda t: pyb.LED(1).toggle()) tim.callback(lambda t: pyb.LED(1).toggle())
RTC (real time clock)
---------------------
See :ref:`pyb.RTC <pyb.RTC>` ::
from pyb import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
PWM (pulse width modulation) PWM (pulse width modulation)
---------------------------- ----------------------------
@ -167,3 +193,25 @@ See :ref:`pyb.I2C <pyb.I2C>`. ::
i2c.recv(5, 0x42) # receive 5 bytes from slave i2c.recv(5, 0x42) # receive 5 bytes from slave
i2c.mem_read(2, 0x42, 0x10) # read 2 bytes from slave 0x42, slave memory 0x10 i2c.mem_read(2, 0x42, 0x10) # read 2 bytes from slave 0x42, slave memory 0x10
i2c.mem_write('xy', 0x42, 0x10) # write 2 bytes to slave 0x42, slave memory 0x10 i2c.mem_write('xy', 0x42, 0x10) # write 2 bytes to slave 0x42, slave memory 0x10
CAN bus (controller area network)
---------------------------------
See :ref:`pyb.CAN <pyb.CAN>`. ::
from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))
can.send('message!', 123) # send a message with id 123
can.recv(0) # receive message on FIFO 0
Internal accelerometer
----------------------
See :ref:`pyb.Accel <pyb.Accel>`. ::
from pyb import Accel
accel = Accel()
print(accel.x(), accel.y(), accel.z(), accel.tilt())

View File

@ -60,10 +60,10 @@ One problem you might find is that if you stop the script and then start it agai
for l in leds: for l in leds:
l.off() l.off()
The Fourth Special LED The Special LEDs
---------------------- ----------------
The blue LED is special. As well as turning it on and off, you can control the intensity using the intensity() method. This takes a number between 0 and 255 that determines how bright it is. The following script makes the blue LED gradually brighter then turns it off again. :: The yellow and blue LEDs are special. As well as turning them on and off, you can control their intensity using the intensity() method. This takes a number between 0 and 255 that determines how bright it is. The following script makes the blue LED gradually brighter then turns it off again. ::
led = pyb.LED(4) led = pyb.LED(4)
intensity = 0 intensity = 0
@ -72,4 +72,4 @@ The blue LED is special. As well as turning it on and off, you can control the i
led.intensity(intensity) led.intensity(intensity)
pyb.delay(20) pyb.delay(20)
You can call intensity() on the other LEDs but they can only be off or on. 0 sets them off and any other number up to 255 turns them on. You can call intensity() on LEDs 1 and 2 but they can only be off or on. 0 sets them off and any other number up to 255 turns them on.

View File

@ -80,7 +80,7 @@ example causes two LED's to flash at different rates.
self.led.toggle() self.led.toggle()
red = Foo(pyb.Timer(4, freq=1), pyb.LED(1)) red = Foo(pyb.Timer(4, freq=1), pyb.LED(1))
greeen = Foo(pyb.Timer(2, freq=0.8), pyb.LED(2)) green = Foo(pyb.Timer(2, freq=0.8), pyb.LED(2))
In this example the ``red`` instance associates timer 4 with LED 1: when a timer 4 interrupt occurs ``red.cb()`` In this example the ``red`` instance associates timer 4 with LED 1: when a timer 4 interrupt occurs ``red.cb()``
is called causing LED 1 to change state. The ``green`` instance operates similarly: a timer 2 interrupt is called causing LED 1 to change state. The ``green`` instance operates similarly: a timer 2 interrupt

View File

@ -1,7 +1,6 @@
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces # MicroPython SSD1306 OLED driver, I2C and SPI interfaces
from micropython import const from micropython import const
import time
import framebuf import framebuf
@ -47,7 +46,6 @@ class SSD1306:
self.text = fb.text self.text = fb.text
self.scroll = fb.scroll self.scroll = fb.scroll
self.blit = fb.blit self.blit = fb.blit
self.poweron()
self.init_display() self.init_display()
def init_display(self): def init_display(self):
@ -80,6 +78,9 @@ class SSD1306:
def poweroff(self): def poweroff(self):
self.write_cmd(SET_DISP | 0x00) self.write_cmd(SET_DISP | 0x00)
def poweron(self):
self.write_cmd(SET_DISP | 0x01)
def contrast(self, contrast): def contrast(self, contrast):
self.write_cmd(SET_CONTRAST) self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast) self.write_cmd(contrast)
@ -123,9 +124,6 @@ class SSD1306_I2C(SSD1306):
self.i2c.write(buf) self.i2c.write(buf)
self.i2c.stop() self.i2c.stop()
def poweron(self):
pass
class SSD1306_SPI(SSD1306): class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
@ -137,6 +135,12 @@ class SSD1306_SPI(SSD1306):
self.dc = dc self.dc = dc
self.res = res self.res = res
self.cs = cs self.cs = cs
import time
self.res(1)
time.sleep_ms(1)
self.res(0)
time.sleep_ms(10)
self.res(1)
super().__init__(width, height, external_vcc) super().__init__(width, height, external_vcc)
def write_cmd(self, cmd): def write_cmd(self, cmd):
@ -154,10 +158,3 @@ class SSD1306_SPI(SSD1306):
self.cs(0) self.cs(0)
self.spi.write(buf) self.spi.write(buf)
self.cs(1) self.cs(1)
def poweron(self):
self.res(1)
time.sleep_ms(1)
self.res(0)
time.sleep_ms(10)
self.res(1)

View File

@ -52,10 +52,9 @@
#include <string.h> #include <string.h>
#include "py/mpthread.h"
#include "socket.h" #include "socket.h"
extern void HAL_Delay(uint32_t);
#define SOCK_ANY_PORT_NUM 0xC000; #define SOCK_ANY_PORT_NUM 0xC000;
static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
@ -242,7 +241,7 @@ int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port)
#endif #endif
return SOCKERR_TIMEOUT; return SOCKERR_TIMEOUT;
} }
HAL_Delay(1); MICROPY_THREAD_YIELD();
} }
#if _WIZCHIP_ == 5200 // for W5200 ARP errata #if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00"); setSUBR((uint8_t*)"\x00\x00\x00\x00");
@ -317,6 +316,7 @@ int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len)
} }
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break; if(len <= freesize) break;
MICROPY_THREAD_YIELD();
} }
wiz_send_data(sn, buf, len); wiz_send_data(sn, buf, len);
#if _WIZCHIP_ == 5200 #if _WIZCHIP_ == 5200
@ -368,7 +368,7 @@ int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len)
} }
if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
if(recvsize != 0) break; if(recvsize != 0) break;
HAL_Delay(1); MICROPY_THREAD_YIELD();
}; };
if(recvsize < len) len = recvsize; if(recvsize < len) len = recvsize;
wiz_recv_data(sn, buf, len); wiz_recv_data(sn, buf, len);
@ -416,7 +416,7 @@ int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break; if(len <= freesize) break;
HAL_Delay(1); MICROPY_THREAD_YIELD();
}; };
wiz_send_data(sn, buf, len); wiz_send_data(sn, buf, len);
@ -446,7 +446,7 @@ int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t
return SOCKERR_TIMEOUT; return SOCKERR_TIMEOUT;
} }
//////////// ////////////
HAL_Delay(1); MICROPY_THREAD_YIELD();
} }
#if _WIZCHIP_ == 5200 // for W5200 ARP errata #if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00"); setSUBR((uint8_t*)"\x00\x00\x00\x00");
@ -486,6 +486,7 @@ int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
if(pack_len != 0) break; if(pack_len != 0) break;
MICROPY_THREAD_YIELD();
}; };
} }
sock_pack_info[sn] = PACK_COMPLETED; sock_pack_info[sn] = PACK_COMPLETED;

View File

@ -57,6 +57,16 @@
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
#define LPC_SSP0 (0)
static void Chip_SSP_ReadFrames_Blocking(int dummy, uint8_t *buf, uint32_t len) {
WIZCHIP.IF.SPI._read_bytes(buf, len);
}
static void Chip_SSP_WriteFrames_Blocking(int dummy, const uint8_t *buf, uint32_t len) {
WIZCHIP.IF.SPI._write_bytes(buf, len);
}
uint8_t WIZCHIP_READ(uint32_t AddrSel) uint8_t WIZCHIP_READ(uint32_t AddrSel)
{ {
uint8_t ret; uint8_t ret;

View File

@ -44,7 +44,6 @@
#include <stdint.h> #include <stdint.h>
#include "../wizchip_conf.h" #include "../wizchip_conf.h"
#include "board.h"
#define _W5500_IO_BASE_ 0x00000000 #define _W5500_IO_BASE_ 0x00000000

View File

@ -56,7 +56,9 @@
* @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n * @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n
* ex> <code> #define \_WIZCHIP_ 5500 </code> * ex> <code> #define \_WIZCHIP_ 5500 </code>
*/ */
#ifndef _WIZCHIP_
#define _WIZCHIP_ 5200 // 5100, 5200, 5500 #define _WIZCHIP_ 5200 // 5100, 5200, 5500
#endif
#define _WIZCHIP_IO_MODE_NONE_ 0x0000 #define _WIZCHIP_IO_MODE_NONE_ 0x0000
#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ #define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */

View File

@ -8,6 +8,12 @@ class LEDClass:
def value(self, v): def value(self, v):
print(self.id, v) print(self.id, v)
def on(self):
self.value(1)
def off(self):
self.value(0)
LED = LEDClass(1) LED = LEDClass(1)
LED2 = LEDClass(12) LED2 = LEDClass(12)

View File

@ -35,8 +35,9 @@
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
int mp_uos_dupterm_rx_chr(void);
void mp_uos_dupterm_tx_strn(const char *str, size_t len); void mp_uos_dupterm_tx_strn(const char *str, size_t len);
void mp_uos_deactivate(const char *msg, mp_obj_t exc); void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc);
#else #else
#define mp_uos_dupterm_tx_strn(s, l) #define mp_uos_dupterm_tx_strn(s, l)
#endif #endif

View File

@ -1032,7 +1032,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
break; break;
} }
case MOD_NETWORK_SOCK_DGRAM: case MOD_NETWORK_SOCK_DGRAM:
mp_raise_NotImplementedError(""); mp_raise_NotImplementedError(NULL);
break; break;
} }

View File

@ -51,7 +51,11 @@ struct ssl_args {
STATIC const mp_obj_type_t ussl_socket_type; STATIC const mp_obj_type_t ussl_socket_type;
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
#if MICROPY_PY_USSL_FINALISER
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
#else
mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
#endif
o->base.type = &ussl_socket_type; o->base.type = &ussl_socket_type;
o->buf = NULL; o->buf = NULL;
o->bytes_left = 0; o->bytes_left = 0;
@ -152,7 +156,7 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
// Currently supports only blocking mode // Currently supports only blocking mode
(void)self_in; (void)self_in;
if (!mp_obj_is_true(flag_in)) { if (!mp_obj_is_true(flag_in)) {
mp_raise_NotImplementedError(""); mp_raise_NotImplementedError(NULL);
} }
return mp_const_none; return mp_const_none;
} }
@ -178,6 +182,9 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) },
#if MICROPY_PY_USSL_FINALISER
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socket_close_obj) },
#endif
}; };
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);

View File

@ -65,23 +65,30 @@ struct ssl_args {
STATIC const mp_obj_type_t ussl_socket_type; STATIC const mp_obj_type_t ussl_socket_type;
void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { #ifdef MBEDTLS_DEBUG_C
STATIC void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) {
(void)ctx;
(void)level;
printf("DBG:%s:%04d: %s\n", file, line, str); printf("DBG:%s:%04d: %s\n", file, line, str);
} }
#endif
// TODO: FIXME! // TODO: FIXME!
int null_entropy_func(void *data, unsigned char *output, size_t len) { STATIC int null_entropy_func(void *data, unsigned char *output, size_t len) {
(void)data;
(void)output;
(void)len;
// enjoy random bytes // enjoy random bytes
return 0; return 0;
} }
int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) {
mp_obj_t sock = *(mp_obj_t*)ctx; mp_obj_t sock = *(mp_obj_t*)ctx;
const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_WRITE); const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_WRITE);
int err; int err;
int out_sz = sock_stream->write(sock, buf, len, &err); mp_uint_t out_sz = sock_stream->write(sock, buf, len, &err);
if (out_sz == MP_STREAM_ERROR) { if (out_sz == MP_STREAM_ERROR) {
if (mp_is_nonblocking_error(err)) { if (mp_is_nonblocking_error(err)) {
return MBEDTLS_ERR_SSL_WANT_WRITE; return MBEDTLS_ERR_SSL_WANT_WRITE;
@ -92,13 +99,13 @@ int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) {
} }
} }
int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
mp_obj_t sock = *(mp_obj_t*)ctx; mp_obj_t sock = *(mp_obj_t*)ctx;
const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_READ); const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_READ);
int err; int err;
int out_sz = sock_stream->read(sock, buf, len, &err); mp_uint_t out_sz = sock_stream->read(sock, buf, len, &err);
if (out_sz == MP_STREAM_ERROR) { if (out_sz == MP_STREAM_ERROR) {
if (mp_is_nonblocking_error(err)) { if (mp_is_nonblocking_error(err)) {
return MBEDTLS_ERR_SSL_WANT_READ; return MBEDTLS_ERR_SSL_WANT_READ;
@ -111,7 +118,11 @@ int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
#if MICROPY_PY_USSL_FINALISER
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
#else
mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
#endif
o->base.type = &ussl_socket_type; o->base.type = &ussl_socket_type;
int ret; int ret;
@ -272,6 +283,9 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) },
#if MICROPY_PY_USSL_FINALISER
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socket_close_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) }, { MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) },
}; };

View File

@ -146,7 +146,7 @@ STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
} }
mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref); mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 3) { if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 3) {
mp_raise_TypeError(""); mp_raise_TypeError(NULL);
} }
struct qentry *item = &heap->items[0]; struct qentry *item = &heap->items[0];

View File

@ -308,7 +308,7 @@ STATIC mp_obj_t webrepl_set_password(mp_obj_t passwd_in) {
size_t len; size_t len;
const char *passwd = mp_obj_str_get_data(passwd_in, &len); const char *passwd = mp_obj_str_get_data(passwd_in, &len);
if (len > sizeof(webrepl_passwd) - 1) { if (len > sizeof(webrepl_passwd) - 1) {
mp_raise_ValueError(""); mp_raise_ValueError(NULL);
} }
strcpy(webrepl_passwd, passwd); strcpy(webrepl_passwd, passwd);
return mp_const_none; return mp_const_none;

View File

@ -4,6 +4,7 @@
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2016 Paul Sokolovsky * Copyright (c) 2016 Paul Sokolovsky
* Copyright (c) 2017 Damien P. George
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -31,61 +32,114 @@
#include "py/objtuple.h" #include "py/objtuple.h"
#include "py/objarray.h" #include "py/objarray.h"
#include "py/stream.h" #include "py/stream.h"
#include "lib/utils/interrupt_char.h"
#ifdef MICROPY_PY_OS_DUPTERM #ifdef MICROPY_PY_OS_DUPTERM
void mp_uos_deactivate(const char *msg, mp_obj_t exc) { void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc) {
mp_obj_t term = MP_STATE_PORT(term_obj); mp_obj_t term = MP_STATE_VM(dupterm_objs[dupterm_idx]);
MP_STATE_PORT(term_obj) = NULL; MP_STATE_VM(dupterm_objs[dupterm_idx]) = MP_OBJ_NULL;
mp_printf(&mp_plat_print, msg); mp_printf(&mp_plat_print, msg);
if (exc != MP_OBJ_NULL) { if (exc != MP_OBJ_NULL) {
mp_obj_print_exception(&mp_plat_print, exc); mp_obj_print_exception(&mp_plat_print, exc);
} }
mp_stream_close(term); nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_stream_close(term);
nlr_pop();
} else {
// Ignore any errors during stream closing
}
}
int mp_uos_dupterm_rx_chr(void) {
for (size_t idx = 0; idx < MICROPY_PY_OS_DUPTERM; ++idx) {
if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) {
continue;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t readinto_m[3];
mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_readinto, readinto_m);
readinto_m[2] = MP_STATE_VM(dupterm_arr_obj);
mp_obj_t res = mp_call_method_n_kw(1, 0, readinto_m);
if (res == mp_const_none) {
nlr_pop();
} else if (res == MP_OBJ_NEW_SMALL_INT(0)) {
nlr_pop();
mp_uos_deactivate(idx, "dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
} else {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(MP_STATE_VM(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ);
nlr_pop();
if (*(byte*)bufinfo.buf == mp_interrupt_char) {
// Signal keyboard interrupt to be raised as soon as the VM resumes
mp_keyboard_interrupt();
return -2;
}
return *(byte*)bufinfo.buf;
}
} else {
mp_uos_deactivate(idx, "dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
}
}
// No chars available
return -1;
} }
void mp_uos_dupterm_tx_strn(const char *str, size_t len) { void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) { for (size_t idx = 0; idx < MICROPY_PY_OS_DUPTERM; ++idx) {
if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) {
continue;
}
nlr_buf_t nlr; nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) { if (nlr_push(&nlr) == 0) {
mp_obj_t write_m[3]; mp_obj_t write_m[3];
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_write, write_m); mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_write, write_m);
mp_obj_array_t *arr = MP_OBJ_TO_PTR(MP_STATE_PORT(dupterm_arr_obj)); mp_obj_array_t *arr = MP_OBJ_TO_PTR(MP_STATE_VM(dupterm_arr_obj));
void *org_items = arr->items; void *org_items = arr->items;
arr->items = (void*)str; arr->items = (void*)str;
arr->len = len; arr->len = len;
write_m[2] = MP_STATE_PORT(dupterm_arr_obj); write_m[2] = MP_STATE_VM(dupterm_arr_obj);
mp_call_method_n_kw(1, 0, write_m); mp_call_method_n_kw(1, 0, write_m);
arr = MP_OBJ_TO_PTR(MP_STATE_PORT(dupterm_arr_obj)); arr = MP_OBJ_TO_PTR(MP_STATE_VM(dupterm_arr_obj));
arr->items = org_items; arr->items = org_items;
arr->len = 1; arr->len = 1;
nlr_pop(); nlr_pop();
} else { } else {
mp_uos_deactivate("dupterm: Exception in write() method, deactivating: ", nlr.ret_val); mp_uos_deactivate(idx, "dupterm: Exception in write() method, deactivating: ", nlr.ret_val);
} }
} }
} }
STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) {
if (n_args == 0) { mp_int_t idx = 0;
if (MP_STATE_PORT(term_obj) == MP_OBJ_NULL) { if (n_args == 2) {
return mp_const_none; idx = mp_obj_get_int(args[1]);
} else {
return MP_STATE_PORT(term_obj);
}
} else {
if (args[0] == mp_const_none) {
MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
} else {
MP_STATE_PORT(term_obj) = args[0];
if (MP_STATE_PORT(dupterm_arr_obj) == MP_OBJ_NULL) {
MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
}
}
return mp_const_none;
} }
if (idx < 0 || idx >= MICROPY_PY_OS_DUPTERM) {
mp_raise_ValueError("invalid dupterm index");
}
mp_obj_t previous_obj = MP_STATE_VM(dupterm_objs[idx]);
if (previous_obj == MP_OBJ_NULL) {
previous_obj = mp_const_none;
}
if (args[0] == mp_const_none) {
MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL;
} else {
MP_STATE_VM(dupterm_objs[idx]) = args[0];
if (MP_STATE_VM(dupterm_arr_obj) == MP_OBJ_NULL) {
MP_STATE_VM(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
}
}
return previous_obj;
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj, 0, 1, mp_uos_dupterm); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj, 1, 2, mp_uos_dupterm);
#endif #endif

View File

@ -38,6 +38,10 @@
#include "extmod/vfs_fat.h" #include "extmod/vfs_fat.h"
#endif #endif
// For mp_vfs_proxy_call, the maximum number of additional args that can be passed.
// A fixed maximum size is used to avoid the need for a costly variable array.
#define PROXY_MAX_ARGS (2)
// path is the path to lookup and *path_out holds the path within the VFS // path is the path to lookup and *path_out holds the path within the VFS
// object (starts with / if an absolute path). // object (starts with / if an absolute path).
// Returns MP_VFS_ROOT for root dir (and then path_out is undefined) and // Returns MP_VFS_ROOT for root dir (and then path_out is undefined) and
@ -97,6 +101,7 @@ STATIC mp_vfs_mount_t *lookup_path(mp_obj_t path_in, mp_obj_t *path_out) {
} }
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
assert(n_args <= PROXY_MAX_ARGS);
if (vfs == MP_VFS_NONE) { if (vfs == MP_VFS_NONE) {
// mount point not found // mount point not found
mp_raise_OSError(MP_ENODEV); mp_raise_OSError(MP_ENODEV);
@ -105,7 +110,7 @@ STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_
// can't do operation on root dir // can't do operation on root dir
mp_raise_OSError(MP_EPERM); mp_raise_OSError(MP_EPERM);
} }
mp_obj_t meth[n_args + 2]; mp_obj_t meth[2 + PROXY_MAX_ARGS];
mp_load_method(vfs->obj, meth_name, meth); mp_load_method(vfs->obj, meth_name, meth);
if (args != NULL) { if (args != NULL) {
memcpy(meth + 2, args, n_args * sizeof(*args)); memcpy(meth + 2, args, n_args * sizeof(*args));

@ -1 +1 @@
Subproject commit 9b3092eb3b4b230a63c0c389bfbd3c55682c620f Subproject commit dac9176cac58cc5e49669a9a4d404a6f6dd7cc10

View File

@ -48,16 +48,6 @@ float copysignf(float x, float y) {
} }
#endif #endif
// some compilers define log2f in terms of logf
#ifdef log2f
#undef log2f
#endif
// some compilers have _M_LN2 defined in math.h, some don't
#ifndef _M_LN2
#define _M_LN2 (0.69314718055994530942)
#endif
float log2f(float x) { return logf(x) / (float)_M_LN2; }
static const float _M_LN10 = 2.30258509299404; // 0x40135d8e static const float _M_LN10 = 2.30258509299404; // 0x40135d8e
float log10f(float x) { return logf(x) / (float)_M_LN10; } float log10f(float x) { return logf(x) / (float)_M_LN10; }

View File

@ -159,41 +159,6 @@ void mp_hal_signal_input(void) {
#endif #endif
} }
static int call_dupterm_read(void) {
if (MP_STATE_PORT(term_obj) == NULL) {
return -1;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t readinto_m[3];
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_readinto, readinto_m);
readinto_m[2] = MP_STATE_PORT(dupterm_arr_obj);
mp_obj_t res = mp_call_method_n_kw(1, 0, readinto_m);
if (res == mp_const_none) {
nlr_pop();
return -2;
}
if (res == MP_OBJ_NEW_SMALL_INT(0)) {
mp_uos_deactivate("dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
nlr_pop();
return -1;
}
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(MP_STATE_PORT(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ);
nlr_pop();
if (*(byte*)bufinfo.buf == mp_interrupt_char) {
mp_keyboard_interrupt();
return -2;
}
return *(byte*)bufinfo.buf;
} else {
mp_uos_deactivate("dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
}
return -1;
}
STATIC void dupterm_task_handler(os_event_t *evt) { STATIC void dupterm_task_handler(os_event_t *evt) {
static byte lock; static byte lock;
if (lock) { if (lock) {
@ -201,7 +166,7 @@ STATIC void dupterm_task_handler(os_event_t *evt) {
} }
lock = 1; lock = 1;
while (1) { while (1) {
int c = call_dupterm_read(); int c = mp_uos_dupterm_rx_chr();
if (c < 0) { if (c < 0) {
break; break;
} }

View File

@ -149,7 +149,7 @@ mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t
// args[0] holds the id of the peripheral // args[0] holds the id of the peripheral
if (args[0] != MP_OBJ_NEW_SMALL_INT(1)) { if (args[0] != MP_OBJ_NEW_SMALL_INT(1)) {
// FlashROM is on SPI0, so far we don't support its usage // FlashROM is on SPI0, so far we don't support its usage
mp_raise_ValueError(""); mp_raise_ValueError(NULL);
} }
machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t); machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t);

View File

@ -51,7 +51,7 @@ STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args
case 0: case 0:
return &wdt_default; return &wdt_default;
default: default:
mp_raise_ValueError(""); mp_raise_ValueError(NULL);
} }
} }

View File

@ -101,8 +101,7 @@ STATIC void mp_reset(void) {
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR));
mp_obj_list_init(mp_sys_argv, 0); mp_obj_list_init(mp_sys_argv, 0);
MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
reset_pins(); reset_pins();
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
extern void esp_native_code_init(void); extern void esp_native_code_init(void);

View File

@ -93,29 +93,55 @@ STATIC mp_obj_t esp_active(size_t n_args, const mp_obj_t *args) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_active_obj, 1, 2, esp_active); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_active_obj, 1, 2, esp_active);
STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
require_if(args[0], STATION_IF); enum { ARG_ssid, ARG_password, ARG_bssid };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
// parse args
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
require_if(pos_args[0], STATION_IF);
struct station_config config = {{0}}; struct station_config config = {{0}};
size_t len; size_t len;
const char *p; const char *p;
bool set_config = false;
if (n_args > 1) { // set parameters based on given args
p = mp_obj_str_get_data(args[1], &len); if (args[ARG_ssid].u_obj != mp_const_none) {
p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len);
len = MIN(len, sizeof(config.ssid)); len = MIN(len, sizeof(config.ssid));
memcpy(config.ssid, p, len); memcpy(config.ssid, p, len);
if (n_args > 2) { set_config = true;
p = mp_obj_str_get_data(args[2], &len); }
len = MIN(len, sizeof(config.password)); if (args[ARG_password].u_obj != mp_const_none) {
memcpy(config.password, p, len); p = mp_obj_str_get_data(args[ARG_password].u_obj, &len);
len = MIN(len, sizeof(config.password));
memcpy(config.password, p, len);
set_config = true;
}
if (args[ARG_bssid].u_obj != mp_const_none) {
p = mp_obj_str_get_data(args[ARG_bssid].u_obj, &len);
if (len != sizeof(config.bssid)) {
mp_raise_ValueError(NULL);
} }
config.bssid_set = 1;
memcpy(config.bssid, p, sizeof(config.bssid));
set_config = true;
}
if (set_config) {
error_check(wifi_station_set_config(&config), "Cannot set STA config"); error_check(wifi_station_set_config(&config), "Cannot set STA config");
} }
error_check(wifi_station_connect(), "Cannot connect to AP"); error_check(wifi_station_connect(), "Cannot connect to AP");
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_connect_obj, 1, 7, esp_connect); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_connect_obj, 1, esp_connect);
STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) { STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) {
require_if(self_in, STATION_IF); require_if(self_in, STATION_IF);

View File

@ -16,12 +16,9 @@ def getpass(prompt):
def input_pass(): def input_pass():
while 1: while 1:
passwd1 = getpass("New password: ") passwd1 = getpass("New password (4-9 chars): ")
if len(passwd1) < 4: if len(passwd1) < 4 or len(passwd1) > 9:
print("Password too short") print("Invalid password length")
continue
elif len(passwd1) > 9:
print("Password too long")
continue continue
passwd2 = getpass("Confirm password: ") passwd2 = getpass("Confirm password: ")
if passwd1 == passwd2: if passwd1 == passwd2:

Binary file not shown.

View File

@ -287,13 +287,13 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\
class/src/usbd_msc_data.c \ class/src/usbd_msc_data.c \
) )
ifeq ($(MICROPY_PY_WIZNET5K),1) ifneq ($(MICROPY_PY_WIZNET5K),0)
WIZNET5K_DIR=drivers/wiznet5k WIZNET5K_DIR=drivers/wiznet5k
INC += -I$(TOP)/$(WIZNET5K_DIR) INC += -I$(TOP)/$(WIZNET5K_DIR)
CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=1 CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K)
SRC_MOD += modnwwiznet5k.c SRC_MOD += modnwwiznet5k.c
SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
ethernet/w5200/w5200.c \ ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
ethernet/wizchip_conf.c \ ethernet/wizchip_conf.c \
ethernet/socket.c \ ethernet/socket.c \
internet/dns/dns.c \ internet/dns/dns.c \

View File

@ -15,9 +15,9 @@ PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,LCD_R4,EVENTOUT
PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,SAI2_FS_B,CAN1_TX,OTG_FS_DP,,,,LCD_R5,EVENTOUT PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,SAI2_FS_B,CAN1_TX,OTG_FS_DP,,,,LCD_R5,EVENTOUT
PortA,PA13,JTMS,SWDIO,,,,,,,,,,,,,,EVENTOUT PortA,PA13,JTMS,SWDIO,,,,,,,,,,,,,,EVENTOUT
PortA,PA14,JTCK,SWCLK,,,,,,,,,,,,,,EVENTOUT PortA,PA14,JTCK,SWCLK,,,,,,,,,,,,,,EVENTOUT
PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,HDMICE,CSPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,,UART4_RTS,,,,,,,EVENTOUT PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,HDMICEC,SPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,,UART4_RTS,,,,,,,EVENTOUT
PortB,PB0,,TIM1_CH2N,TIM3_CH3T,IM8_CH2N,,,,,UART4_CTS,LCD_R3,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,EVENTOUT PortB,PB0,,TIM1_CH2N,TIM3_CH3T,TIM8_CH2N,,,,,UART4_CTS,LCD_R3,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,EVENTOUT
PortB,PB1,,TIM1_CH3N,TIM3_CH4T,IM8_CH3N,,,,,,LCD_R6,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,,EVENTOUT PortB,PB1,,TIM1_CH3N,TIM3_CH4T,TIM8_CH3N,,,,,,LCD_R6,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,,EVENTOUT
PortB,PB2,,,,,,,SAI1_SD_A,SPI3_MOSI/I2S3_SD,,QUADSPI_CLK,,,,,,EVENTOUT PortB,PB2,,,,,,,SAI1_SD_A,SPI3_MOSI/I2S3_SD,,QUADSPI_CLK,,,,,,EVENTOUT
PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK/I2S1_CK,SPI3_SCK/I2S3_CK,,,,SDMMC2_D2,,,,,EVENTOUT PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK/I2S1_CK,SPI3_SCK/I2S3_CK,,,,SDMMC2_D2,,,,,EVENTOUT
PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,SPI2_NSS/I2S2_WS,,,SDMMC2_D3,,,,,EVENTOUT PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,SPI2_NSS/I2S2_WS,,,SDMMC2_D3,,,,,EVENTOUT
@ -41,7 +41,7 @@ PortC,PC5,,,,,,,,,SPDIFRX_IN3,,,ETH_MII_RXD1/ETH_RMII_RXD1,FMC_SDCKE0,,,EVENTOUT
PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,SDMMC2_D6,,SDMMC1_D6,DCMI_D0,LCD_HSYNC,EVENTOUT PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,SDMMC2_D6,,SDMMC1_D6,DCMI_D0,LCD_HSYNC,EVENTOUT
PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,SDMMC2_D7,,SDMMC1_D7,DCMI_D1,LCD_G6,EVENTOUT PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,SDMMC2_D7,,SDMMC1_D7,DCMI_D1,LCD_G6,EVENTOUT
PortC,PC8,TRACED1,,TIM3_CH3,TIM8_CH3,,,,UART5_RTS,USART6_CK,,,,SDMMC1_D0,DCMI_D2,,EVENTOUT PortC,PC8,TRACED1,,TIM3_CH3,TIM8_CH3,,,,UART5_RTS,USART6_CK,,,,SDMMC1_D0,DCMI_D2,,EVENTOUT
PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,UART5_CTS,,QUADSPI_BK1_IO0,,,SDMMC1_D1,DCMI_D3,,EVENTOUT PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S2_CKIN,,UART5_CTS,,QUADSPI_BK1_IO0,,,SDMMC1_D1,DCMI_D3,,EVENTOUT
PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,QUADSPI_BK1_IO1,,,SDMMC1_D2,DCMI_D8,LCD_R2,EVENTOUT PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,QUADSPI_BK1_IO1,,,SDMMC1_D2,DCMI_D8,LCD_R2,EVENTOUT
PortC,PC11,,,,,,,SPI3_MISO,USART3_RX,UART4_RX,QUADSPI_BK2_NCS,,,SDMMC1_D3,DCMI_D4,,EVENTOUT PortC,PC11,,,,,,,SPI3_MISO,USART3_RX,UART4_RX,QUADSPI_BK2_NCS,,,SDMMC1_D3,DCMI_D4,,EVENTOUT
PortC,PC12,TRACED3,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDMMC1_CK,DCMI_D9,,EVENTOUT PortC,PC12,TRACED3,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDMMC1_CK,DCMI_D9,,EVENTOUT

1 Port AF0 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AF9 AF10 AF11 AF12 AF13 AF14 AF15
15 PortA PA12 TIM1_ETR USART1_RTS SAI2_FS_B CAN1_TX OTG_FS_DP LCD_R5 EVENTOUT
16 PortA PA13 JTMS SWDIO EVENTOUT
17 PortA PA14 JTCK SWCLK EVENTOUT
18 PortA PA15 JTDI TIM2_CH1/TIM2_ETR HDMICE HDMICEC CSPI1_NSS/I2S1_WS SPI1_NSS/I2S1_WS SPI3_NSS/I2S3_WS UART4_RTS EVENTOUT
19 PortB PB0 TIM1_CH2N TIM3_CH3T IM8_CH2N TIM8_CH2N UART4_CTS LCD_R3 OTG_HS_ULPI_D1 ETH_MII_RXD2 EVENTOUT
20 PortB PB1 TIM1_CH3N TIM3_CH4T IM8_CH3N TIM8_CH3N LCD_R6 OTG_HS_ULPI_D2 ETH_MII_RXD3 EVENTOUT
21 PortB PB2 SAI1_SD_A SPI3_MOSI/I2S3_SD QUADSPI_CLK EVENTOUT
22 PortB PB3 JTDO/TRACESWO TIM2_CH2 SPI1_SCK/I2S1_CK SPI3_SCK/I2S3_CK SDMMC2_D2 EVENTOUT
23 PortB PB4 NJTRST TIM3_CH1 SPI1_MISO SPI3_MISO SPI2_NSS/I2S2_WS SDMMC2_D3 EVENTOUT
41 PortC PC6 TIM3_CH1 TIM8_CH1 I2S2_MCK USART6_TX SDMMC2_D6 SDMMC1_D6 DCMI_D0 LCD_HSYNC EVENTOUT
42 PortC PC7 TIM3_CH2 TIM8_CH2 I2S3_MCK USART6_RX SDMMC2_D7 SDMMC1_D7 DCMI_D1 LCD_G6 EVENTOUT
43 PortC PC8 TRACED1 TIM3_CH3 TIM8_CH3 UART5_RTS USART6_CK SDMMC1_D0 DCMI_D2 EVENTOUT
44 PortC PC9 MCO2 TIM3_CH4 TIM8_CH4 I2C3_SDA I2S_CKIN I2S2_CKIN UART5_CTS QUADSPI_BK1_IO0 SDMMC1_D1 DCMI_D3 EVENTOUT
45 PortC PC10 SPI3_SCK/I2S3_CK USART3_TX UART4_TX QUADSPI_BK1_IO1 SDMMC1_D2 DCMI_D8 LCD_R2 EVENTOUT
46 PortC PC11 SPI3_MISO USART3_RX UART4_RX QUADSPI_BK2_NCS SDMMC1_D3 DCMI_D4 EVENTOUT
47 PortC PC12 TRACED3 SPI3_MOSI/I2S3_SD USART3_CK UART5_TX SDMMC1_CK DCMI_D9 EVENTOUT

View File

@ -125,7 +125,7 @@ STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin
if (ip == 0) { if (ip == 0) {
// unknown host // unknown host
return MP_ENOENT; return -2;
} }
out_ip[0] = ip >> 24; out_ip[0] = ip >> 24;

View File

@ -30,6 +30,7 @@
#include "py/objlist.h" #include "py/objlist.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#include "py/mphal.h" #include "py/mphal.h"
#include "lib/netutils/netutils.h" #include "lib/netutils/netutils.h"
@ -92,7 +93,7 @@ STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len,
return 0; return 0;
} else { } else {
// failure // failure
return MP_ENOENT; return -2;
} }
} }
@ -173,11 +174,7 @@ STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_
int sr = getSn_SR((uint8_t)socket->u_param.fileno); int sr = getSn_SR((uint8_t)socket->u_param.fileno);
if (sr == SOCK_ESTABLISHED) { if (sr == SOCK_ESTABLISHED) {
socket2->u_param = socket->u_param; socket2->u_param = socket->u_param;
// TODO need to populate this with the correct values getSn_DIPR((uint8_t)socket2->u_param.fileno, ip);
ip[0] = 0;
ip[1] = 0;
ip[2] = 0;
ip[3] = 0;
*port = getSn_PORT(socket2->u_param.fileno); *port = getSn_PORT(socket2->u_param.fileno);
// WIZnet turns the listening socket into the client socket, so we // WIZnet turns the listening socket into the client socket, so we
@ -309,9 +306,19 @@ STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_
} }
STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) {
// TODO if (request == MP_STREAM_POLL) {
*_errno = MP_EINVAL; int ret = 0;
return -1; if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) {
ret |= MP_STREAM_POLL_RD;
}
if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
} else {
*_errno = MP_EINVAL;
return MP_STREAM_ERROR;
}
} }
#if 0 #if 0
@ -350,7 +357,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size
wiznet5k_obj.spi->Init.CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle wiznet5k_obj.spi->Init.CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle
wiznet5k_obj.spi->Init.CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle wiznet5k_obj.spi->Init.CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle
wiznet5k_obj.spi->Init.NSS = SPI_NSS_SOFT; wiznet5k_obj.spi->Init.NSS = SPI_NSS_SOFT;
wiznet5k_obj.spi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz wiznet5k_obj.spi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz
wiznet5k_obj.spi->Init.FirstBit = SPI_FIRSTBIT_MSB; wiznet5k_obj.spi->Init.FirstBit = SPI_FIRSTBIT_MSB;
wiznet5k_obj.spi->Init.TIMode = SPI_TIMODE_DISABLED; wiznet5k_obj.spi->Init.TIMode = SPI_TIMODE_DISABLED;
wiznet5k_obj.spi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; wiznet5k_obj.spi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
@ -402,7 +409,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
if (i % 16 == 0) { if (i % 16 == 0) {
printf("\n %04x:", i); printf("\n %04x:", i);
} }
printf(" %02x", WIZCHIP_READ(i)); #if MICROPY_PY_WIZNET5K == 5200
uint32_t reg = i;
#else
uint32_t reg = _W5500_IO_BASE_ | i << 8;
#endif
printf(" %02x", WIZCHIP_READ(reg));
} }
for (int sn = 0; sn < 4; ++sn) { for (int sn = 0; sn < 4; ++sn) {
printf("\nWiz SREG[%d]:", sn); printf("\nWiz SREG[%d]:", sn);
@ -410,7 +422,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
if (i % 16 == 0) { if (i % 16 == 0) {
printf("\n %04x:", i); printf("\n %04x:", i);
} }
printf(" %02x", WIZCHIP_READ(WIZCHIP_SREG_ADDR(sn, i))); #if MICROPY_PY_WIZNET5K == 5200
uint32_t reg = WIZCHIP_SREG_ADDR(sn, i);
#else
uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3;
#endif
printf(" %02x", WIZCHIP_READ(reg));
} }
} }
printf("\n"); printf("\n");
@ -418,6 +435,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs); STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs);
STATIC mp_obj_t wiznet5k_isconnected(mp_obj_t self_in) {
(void)self_in;
return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_isconnected_obj, wiznet5k_isconnected);
/// \method ifconfig([(ip, subnet, gateway, dns)]) /// \method ifconfig([(ip, subnet, gateway, dns)])
/// Get/set IP address, subnet mask, gateway and DNS. /// Get/set IP address, subnet mask, gateway and DNS.
STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) {
@ -449,6 +472,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k
STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) }, { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) },
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) },
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table);

View File

@ -27,7 +27,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "py/obj.h" #include "py/runtime.h"
#include "py/gc.h" #include "py/gc.h"
#include "py/builtin.h" #include "py/builtin.h"
#include "py/mphal.h" #include "py/mphal.h"
@ -104,6 +104,28 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_micros_obj, pyb_elapsed_micros);
MP_DECLARE_CONST_FUN_OBJ_KW(pyb_main_obj); // defined in main.c MP_DECLARE_CONST_FUN_OBJ_KW(pyb_main_obj); // defined in main.c
// Get or set the UART object that the REPL is repeated on.
// This is a legacy function, use of uos.dupterm is preferred.
STATIC mp_obj_t pyb_repl_uart(size_t n_args, const mp_obj_t *args) {
if (n_args == 0) {
if (MP_STATE_PORT(pyb_stdio_uart) == NULL) {
return mp_const_none;
} else {
return MP_STATE_PORT(pyb_stdio_uart);
}
} else {
if (args[0] == mp_const_none) {
MP_STATE_PORT(pyb_stdio_uart) = NULL;
} else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
MP_STATE_PORT(pyb_stdio_uart) = args[0];
} else {
mp_raise_ValueError("need a UART object");
}
return mp_const_none;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart);
STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = { STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyb) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyb) },
@ -126,7 +148,7 @@ STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_sleep_obj) },
{ MP_ROM_QSTR(MP_QSTR_standby), MP_ROM_PTR(&machine_deepsleep_obj) }, { MP_ROM_QSTR(MP_QSTR_standby), MP_ROM_PTR(&machine_deepsleep_obj) },
{ MP_ROM_QSTR(MP_QSTR_main), MP_ROM_PTR(&pyb_main_obj) }, { MP_ROM_QSTR(MP_QSTR_main), MP_ROM_PTR(&pyb_main_obj) },
{ MP_ROM_QSTR(MP_QSTR_repl_uart), MP_ROM_PTR(&mod_os_dupterm_obj) }, { MP_ROM_QSTR(MP_QSTR_repl_uart), MP_ROM_PTR(&pyb_repl_uart_obj) },
{ MP_ROM_QSTR(MP_QSTR_usb_mode), MP_ROM_PTR(&pyb_usb_mode_obj) }, { MP_ROM_QSTR(MP_QSTR_usb_mode), MP_ROM_PTR(&pyb_usb_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_hid_mouse), MP_ROM_PTR(&pyb_usb_hid_mouse_obj) }, { MP_ROM_QSTR(MP_QSTR_hid_mouse), MP_ROM_PTR(&pyb_usb_hid_mouse_obj) },

View File

@ -33,6 +33,7 @@
#include "lib/timeutils/timeutils.h" #include "lib/timeutils/timeutils.h"
#include "lib/oofatfs/ff.h" #include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h" #include "lib/oofatfs/diskio.h"
#include "extmod/misc.h"
#include "extmod/vfs.h" #include "extmod/vfs.h"
#include "extmod/vfs_fat.h" #include "extmod/vfs_fat.h"
#include "genhdr/mpversion.h" #include "genhdr/mpversion.h"
@ -105,28 +106,6 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
#endif #endif
// Get or set the UART object that the REPL is repeated on.
// TODO should accept any object with read/write methods.
STATIC mp_obj_t os_dupterm(size_t n_args, const mp_obj_t *args) {
if (n_args == 0) {
if (MP_STATE_PORT(pyb_stdio_uart) == NULL) {
return mp_const_none;
} else {
return MP_STATE_PORT(pyb_stdio_uart);
}
} else {
if (args[0] == mp_const_none) {
MP_STATE_PORT(pyb_stdio_uart) = NULL;
} else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
MP_STATE_PORT(pyb_stdio_uart) = args[0];
} else {
mp_raise_ValueError("need a UART object");
}
return mp_const_none;
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_dupterm_obj, 0, 1, os_dupterm);
STATIC const mp_rom_map_elem_t os_module_globals_table[] = { STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
@ -154,7 +133,7 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
#endif #endif
// these are MicroPython extensions // these are MicroPython extensions
{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mod_os_dupterm_obj) }, { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) },
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },

View File

@ -390,29 +390,48 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
size_t hlen; size_t hlen;
const char *host = mp_obj_str_get_data(host_in, &hlen); const char *host = mp_obj_str_get_data(host_in, &hlen);
mp_int_t port = mp_obj_get_int(port_in); mp_int_t port = mp_obj_get_int(port_in);
uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
bool have_ip = false;
// find a NIC that can do a name lookup if (hlen > 0) {
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { // check if host is already in IP form
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; nlr_buf_t nlr;
mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); if (nlr_push(&nlr) == 0) {
if (nic_type->gethostbyname != NULL) { netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG);
uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; have_ip = true;
int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); nlr_pop();
if (ret != 0) { } else {
// TODO CPython raises: socket.gaierror: [Errno -2] Name or service not known // swallow exception: host was not in IP form so need to do DNS lookup
mp_raise_OSError(ret);
}
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
} }
} }
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); if (!have_ip) {
// find a NIC that can do a name lookup
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
if (nic_type->gethostbyname != NULL) {
int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
if (ret != 0) {
mp_raise_OSError(ret);
}
have_ip = true;
break;
}
}
}
if (!have_ip) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
}
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);

View File

@ -126,6 +126,7 @@
#define MICROPY_PY_USELECT (1) #define MICROPY_PY_USELECT (1)
#define MICROPY_PY_UTIMEQ (1) #define MICROPY_PY_UTIMEQ (1)
#define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_UTIME_MP_HAL (1)
#define MICROPY_PY_OS_DUPTERM (1)
#define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE (1)
#define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PULSE (1)
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
@ -326,6 +327,8 @@ static inline mp_uint_t disable_irq(void) {
__WFI(); \ __WFI(); \
} \ } \
} while (0); } while (0);
#define MICROPY_THREAD_YIELD() pyb_thread_yield()
#else #else
#define MICROPY_EVENT_POLL_HOOK \ #define MICROPY_EVENT_POLL_HOOK \
do { \ do { \
@ -333,8 +336,13 @@ static inline mp_uint_t disable_irq(void) {
mp_handle_pending(); \ mp_handle_pending(); \
__WFI(); \ __WFI(); \
} while (0); } while (0);
#define MICROPY_THREAD_YIELD()
#endif #endif
// We need an implementation of the log2 function which is not a macro
#define MP_NEED_LOG2 (1)
// There is no classical C heap in bare-metal ports, only Python // There is no classical C heap in bare-metal ports, only Python
// garbage-collected heap. For completeness, emulate C heap via // garbage-collected heap. For completeness, emulate C heap via
// GC heap. Note that MicroPython core never uses malloc() and friends, // GC heap. Note that MicroPython core never uses malloc() and friends,

View File

@ -1,6 +1,9 @@
# Enable/disable extra modules # Enable/disable extra modules
# wiznet5k module for ethernet support # wiznet5k module for ethernet support; valid values are:
# 0 : no Wiznet support
# 5200 : support for W5200 module
# 5500 : support for W5500 module
MICROPY_PY_WIZNET5K ?= 0 MICROPY_PY_WIZNET5K ?= 0
# cc3k module for wifi support # cc3k module for wifi support

View File

@ -3,6 +3,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#include "py/mphal.h" #include "py/mphal.h"
#include "extmod/misc.h"
#include "usb.h" #include "usb.h"
#include "uart.h" #include "uart.h"
@ -38,6 +39,10 @@ int mp_hal_stdin_rx_chr(void) {
} else if (MP_STATE_PORT(pyb_stdio_uart) != NULL && uart_rx_any(MP_STATE_PORT(pyb_stdio_uart))) { } else if (MP_STATE_PORT(pyb_stdio_uart) != NULL && uart_rx_any(MP_STATE_PORT(pyb_stdio_uart))) {
return uart_rx_char(MP_STATE_PORT(pyb_stdio_uart)); return uart_rx_char(MP_STATE_PORT(pyb_stdio_uart));
} }
int dupterm_c = mp_uos_dupterm_rx_chr();
if (dupterm_c >= 0) {
return dupterm_c;
}
MICROPY_EVENT_POLL_HOOK MICROPY_EVENT_POLL_HOOK
} }
} }
@ -56,15 +61,26 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
if (usb_vcp_is_enabled()) { if (usb_vcp_is_enabled()) {
usb_vcp_send_strn(str, len); usb_vcp_send_strn(str, len);
} }
mp_uos_dupterm_tx_strn(str, len);
} }
// Efficiently convert "\n" to "\r\n"
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) { void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
// send stdout to UART and USB CDC VCP const char *last = str;
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) { while (len--) {
uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len); if (*str == '\n') {
if (str > last) {
mp_hal_stdout_tx_strn(last, str - last);
}
mp_hal_stdout_tx_strn("\r\n", 2);
++str;
last = str;
} else {
++str;
}
} }
if (usb_vcp_is_enabled()) { if (str > last) {
usb_vcp_send_strn_cooked(str, len); mp_hal_stdout_tx_strn(last, str - last);
} }
} }

View File

@ -454,26 +454,11 @@ STATIC size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_
return num_tx; return num_tx;
} }
STATIC void uart_tx_char(pyb_uart_obj_t *uart_obj, int c) {
uint16_t ch = c;
int errcode;
uart_tx_data(uart_obj, &ch, 1, &errcode);
}
void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) { void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
int errcode; int errcode;
uart_tx_data(uart_obj, str, len, &errcode); uart_tx_data(uart_obj, str, len, &errcode);
} }
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
for (const char *top = str + len; str < top; str++) {
if (*str == '\n') {
uart_tx_char(uart_obj, '\r');
}
uart_tx_char(uart_obj, *str);
}
}
// this IRQ handler is set up to handle RXNE interrupts only // this IRQ handler is set up to handle RXNE interrupts only
void uart_irq_handler(mp_uint_t uart_id) { void uart_irq_handler(mp_uint_t uart_id) {
// get the uart object // get the uart object

View File

@ -48,6 +48,5 @@ void uart_irq_handler(mp_uint_t uart_id);
mp_uint_t uart_rx_any(pyb_uart_obj_t *uart_obj); mp_uint_t uart_rx_any(pyb_uart_obj_t *uart_obj);
int uart_rx_char(pyb_uart_obj_t *uart_obj); int uart_rx_char(pyb_uart_obj_t *uart_obj);
void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len); void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
#endif // MICROPY_INCLUDED_STMHAL_UART_H #endif // MICROPY_INCLUDED_STMHAL_UART_H

View File

@ -178,20 +178,6 @@ void usb_vcp_send_strn(const char *str, int len) {
#endif #endif
} }
void usb_vcp_send_strn_cooked(const char *str, int len) {
#ifdef USE_DEVICE_MODE
if (usb_device.enabled) {
for (const char *top = str + len; str < top; str++) {
if (*str == '\n') {
usbd_cdc_tx_always(&usb_device.usbd_cdc_itf, (const uint8_t*)"\r\n", 2);
} else {
usbd_cdc_tx_always(&usb_device.usbd_cdc_itf, (const uint8_t*)str, 1);
}
}
}
#endif
}
/******************************************************************************/ /******************************************************************************/
// MicroPython bindings for USB // MicroPython bindings for USB

View File

@ -63,7 +63,6 @@ void pyb_usb_dev_deinit(void);
bool usb_vcp_is_enabled(void); bool usb_vcp_is_enabled(void);
int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0 int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0
void usb_vcp_send_strn(const char* str, int len); void usb_vcp_send_strn(const char* str, int len);
void usb_vcp_send_strn_cooked(const char *str, int len);
void pyb_usb_host_init(void); void pyb_usb_host_init(void);
void pyb_usb_host_process(void); void pyb_usb_host_process(void);

View File

@ -57,10 +57,14 @@
#define CDC_SEND_BREAK 0x23 #define CDC_SEND_BREAK 0x23
uint8_t *usbd_cdc_init(usbd_cdc_itf_t *cdc, usbd_cdc_msc_hid_state_t *usbd) { uint8_t *usbd_cdc_init(usbd_cdc_itf_t *cdc, usbd_cdc_msc_hid_state_t *usbd) {
// Link the parent state
cdc->usbd = usbd; cdc->usbd = usbd;
// Reset all the CDC state
// Note: we don't reset tx_buf_ptr_in in order to allow the output buffer to
// be filled (by usbd_cdc_tx_always) before the USB device is connected.
cdc->rx_buf_put = 0; cdc->rx_buf_put = 0;
cdc->rx_buf_get = 0; cdc->rx_buf_get = 0;
cdc->tx_buf_ptr_in = 0;
cdc->tx_buf_ptr_out = 0; cdc->tx_buf_ptr_out = 0;
cdc->tx_buf_ptr_out_shadow = 0; cdc->tx_buf_ptr_out_shadow = 0;
cdc->tx_buf_ptr_wait_count = 0; cdc->tx_buf_ptr_wait_count = 0;

View File

@ -43,8 +43,8 @@ typedef struct _usbd_cdc_itf_t {
uint16_t rx_buf_get; // circular buffer index uint16_t rx_buf_get; // circular buffer index
uint8_t tx_buf[USBD_CDC_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer uint8_t tx_buf[USBD_CDC_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer
uint16_t tx_buf_ptr_in; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available uint16_t tx_buf_ptr_in; // increment this pointer modulo USBD_CDC_TX_DATA_SIZE when new data is available
volatile uint16_t tx_buf_ptr_out; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained volatile uint16_t tx_buf_ptr_out; // increment this pointer modulo USBD_CDC_TX_DATA_SIZE when data is drained
uint16_t tx_buf_ptr_out_shadow; // shadow of above uint16_t tx_buf_ptr_out_shadow; // shadow of above
uint8_t tx_buf_ptr_wait_count; // used to implement a timeout waiting for low-level USB driver uint8_t tx_buf_ptr_wait_count; // used to implement a timeout waiting for low-level USB driver
uint8_t tx_need_empty_packet; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size uint8_t tx_need_empty_packet; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size

View File

@ -49,6 +49,7 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) { void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
// send stdout to UART and USB CDC VCP // send stdout to UART and USB CDC VCP
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) { if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len); uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len);
} }
if (usb_vcp_is_enabled()) { if (usb_vcp_is_enabled()) {

View File

@ -426,11 +426,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_send_obj, 1, pyb_uart_send);
/// ///
/// Return value: if `recv` is an integer then a new buffer of the bytes received, /// Return value: if `recv` is an integer then a new buffer of the bytes received,
/// otherwise the same buffer that was passed in to `recv`. /// otherwise the same buffer that was passed in to `recv`.
#if 0
STATIC const mp_arg_t pyb_uart_recv_args[] = { STATIC const mp_arg_t pyb_uart_recv_args[] = {
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
}; };
#define PYB_UART_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_uart_recv_args) #define PYB_UART_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_uart_recv_args)
#endif
STATIC mp_obj_t pyb_uart_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { STATIC mp_obj_t pyb_uart_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// TODO assumes transmission size is 8-bits wide // TODO assumes transmission size is 8-bits wide

View File

@ -97,7 +97,7 @@ SRC_MOD += modtermios.c
endif endif
ifeq ($(MICROPY_PY_SOCKET),1) ifeq ($(MICROPY_PY_SOCKET),1)
CFLAGS_MOD += -DMICROPY_PY_SOCKET=1 CFLAGS_MOD += -DMICROPY_PY_SOCKET=1
SRC_MOD += modsocket.c SRC_MOD += modusocket.c
endif endif
ifeq ($(MICROPY_PY_THREAD),1) ifeq ($(MICROPY_PY_THREAD),1)
CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0

View File

@ -266,7 +266,7 @@ STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value)
return mp_const_none; return mp_const_none;
} }
} }
mp_raise_NotImplementedError(""); mp_raise_NotImplementedError(NULL);
} }
if (!JJ(IsInstanceOf, self->obj, List_class)) { if (!JJ(IsInstanceOf, self->obj, List_class)) {

View File

@ -60,8 +60,6 @@
should be add to separate modules (C or Python level). should be add to separate modules (C or Python level).
*/ */
#define MICROPY_SOCKET_EXTRA (0)
// This type must "inherit" from mp_obj_fdfile_t, i.e. matching subset of // This type must "inherit" from mp_obj_fdfile_t, i.e. matching subset of
// fields should have the same layout. // fields should have the same layout.
typedef struct _mp_obj_socket_t { typedef struct _mp_obj_socket_t {
@ -382,26 +380,6 @@ const mp_obj_type_t mp_type_socket = {
.locals_dict = (mp_obj_dict_t*)&usocket_locals_dict, .locals_dict = (mp_obj_dict_t*)&usocket_locals_dict,
}; };
#if MICROPY_SOCKET_EXTRA
STATIC mp_obj_t mod_socket_htons(mp_obj_t arg) {
return MP_OBJ_NEW_SMALL_INT(htons(MP_OBJ_SMALL_INT_VALUE(arg)));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_socket_htons_obj, mod_socket_htons);
STATIC mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) {
const char *s = mp_obj_str_get_str(arg);
struct hostent *h = gethostbyname(s);
if (h == NULL) {
// CPython: socket.herror
mp_raise_OSError(h_errno);
}
assert(h->h_length == 4);
return mp_obj_new_int(*(int*)*h->h_addr_list);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_socket_gethostbyname_obj, mod_socket_gethostbyname);
#endif // MICROPY_SOCKET_EXTRA
#define BINADDR_MAX_LEN sizeof(struct in6_addr) #define BINADDR_MAX_LEN sizeof(struct in6_addr)
STATIC mp_obj_t mod_socket_inet_pton(mp_obj_t family_in, mp_obj_t addr_in) { STATIC mp_obj_t mod_socket_inet_pton(mp_obj_t family_in, mp_obj_t addr_in) {
int family = mp_obj_get_int(family_in); int family = mp_obj_get_int(family_in);
@ -549,10 +527,6 @@ STATIC const mp_rom_map_elem_t mp_module_socket_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_inet_pton), MP_ROM_PTR(&mod_socket_inet_pton_obj) }, { MP_ROM_QSTR(MP_QSTR_inet_pton), MP_ROM_PTR(&mod_socket_inet_pton_obj) },
{ MP_ROM_QSTR(MP_QSTR_inet_ntop), MP_ROM_PTR(&mod_socket_inet_ntop_obj) }, { MP_ROM_QSTR(MP_QSTR_inet_ntop), MP_ROM_PTR(&mod_socket_inet_ntop_obj) },
{ MP_ROM_QSTR(MP_QSTR_sockaddr), MP_ROM_PTR(&mod_socket_sockaddr_obj) }, { MP_ROM_QSTR(MP_QSTR_sockaddr), MP_ROM_PTR(&mod_socket_sockaddr_obj) },
#if MICROPY_SOCKET_EXTRA
{ MP_ROM_QSTR(MP_QSTR_htons), MP_ROM_PTR(&mod_socket_htons_obj) },
{ MP_ROM_QSTR(MP_QSTR_gethostbyname), MP_ROM_PTR(&mod_socket_gethostbyname_obj) },
#endif
#define C(name) { MP_ROM_QSTR(MP_QSTR_ ## name), MP_ROM_INT(name) } #define C(name) { MP_ROM_QSTR(MP_QSTR_ ## name), MP_ROM_INT(name) }
C(AF_UNIX), C(AF_UNIX),

View File

@ -85,6 +85,7 @@
#define MICROPY_PY_BUILTINS_POW3 (1) #define MICROPY_PY_BUILTINS_POW3 (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_ALL_SPECIAL_METHODS (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
#define MICROPY_PY_SYS_EXIT (1) #define MICROPY_PY_SYS_EXIT (1)

View File

@ -108,11 +108,11 @@ void mp_hal_stdio_mode_orig(void) {
#endif #endif
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
static int call_dupterm_read(void) { static int call_dupterm_read(size_t idx) {
nlr_buf_t nlr; nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) { if (nlr_push(&nlr) == 0) {
mp_obj_t read_m[3]; mp_obj_t read_m[3];
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m); mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_read, read_m);
read_m[2] = MP_OBJ_NEW_SMALL_INT(1); read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m); mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
if (res == mp_const_none) { if (res == mp_const_none) {
@ -122,18 +122,18 @@ static int call_dupterm_read(void) {
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
if (bufinfo.len == 0) { if (bufinfo.len == 0) {
mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n"); mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
MP_STATE_PORT(term_obj) = NULL; MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL;
return -1; return -1;
} }
nlr_pop(); nlr_pop();
return *(byte*)bufinfo.buf; return *(byte*)bufinfo.buf;
} else { } else {
// Temporarily disable dupterm to avoid infinite recursion // Temporarily disable dupterm to avoid infinite recursion
mp_obj_t save_term = MP_STATE_PORT(term_obj); mp_obj_t save_term = MP_STATE_VM(dupterm_objs[idx]);
MP_STATE_PORT(term_obj) = NULL; MP_STATE_VM(dupterm_objs[idx]) = NULL;
mp_printf(&mp_plat_print, "dupterm: "); mp_printf(&mp_plat_print, "dupterm: ");
mp_obj_print_exception(&mp_plat_print, nlr.ret_val); mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
MP_STATE_PORT(term_obj) = save_term; MP_STATE_VM(dupterm_objs[idx]) = save_term;
} }
return -1; return -1;
@ -143,10 +143,11 @@ static int call_dupterm_read(void) {
int mp_hal_stdin_rx_chr(void) { int mp_hal_stdin_rx_chr(void) {
unsigned char c; unsigned char c;
#if MICROPY_PY_OS_DUPTERM #if MICROPY_PY_OS_DUPTERM
if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) { // TODO only support dupterm one slot at the moment
if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) {
int c; int c;
do { do {
c = call_dupterm_read(); c = call_dupterm_read(0);
} while (c == -2); } while (c == -2);
if (c == -1) { if (c == -1) {
goto main_term; goto main_term;

View File

@ -60,7 +60,9 @@ static char *stack_top;
static char heap[MICROPY_HEAP_SIZE]; static char heap[MICROPY_HEAP_SIZE];
void init_zephyr(void) { void init_zephyr(void) {
// TODO: Make addresses configurable // We now rely on CONFIG_NET_APP_SETTINGS to set up bootstrap
// network addresses.
#if 0
#ifdef CONFIG_NETWORKING #ifdef CONFIG_NETWORKING
if (net_if_get_default() == NULL) { if (net_if_get_default() == NULL) {
// If there's no default networking interface, // If there's no default networking interface,
@ -81,6 +83,7 @@ void init_zephyr(void) {
static struct in6_addr in6addr_my = {{{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}; static struct in6_addr in6addr_my = {{{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};
net_if_ipv6_addr_add(net_if_get_default(), &in6addr_my, NET_ADDR_MANUAL, 0); net_if_ipv6_addr_add(net_if_get_default(), &in6addr_my, NET_ADDR_MANUAL, 0);
#endif #endif
#endif
} }
int real_main(void) { int real_main(void) {

View File

@ -4,6 +4,12 @@ CONFIG_REBOOT=y
CONFIG_STDOUT_CONSOLE=y CONFIG_STDOUT_CONSOLE=y
CONFIG_CONSOLE_HANDLER=y CONFIG_CONSOLE_HANDLER=y
CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS=y CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS=y
CONFIG_CONSOLE_PULL=y
CONFIG_CONSOLE_GETCHAR=y
CONFIG_CONSOLE_GETCHAR_BUFSIZE=128
CONFIG_CONSOLE_PUTCHAR_BUFSIZE=128
CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC=y
CONFIG_FLOAT=y CONFIG_FLOAT=y
CONFIG_MAIN_STACK_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096
@ -18,6 +24,14 @@ CONFIG_NET_SOCKETS=y
CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_NBUF_RX_COUNT=5 CONFIG_NET_NBUF_RX_COUNT=5
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_INIT_TIMEOUT=3
CONFIG_NET_APP_NEED_IPV6=y
CONFIG_NET_APP_NEED_IPV4=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_APP_MY_IPV4_GW="192.0.2.2"
# DNS # DNS
CONFIG_DNS_RESOLVER=y CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2 CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2

View File

@ -1,3 +1,7 @@
# Interrupt-driven UART console has emulation artifacts under QEMU,
# disable it
CONFIG_CONSOLE_PULL=n
# Networking drivers # Networking drivers
# SLIP driver for QEMU # SLIP driver for QEMU
CONFIG_NET_SLIP_TAP=y CONFIG_NET_SLIP_TAP=y

View File

@ -1,3 +1,7 @@
# Interrupt-driven UART console has emulation artifacts under QEMU,
# disable it
CONFIG_CONSOLE_PULL=n
# Networking drivers # Networking drivers
# SLIP driver for QEMU # SLIP driver for QEMU
CONFIG_NET_SLIP_TAP=y CONFIG_NET_SLIP_TAP=y

View File

@ -24,11 +24,16 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <zephyr.h> #include <zephyr.h>
#include <console.h>
#include "zephyr_getchar.h" #include "zephyr_getchar.h"
int real_main(void); int real_main(void);
void main(void) { void main(void) {
#ifdef CONFIG_CONSOLE_PULL
console_init();
#else
zephyr_getchar_init(); zephyr_getchar_init();
#endif
real_main(); real_main();
} }

View File

@ -28,6 +28,7 @@
#include "src/zephyr_getchar.h" #include "src/zephyr_getchar.h"
// Zephyr headers // Zephyr headers
#include <uart.h> #include <uart.h>
#include <console.h>
/* /*
* Core UART functions to implement for a port * Core UART functions to implement for a port
@ -35,11 +36,23 @@
// Receive single character // Receive single character
int mp_hal_stdin_rx_chr(void) { int mp_hal_stdin_rx_chr(void) {
#ifdef CONFIG_CONSOLE_PULL
return console_getchar();
#else
return zephyr_getchar(); return zephyr_getchar();
#endif
} }
// Send string of given length // Send string of given length
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
#ifdef CONFIG_CONSOLE_PULL
while (len--) {
char c = *str++;
while (console_putchar(c) == -1) {
k_sleep(1);
}
}
#else
static struct device *uart_console_dev; static struct device *uart_console_dev;
if (uart_console_dev == NULL) { if (uart_console_dev == NULL) {
uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME); uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
@ -48,4 +61,5 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
while (len--) { while (len--) {
uart_poll_out(uart_console_dev, *str++); uart_poll_out(uart_console_dev, *str++);
} }
#endif
} }

View File

@ -136,11 +136,9 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args,
mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals); mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals);
} }
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || defined(_MSC_VER)
NORETURN void mp_arg_error_terse_mismatch(void) { NORETURN void mp_arg_error_terse_mismatch(void) {
mp_raise_TypeError("argument num/types mismatch"); mp_raise_TypeError("argument num/types mismatch");
} }
#endif
#if MICROPY_CPYTHON_COMPAT #if MICROPY_CPYTHON_COMPAT
NORETURN void mp_arg_error_unimpl_kw(void) { NORETURN void mp_arg_error_unimpl_kw(void) {

View File

@ -322,7 +322,7 @@ STATIC const byte opcode_format_table[64] = {
OC4(O, O, U, U), // 0x38-0x3b OC4(O, O, U, U), // 0x38-0x3b
OC4(U, O, B, O), // 0x3c-0x3f OC4(U, O, B, O), // 0x3c-0x3f
OC4(O, B, B, O), // 0x40-0x43 OC4(O, B, B, O), // 0x40-0x43
OC4(B, B, O, U), // 0x44-0x47 OC4(B, B, O, B), // 0x44-0x47
OC4(U, U, U, U), // 0x48-0x4b OC4(U, U, U, U), // 0x48-0x4b
OC4(U, U, U, U), // 0x4c-0x4f OC4(U, U, U, U), // 0x4c-0x4f
OC4(V, V, U, V), // 0x50-0x53 OC4(V, V, U, V), // 0x50-0x53
@ -362,7 +362,7 @@ STATIC const byte opcode_format_table[64] = {
OC4(B, B, B, B), // 0xcc-0xcf OC4(B, B, B, B), // 0xcc-0xcf
OC4(B, B, B, B), // 0xd0-0xd3 OC4(B, B, B, B), // 0xd0-0xd3
OC4(B, B, B, B), // 0xd4-0xd7 OC4(U, U, U, B), // 0xd4-0xd7
OC4(B, B, B, B), // 0xd8-0xdb OC4(B, B, B, B), // 0xd8-0xdb
OC4(B, B, B, B), // 0xdc-0xdf OC4(B, B, B, B), // 0xdc-0xdf
@ -373,7 +373,7 @@ STATIC const byte opcode_format_table[64] = {
OC4(B, B, B, B), // 0xf0-0xf3 OC4(B, B, B, B), // 0xf0-0xf3
OC4(B, B, B, B), // 0xf4-0xf7 OC4(B, B, B, B), // 0xf4-0xf7
OC4(B, B, B, U), // 0xf8-0xfb OC4(U, U, U, U), // 0xf8-0xfb
OC4(U, U, U, U), // 0xfc-0xff OC4(U, U, U, U), // 0xfc-0xff
}; };
#undef OC4 #undef OC4

View File

@ -113,7 +113,7 @@
#define MP_BC_LOAD_CONST_SMALL_INT_MULTI (0x70) // + N(64) #define MP_BC_LOAD_CONST_SMALL_INT_MULTI (0x70) // + N(64)
#define MP_BC_LOAD_FAST_MULTI (0xb0) // + N(16) #define MP_BC_LOAD_FAST_MULTI (0xb0) // + N(16)
#define MP_BC_STORE_FAST_MULTI (0xc0) // + N(16) #define MP_BC_STORE_FAST_MULTI (0xc0) // + N(16)
#define MP_BC_UNARY_OP_MULTI (0xd0) // + op(<MP_UNARY_OP_NON_BYTECODE) #define MP_BC_UNARY_OP_MULTI (0xd0) // + op(<MP_UNARY_OP_NUM_BYTECODE)
#define MP_BC_BINARY_OP_MULTI (0xd7) // + op(36) #define MP_BC_BINARY_OP_MULTI (0xd7) // + op(<MP_BINARY_OP_NUM_BYTECODE)
#endif // MICROPY_INCLUDED_PY_BC0_H #endif // MICROPY_INCLUDED_PY_BC0_H

View File

@ -123,6 +123,8 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
[MP_F_NEW_CELL] = 1, [MP_F_NEW_CELL] = 1,
[MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3, [MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3,
[MP_F_SETUP_CODE_STATE] = 5, [MP_F_SETUP_CODE_STATE] = 5,
[MP_F_SMALL_INT_FLOOR_DIVIDE] = 2,
[MP_F_SMALL_INT_MODULO] = 2,
}; };
#include "py/asmx86.h" #include "py/asmx86.h"
@ -1823,18 +1825,20 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
vtype_kind_t vtype_lhs = peek_vtype(emit, 1); vtype_kind_t vtype_lhs = peek_vtype(emit, 1);
vtype_kind_t vtype_rhs = peek_vtype(emit, 0); vtype_kind_t vtype_rhs = peek_vtype(emit, 0);
if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) { if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) {
// for integers, inplace and normal ops are equivalent, so use just normal ops
if (MP_BINARY_OP_INPLACE_OR <= op && op <= MP_BINARY_OP_INPLACE_POWER) {
op += MP_BINARY_OP_OR - MP_BINARY_OP_INPLACE_OR;
}
#if N_X64 || N_X86 #if N_X64 || N_X86
// special cases for x86 and shifting // special cases for x86 and shifting
if (op == MP_BINARY_OP_LSHIFT if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_RSHIFT) {
|| op == MP_BINARY_OP_INPLACE_LSHIFT
|| op == MP_BINARY_OP_RSHIFT
|| op == MP_BINARY_OP_INPLACE_RSHIFT) {
#if N_X64 #if N_X64
emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X64_REG_RCX, &vtype_lhs, REG_RET); emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X64_REG_RCX, &vtype_lhs, REG_RET);
#else #else
emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X86_REG_ECX, &vtype_lhs, REG_RET); emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X86_REG_ECX, &vtype_lhs, REG_RET);
#endif #endif
if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) { if (op == MP_BINARY_OP_LSHIFT) {
ASM_LSL_REG(emit->as, REG_RET); ASM_LSL_REG(emit->as, REG_RET);
} else { } else {
ASM_ASR_REG(emit->as, REG_RET); ASM_ASR_REG(emit->as, REG_RET);
@ -1843,35 +1847,48 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
return; return;
} }
#endif #endif
// special cases for floor-divide and module because we dispatch to helper functions
if (op == MP_BINARY_OP_FLOOR_DIVIDE || op == MP_BINARY_OP_MODULO) {
emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_2, &vtype_lhs, REG_ARG_1);
if (op == MP_BINARY_OP_FLOOR_DIVIDE) {
emit_call(emit, MP_F_SMALL_INT_FLOOR_DIVIDE);
} else {
emit_call(emit, MP_F_SMALL_INT_MODULO);
}
emit_post_push_reg(emit, VTYPE_INT, REG_RET);
return;
}
int reg_rhs = REG_ARG_3; int reg_rhs = REG_ARG_3;
emit_pre_pop_reg_flexible(emit, &vtype_rhs, &reg_rhs, REG_RET, REG_ARG_2); emit_pre_pop_reg_flexible(emit, &vtype_rhs, &reg_rhs, REG_RET, REG_ARG_2);
emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2); emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2);
if (0) { if (0) {
// dummy // dummy
#if !(N_X64 || N_X86) #if !(N_X64 || N_X86)
} else if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) { } else if (op == MP_BINARY_OP_LSHIFT) {
ASM_LSL_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_LSL_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (op == MP_BINARY_OP_RSHIFT || op == MP_BINARY_OP_INPLACE_RSHIFT) { } else if (op == MP_BINARY_OP_RSHIFT) {
ASM_ASR_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_ASR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
#endif #endif
} else if (op == MP_BINARY_OP_OR || op == MP_BINARY_OP_INPLACE_OR) { } else if (op == MP_BINARY_OP_OR) {
ASM_OR_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_OR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (op == MP_BINARY_OP_XOR || op == MP_BINARY_OP_INPLACE_XOR) { } else if (op == MP_BINARY_OP_XOR) {
ASM_XOR_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_XOR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (op == MP_BINARY_OP_AND || op == MP_BINARY_OP_INPLACE_AND) { } else if (op == MP_BINARY_OP_AND) {
ASM_AND_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_AND_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (op == MP_BINARY_OP_ADD || op == MP_BINARY_OP_INPLACE_ADD) { } else if (op == MP_BINARY_OP_ADD) {
ASM_ADD_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_ADD_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (op == MP_BINARY_OP_SUBTRACT || op == MP_BINARY_OP_INPLACE_SUBTRACT) { } else if (op == MP_BINARY_OP_SUBTRACT) {
ASM_SUB_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_SUB_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (op == MP_BINARY_OP_MULTIPLY || op == MP_BINARY_OP_INPLACE_MULTIPLY) { } else if (op == MP_BINARY_OP_MULTIPLY) {
ASM_MUL_REG_REG(emit->as, REG_ARG_2, reg_rhs); ASM_MUL_REG_REG(emit->as, REG_ARG_2, reg_rhs);
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
} else if (MP_BINARY_OP_LESS <= op && op <= MP_BINARY_OP_NOT_EQUAL) { } else if (MP_BINARY_OP_LESS <= op && op <= MP_BINARY_OP_NOT_EQUAL) {

View File

@ -30,6 +30,7 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <math.h>
#include "py/formatfloat.h" #include "py/formatfloat.h"
/*********************************************************************** /***********************************************************************
@ -68,12 +69,10 @@ union floatbits {
uint32_t u; uint32_t u;
}; };
static inline int fp_signbit(float x) { union floatbits fb = {x}; return fb.u & FLT_SIGN_MASK; } static inline int fp_signbit(float x) { union floatbits fb = {x}; return fb.u & FLT_SIGN_MASK; }
static inline int fp_isspecial(float x) { union floatbits fb = {x}; return (fb.u & FLT_EXP_MASK) == FLT_EXP_MASK; } #define fp_isnan(x) isnan(x)
static inline int fp_isinf(float x) { union floatbits fb = {x}; return (fb.u & FLT_MAN_MASK) == 0; } #define fp_isinf(x) isinf(x)
static inline int fp_iszero(float x) { union floatbits fb = {x}; return fb.u == 0; } static inline int fp_iszero(float x) { union floatbits fb = {x}; return fb.u == 0; }
static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u < 0x3f800000; } static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u < 0x3f800000; }
// Assumes both fp_isspecial() and fp_isinf() were applied before
#define fp_isnan(x) 1
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
@ -82,9 +81,7 @@ static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u <
#define FPROUND_TO_ONE 0.999999999995 #define FPROUND_TO_ONE 0.999999999995
#define FPDECEXP 256 #define FPDECEXP 256
#define FPMIN_BUF_SIZE 7 // +9e+199 #define FPMIN_BUF_SIZE 7 // +9e+199
#include <math.h>
#define fp_signbit(x) signbit(x) #define fp_signbit(x) signbit(x)
#define fp_isspecial(x) 1
#define fp_isnan(x) isnan(x) #define fp_isnan(x) isnan(x)
#define fp_isinf(x) isinf(x) #define fp_isinf(x) isinf(x)
#define fp_iszero(x) (x == 0) #define fp_iszero(x) (x == 0)
@ -122,7 +119,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
} }
return buf_size >= 2; return buf_size >= 2;
} }
if (fp_signbit(f)) { if (fp_signbit(f) && !fp_isnan(f)) {
*s++ = '-'; *s++ = '-';
f = -f; f = -f;
} else { } else {
@ -135,7 +132,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
// It is buf_size minus room for the sign and null byte. // It is buf_size minus room for the sign and null byte.
int buf_remaining = buf_size - 1 - (s - buf); int buf_remaining = buf_size - 1 - (s - buf);
if (fp_isspecial(f)) { {
char uc = fmt & 0x20; char uc = fmt & 0x20;
if (fp_isinf(f)) { if (fp_isinf(f)) {
*s++ = 'I' ^ uc; *s++ = 'I' ^ uc;

View File

@ -108,7 +108,15 @@ def parse_input_headers(infiles):
continue continue
# add the qstr to the list, with order number to retain original order in file # add the qstr to the list, with order number to retain original order in file
qstrs[ident] = (len(qstrs), ident, qstr) order = len(qstrs)
# but put special method names like __add__ at the top of list, so
# that their id's fit into a byte
if ident == "":
# Sort empty qstr above all still
order = -200000
elif ident.startswith("__"):
order -= 100000
qstrs[ident] = (order, ident, qstr)
if not qcfgs: if not qcfgs:
sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n") sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n")

View File

@ -68,13 +68,7 @@ LD += -m32
endif endif
MAKE_FROZEN = $(TOP)/tools/make-frozen.py MAKE_FROZEN = $(TOP)/tools/make-frozen.py
# allow mpy-cross (for WSL) and mpy-cross.exe (for cygwin) to coexist
ifeq ($(OS),Windows_NT)
MPY_CROSS = $(TOP)/mpy-cross/mpy-cross.exe
PROG_EXT = .exe
else
MPY_CROSS = $(TOP)/mpy-cross/mpy-cross MPY_CROSS = $(TOP)/mpy-cross/mpy-cross
endif
MPY_TOOL = $(TOP)/tools/mpy-tool.py MPY_TOOL = $(TOP)/tools/mpy-tool.py
all: all:

View File

@ -144,13 +144,13 @@ $(PROG): $(OBJ)
# we may want to compile using Thumb, but link with non-Thumb libc. # we may want to compile using Thumb, but link with non-Thumb libc.
$(Q)$(CC) -o $@ $^ $(LIB) $(LDFLAGS) $(Q)$(CC) -o $@ $^ $(LIB) $(LDFLAGS)
ifndef DEBUG ifndef DEBUG
$(Q)$(STRIP) $(STRIPFLAGS_EXTRA) $(PROG)$(PROG_EXT) $(Q)$(STRIP) $(STRIPFLAGS_EXTRA) $(PROG)
endif endif
$(Q)$(SIZE) $$(find $(BUILD) -path "$(BUILD)/build/frozen*.o") $(PROG)$(PROG_EXT) $(Q)$(SIZE) $$(find $(BUILD) -path "$(BUILD)/build/frozen*.o") $(PROG)
clean: clean-prog clean: clean-prog
clean-prog: clean-prog:
$(RM) -f $(PROG)$(PROG_EXT) $(RM) -f $(PROG)
$(RM) -f $(PROG).map $(RM) -f $(PROG).map
.PHONY: clean-prog .PHONY: clean-prog

View File

@ -348,31 +348,16 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
if (MP_OBJ_IS_STR(o_in)) { if (MP_OBJ_IS_STR(o_in)) {
len = unichar_charlen(str, len); len = unichar_charlen(str, len);
if (len == 1) { if (len == 1) {
if (!UTF8_IS_NONASCII(*str)) { return mp_obj_new_int(utf8_get_char((const byte*)str));
goto return_first_byte;
}
mp_int_t ord = *str++ & 0x7F;
for (mp_int_t mask = 0x40; ord & mask; mask >>= 1) {
ord &= ~mask;
}
while (UTF8_IS_CONT(*str)) {
ord = (ord << 6) | (*str++ & 0x3F);
}
return mp_obj_new_int(ord);
} }
} else { } else
// a bytes object #endif
{
// a bytes object, or a str without unicode support (don't sign extend the char)
if (len == 1) { if (len == 1) {
return_first_byte:
return MP_OBJ_NEW_SMALL_INT(((const byte*)str)[0]); return MP_OBJ_NEW_SMALL_INT(((const byte*)str)[0]);
} }
} }
#else
if (len == 1) {
// don't sign extend when converting to ord
return mp_obj_new_int(((const byte*)str)[0]);
}
#endif
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_raise_TypeError("ord expects a character"); mp_raise_TypeError("ord expects a character");

View File

@ -3,7 +3,7 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2013-2017 Damien P. George
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -40,13 +40,30 @@ STATIC NORETURN void math_error(void) {
mp_raise_ValueError("math domain error"); mp_raise_ValueError("math domain error");
} }
#define MATH_FUN_1(py_name, c_name) \ STATIC mp_obj_t math_generic_1(mp_obj_t x_obj, mp_float_t (*f)(mp_float_t)) {
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ mp_float_t x = mp_obj_get_float(x_obj);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); mp_float_t ans = f(x);
if ((isnan(ans) && !isnan(x)) || (isinf(ans) && !isinf(x))) {
math_error();
}
return mp_obj_new_float(ans);
}
#define MATH_FUN_2(py_name, c_name) \ STATIC mp_obj_t math_generic_2(mp_obj_t x_obj, mp_obj_t y_obj, mp_float_t (*f)(mp_float_t, mp_float_t)) {
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \ mp_float_t x = mp_obj_get_float(x_obj);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name); mp_float_t y = mp_obj_get_float(y_obj);
mp_float_t ans = f(x, y);
if ((isnan(ans) && !isnan(x) && !isnan(y)) || (isinf(ans) && !isinf(x))) {
math_error();
}
return mp_obj_new_float(ans);
}
#define MATH_FUN_1(py_name, c_name) \
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { \
return math_generic_1(x_obj, MICROPY_FLOAT_C_FUN(c_name)); \
} \
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
#define MATH_FUN_1_TO_BOOL(py_name, c_name) \ #define MATH_FUN_1_TO_BOOL(py_name, c_name) \
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_bool(c_name(mp_obj_get_float(x_obj))); } \ STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_bool(c_name(mp_obj_get_float(x_obj))); } \
@ -56,23 +73,29 @@ STATIC NORETURN void math_error(void) {
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_int_from_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_int_from_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
#define MATH_FUN_1_ERRCOND(py_name, c_name, error_condition) \ #define MATH_FUN_2(py_name, c_name) \
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { \ STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { \
mp_float_t x = mp_obj_get_float(x_obj); \ return math_generic_2(x_obj, y_obj, MICROPY_FLOAT_C_FUN(c_name)); \
if (error_condition) { \
math_error(); \
} \
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(x)); \
} \ } \
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
#ifdef MP_NEED_LOG2 #define MATH_FUN_2_FLT_INT(py_name, c_name) \
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { \
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_int(y_obj))); \
} \
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
#if MP_NEED_LOG2
#undef log2
#undef log2f
// 1.442695040888963407354163704 is 1/_M_LN2 // 1.442695040888963407354163704 is 1/_M_LN2
#define log2(x) (log(x) * 1.442695040888963407354163704) mp_float_t MICROPY_FLOAT_C_FUN(log2)(mp_float_t x) {
return MICROPY_FLOAT_C_FUN(log)(x) * MICROPY_FLOAT_CONST(1.442695040888963407354163704);
}
#endif #endif
// sqrt(x): returns the square root of x // sqrt(x): returns the square root of x
MATH_FUN_1_ERRCOND(sqrt, sqrt, (x < (mp_float_t)0.0)) MATH_FUN_1(sqrt, sqrt)
// pow(x, y): returns x to the power of y // pow(x, y): returns x to the power of y
MATH_FUN_2(pow, pow) MATH_FUN_2(pow, pow)
// exp(x) // exp(x)
@ -81,9 +104,9 @@ MATH_FUN_1(exp, exp)
// expm1(x) // expm1(x)
MATH_FUN_1(expm1, expm1) MATH_FUN_1(expm1, expm1)
// log2(x) // log2(x)
MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0)) MATH_FUN_1(log2, log2)
// log10(x) // log10(x)
MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0)) MATH_FUN_1(log10, log10)
// cosh(x) // cosh(x)
MATH_FUN_1(cosh, cosh) MATH_FUN_1(cosh, cosh)
// sinh(x) // sinh(x)
@ -114,9 +137,15 @@ MATH_FUN_2(atan2, atan2)
// ceil(x) // ceil(x)
MATH_FUN_1_TO_INT(ceil, ceil) MATH_FUN_1_TO_INT(ceil, ceil)
// copysign(x, y) // copysign(x, y)
MATH_FUN_2(copysign, copysign) STATIC mp_float_t MICROPY_FLOAT_C_FUN(copysign_func)(mp_float_t x, mp_float_t y) {
return MICROPY_FLOAT_C_FUN(copysign)(x, y);
}
MATH_FUN_2(copysign, copysign_func)
// fabs(x) // fabs(x)
MATH_FUN_1(fabs, fabs) STATIC mp_float_t MICROPY_FLOAT_C_FUN(fabs_func)(mp_float_t x) {
return MICROPY_FLOAT_C_FUN(fabs)(x);
}
MATH_FUN_1(fabs, fabs_func)
// floor(x) // floor(x)
MATH_FUN_1_TO_INT(floor, floor) //TODO: delegate to x.__floor__() if x is not a float MATH_FUN_1_TO_INT(floor, floor) //TODO: delegate to x.__floor__() if x is not a float
// fmod(x, y) // fmod(x, y)
@ -130,7 +159,7 @@ MATH_FUN_1_TO_BOOL(isnan, isnan)
// trunc(x) // trunc(x)
MATH_FUN_1_TO_INT(trunc, trunc) MATH_FUN_1_TO_INT(trunc, trunc)
// ldexp(x, exp) // ldexp(x, exp)
MATH_FUN_2(ldexp, ldexp) MATH_FUN_2_FLT_INT(ldexp, ldexp)
#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS #if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
// erf(x): return the error function of x // erf(x): return the error function of x
MATH_FUN_1(erf, erf) MATH_FUN_1(erf, erf)

View File

@ -775,16 +775,24 @@ typedef double mp_float_t;
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (0) #define MICROPY_PY_BUILTINS_TIMEOUTERROR (0)
#endif #endif
// Whether to support complete set of special methods // Whether to support complete set of special methods for user
// for user classes, or only the most used ones. "Reverse" // classes, or only the most used ones. "Inplace" methods are
// methods are controlled by MICROPY_PY_REVERSE_SPECIAL_METHODS // controlled by MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS below.
// below. // "Reverse" methods are controlled by
// MICROPY_PY_REVERSE_SPECIAL_METHODS below.
#ifndef MICROPY_PY_ALL_SPECIAL_METHODS #ifndef MICROPY_PY_ALL_SPECIAL_METHODS
#define MICROPY_PY_ALL_SPECIAL_METHODS (0) #define MICROPY_PY_ALL_SPECIAL_METHODS (0)
#endif #endif
// Whether to support reverse arithmetic operarions methods // Whether to support all inplace arithmetic operarion methods
// (__radd__, etc.) // (__imul__, etc.)
#ifndef MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS
#define MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS (0)
#endif
// Whether to support reverse arithmetic operarion methods
// (__radd__, etc.). Additionally gated by
// MICROPY_PY_ALL_SPECIAL_METHODS.
#ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS #ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
#endif #endif
@ -1111,6 +1119,8 @@ typedef double mp_float_t;
#ifndef MICROPY_PY_USSL #ifndef MICROPY_PY_USSL
#define MICROPY_PY_USSL (0) #define MICROPY_PY_USSL (0)
// Whether to add finaliser code to ussl objects
#define MICROPY_PY_USSL_FINALISER (0)
#endif #endif
#ifndef MICROPY_PY_WEBSOCKET #ifndef MICROPY_PY_WEBSOCKET

View File

@ -168,7 +168,7 @@ typedef struct _mp_state_vm_t {
// root pointers for extmod // root pointers for extmod
#ifdef MICROPY_PY_OS_DUPTERM #ifdef MICROPY_PY_OS_DUPTERM
mp_obj_t term_obj; mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM];
mp_obj_t dupterm_arr_obj; mp_obj_t dupterm_arr_obj;
#endif #endif

View File

@ -29,6 +29,7 @@
#include <assert.h> #include <assert.h>
#include "py/runtime.h" #include "py/runtime.h"
#include "py/smallint.h"
#include "py/emitglue.h" #include "py/emitglue.h"
#include "py/bc.h" #include "py/bc.h"
@ -170,6 +171,8 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_obj_new_cell, mp_obj_new_cell,
mp_make_closure_from_raw_code, mp_make_closure_from_raw_code,
mp_setup_code_state, mp_setup_code_state,
mp_small_int_floor_divide,
mp_small_int_modulo,
}; };
/* /*

View File

@ -286,7 +286,7 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs
// Otherwise, can only look for a scalar numeric value in an array // Otherwise, can only look for a scalar numeric value in an array
if (MP_OBJ_IS_INT(rhs_in) || mp_obj_is_float(rhs_in)) { if (MP_OBJ_IS_INT(rhs_in) || mp_obj_is_float(rhs_in)) {
mp_raise_NotImplementedError(""); mp_raise_NotImplementedError(NULL);
} }
return mp_const_false; return mp_const_false;

View File

@ -158,7 +158,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
mp_bound_slice_t slice; mp_bound_slice_t slice;
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
mp_raise_NotImplementedError(""); mp_raise_NotImplementedError(NULL);
} }
mp_int_t len_adj = slice.start - slice.stop; mp_int_t len_adj = slice.start - slice.stop;
@ -198,7 +198,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
mp_obj_get_array(value, &value_len, &value_items); mp_obj_get_array(value, &value_len, &value_items);
mp_bound_slice_t slice_out; mp_bound_slice_t slice_out;
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) { if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) {
mp_raise_NotImplementedError(""); mp_raise_NotImplementedError(NULL);
} }
mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start); mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start);
//printf("Len adj: %d\n", len_adj); //printf("Len adj: %d\n", len_adj);

View File

@ -335,7 +335,9 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
const uint16_t mp_unary_op_method_name[] = { // Qstrs for special methods are guaranteed to have a small value, so we use byte
// type to represent them.
const byte mp_unary_op_method_name[MP_UNARY_OP_NUM_RUNTIME] = {
[MP_UNARY_OP_BOOL] = MP_QSTR___bool__, [MP_UNARY_OP_BOOL] = MP_QSTR___bool__,
[MP_UNARY_OP_LEN] = MP_QSTR___len__, [MP_UNARY_OP_LEN] = MP_QSTR___len__,
[MP_UNARY_OP_HASH] = MP_QSTR___hash__, [MP_UNARY_OP_HASH] = MP_QSTR___hash__,
@ -343,11 +345,11 @@ const uint16_t mp_unary_op_method_name[] = {
[MP_UNARY_OP_POSITIVE] = MP_QSTR___pos__, [MP_UNARY_OP_POSITIVE] = MP_QSTR___pos__,
[MP_UNARY_OP_NEGATIVE] = MP_QSTR___neg__, [MP_UNARY_OP_NEGATIVE] = MP_QSTR___neg__,
[MP_UNARY_OP_INVERT] = MP_QSTR___invert__, [MP_UNARY_OP_INVERT] = MP_QSTR___invert__,
[MP_UNARY_OP_ABS] = MP_QSTR___abs__,
#endif #endif
#if MICROPY_PY_SYS_GETSIZEOF #if MICROPY_PY_SYS_GETSIZEOF
[MP_UNARY_OP_SIZEOF] = MP_QSTR_getsizeof, [MP_UNARY_OP_SIZEOF] = MP_QSTR___sizeof__,
#endif #endif
[MP_UNARY_OP_NOT] = MP_QSTR_, // don't need to implement this, used to make sure array has full size
}; };
STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
@ -409,59 +411,69 @@ STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
} }
} }
const uint16_t mp_binary_op_method_name[] = { // Binary-op enum values not listed here will have the default value of 0 in the
/* // table, corresponding to MP_QSTR_NULL, and are therefore unsupported (a lookup will
MP_BINARY_OP_OR, // fail). They can be added at the expense of code size for the qstr.
MP_BINARY_OP_XOR, // Qstrs for special methods are guaranteed to have a small value, so we use byte
MP_BINARY_OP_AND, // type to represent them.
MP_BINARY_OP_LSHIFT, const byte mp_binary_op_method_name[MP_BINARY_OP_NUM_RUNTIME] = {
MP_BINARY_OP_RSHIFT, [MP_BINARY_OP_LESS] = MP_QSTR___lt__,
*/ [MP_BINARY_OP_MORE] = MP_QSTR___gt__,
[MP_BINARY_OP_EQUAL] = MP_QSTR___eq__,
[MP_BINARY_OP_LESS_EQUAL] = MP_QSTR___le__,
[MP_BINARY_OP_MORE_EQUAL] = MP_QSTR___ge__,
// MP_BINARY_OP_NOT_EQUAL, // a != b calls a == b and inverts result
[MP_BINARY_OP_IN] = MP_QSTR___contains__,
// All inplace methods are optional, and normal methods will be used
// as a fallback.
[MP_BINARY_OP_INPLACE_ADD] = MP_QSTR___iadd__,
[MP_BINARY_OP_INPLACE_SUBTRACT] = MP_QSTR___isub__,
#if MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS
[MP_BINARY_OP_INPLACE_MULTIPLY] = MP_QSTR___imul__,
[MP_BINARY_OP_INPLACE_FLOOR_DIVIDE] = MP_QSTR___ifloordiv__,
[MP_BINARY_OP_INPLACE_TRUE_DIVIDE] = MP_QSTR___itruediv__,
[MP_BINARY_OP_INPLACE_MODULO] = MP_QSTR___imod__,
[MP_BINARY_OP_INPLACE_POWER] = MP_QSTR___ipow__,
[MP_BINARY_OP_INPLACE_OR] = MP_QSTR___ior__,
[MP_BINARY_OP_INPLACE_XOR] = MP_QSTR___ixor__,
[MP_BINARY_OP_INPLACE_AND] = MP_QSTR___iand__,
[MP_BINARY_OP_INPLACE_LSHIFT] = MP_QSTR___ilshift__,
[MP_BINARY_OP_INPLACE_RSHIFT] = MP_QSTR___irshift__,
#endif
[MP_BINARY_OP_ADD] = MP_QSTR___add__, [MP_BINARY_OP_ADD] = MP_QSTR___add__,
[MP_BINARY_OP_SUBTRACT] = MP_QSTR___sub__, [MP_BINARY_OP_SUBTRACT] = MP_QSTR___sub__,
#if MICROPY_PY_ALL_SPECIAL_METHODS #if MICROPY_PY_ALL_SPECIAL_METHODS
[MP_BINARY_OP_MULTIPLY] = MP_QSTR___mul__, [MP_BINARY_OP_MULTIPLY] = MP_QSTR___mul__,
[MP_BINARY_OP_FLOOR_DIVIDE] = MP_QSTR___floordiv__, [MP_BINARY_OP_FLOOR_DIVIDE] = MP_QSTR___floordiv__,
[MP_BINARY_OP_TRUE_DIVIDE] = MP_QSTR___truediv__, [MP_BINARY_OP_TRUE_DIVIDE] = MP_QSTR___truediv__,
[MP_BINARY_OP_MODULO] = MP_QSTR___mod__,
[MP_BINARY_OP_DIVMOD] = MP_QSTR___divmod__,
[MP_BINARY_OP_POWER] = MP_QSTR___pow__,
[MP_BINARY_OP_OR] = MP_QSTR___or__,
[MP_BINARY_OP_XOR] = MP_QSTR___xor__,
[MP_BINARY_OP_AND] = MP_QSTR___and__,
[MP_BINARY_OP_LSHIFT] = MP_QSTR___lshift__,
[MP_BINARY_OP_RSHIFT] = MP_QSTR___rshift__,
#endif #endif
/*
MP_BINARY_OP_MODULO,
MP_BINARY_OP_POWER,
MP_BINARY_OP_DIVMOD,
MP_BINARY_OP_INPLACE_OR,
MP_BINARY_OP_INPLACE_XOR,
MP_BINARY_OP_INPLACE_AND,
MP_BINARY_OP_INPLACE_LSHIFT,
MP_BINARY_OP_INPLACE_RSHIFT,*/
#if MICROPY_PY_ALL_SPECIAL_METHODS
[MP_BINARY_OP_INPLACE_ADD] = MP_QSTR___iadd__,
[MP_BINARY_OP_INPLACE_SUBTRACT] = MP_QSTR___isub__,
#endif
/*MP_BINARY_OP_INPLACE_MULTIPLY,
MP_BINARY_OP_INPLACE_FLOOR_DIVIDE,
MP_BINARY_OP_INPLACE_TRUE_DIVIDE,
MP_BINARY_OP_INPLACE_MODULO,
MP_BINARY_OP_INPLACE_POWER,*/
#if MICROPY_PY_REVERSE_SPECIAL_METHODS #if MICROPY_PY_REVERSE_SPECIAL_METHODS
[MP_BINARY_OP_REVERSE_ADD] = MP_QSTR___radd__, [MP_BINARY_OP_REVERSE_ADD] = MP_QSTR___radd__,
[MP_BINARY_OP_REVERSE_SUBTRACT] = MP_QSTR___rsub__, [MP_BINARY_OP_REVERSE_SUBTRACT] = MP_QSTR___rsub__,
#if MICROPY_PY_ALL_SPECIAL_METHODS
[MP_BINARY_OP_REVERSE_MULTIPLY] = MP_QSTR___rmul__, [MP_BINARY_OP_REVERSE_MULTIPLY] = MP_QSTR___rmul__,
[MP_BINARY_OP_REVERSE_FLOOR_DIVIDE] = MP_QSTR___rfloordiv__,
[MP_BINARY_OP_REVERSE_TRUE_DIVIDE] = MP_QSTR___rtruediv__,
[MP_BINARY_OP_REVERSE_MODULO] = MP_QSTR___rmod__,
[MP_BINARY_OP_REVERSE_POWER] = MP_QSTR___rpow__,
[MP_BINARY_OP_REVERSE_OR] = MP_QSTR___ror__,
[MP_BINARY_OP_REVERSE_XOR] = MP_QSTR___rxor__,
[MP_BINARY_OP_REVERSE_AND] = MP_QSTR___rand__,
[MP_BINARY_OP_REVERSE_LSHIFT] = MP_QSTR___rlshift__,
[MP_BINARY_OP_REVERSE_RSHIFT] = MP_QSTR___rrshift__,
#endif
#endif #endif
[MP_BINARY_OP_LESS] = MP_QSTR___lt__,
[MP_BINARY_OP_MORE] = MP_QSTR___gt__,
[MP_BINARY_OP_EQUAL] = MP_QSTR___eq__,
[MP_BINARY_OP_LESS_EQUAL] = MP_QSTR___le__,
[MP_BINARY_OP_MORE_EQUAL] = MP_QSTR___ge__,
/*
MP_BINARY_OP_NOT_EQUAL, // a != b calls a == b and inverts result
*/
[MP_BINARY_OP_IN] = MP_QSTR___contains__,
/*
MP_BINARY_OP_IS,
*/
[MP_BINARY_OP_LAST] = 0, // used to make sure array has full size, TODO: FIXME
}; };
STATIC mp_obj_t instance_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { STATIC mp_obj_t instance_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {

View File

@ -39,7 +39,7 @@
#include "py/smallint.h" #include "py/smallint.h"
// The current version of .mpy files // The current version of .mpy files
#define MPY_VERSION (2) #define MPY_VERSION (3)
// The feature flags byte encodes the compile-time config options that // The feature flags byte encodes the compile-time config options that
// affect the generate bytecode. // affect the generate bytecode.

View File

@ -108,6 +108,13 @@ void mp_init(void) {
MP_STATE_VM(mp_module_builtins_override_dict) = NULL; MP_STATE_VM(mp_module_builtins_override_dict) = NULL;
#endif #endif
#ifdef MICROPY_PY_OS_DUPTERM
for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) {
MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL;
}
MP_STATE_VM(dupterm_arr_obj) = MP_OBJ_NULL;
#endif
#ifdef MICROPY_FSUSERMOUNT #ifdef MICROPY_FSUSERMOUNT
// zero out the pointers to the user-mounted devices // zero out the pointers to the user-mounted devices
memset(MP_STATE_VM(fs_user_mount) + MICROPY_FATFS_NUM_PERSISTENT, 0, memset(MP_STATE_VM(fs_user_mount) + MICROPY_FATFS_NUM_PERSISTENT, 0,

View File

@ -57,8 +57,8 @@ typedef struct _mp_arg_t {
} mp_arg_t; } mp_arg_t;
// Tables mapping operator enums to qstrs, defined in objtype.c // Tables mapping operator enums to qstrs, defined in objtype.c
extern const uint16_t mp_unary_op_method_name[]; extern const byte mp_unary_op_method_name[];
extern const uint16_t mp_binary_op_method_name[]; extern const byte mp_binary_op_method_name[];
void mp_init(void); void mp_init(void);
void mp_deinit(void); void mp_deinit(void);

View File

@ -53,41 +53,38 @@ typedef enum {
MP_UNARY_OP_NOT, MP_UNARY_OP_NOT,
// Following ops cannot appear in the bytecode // Following ops cannot appear in the bytecode
MP_UNARY_OP_NON_BYTECODE, MP_UNARY_OP_NUM_BYTECODE,
MP_UNARY_OP_BOOL = MP_UNARY_OP_NON_BYTECODE, // __bool__ MP_UNARY_OP_BOOL = MP_UNARY_OP_NUM_BYTECODE, // __bool__
MP_UNARY_OP_LEN, // __len__ MP_UNARY_OP_LEN, // __len__
MP_UNARY_OP_HASH, // __hash__; must return a small int MP_UNARY_OP_HASH, // __hash__; must return a small int
MP_UNARY_OP_ABS, // __abs__ MP_UNARY_OP_ABS, // __abs__
MP_UNARY_OP_SIZEOF, // for sys.getsizeof() MP_UNARY_OP_SIZEOF, // for sys.getsizeof()
MP_UNARY_OP_NUM_RUNTIME,
} mp_unary_op_t; } mp_unary_op_t;
// Note: the first 35 of these are used in bytecode and changing // Note: the first 9+12+12 of these are used in bytecode and changing
// them requires changing the bytecode version. // them requires changing the bytecode version.
typedef enum { typedef enum {
// Relational operations, should return a bool // 9 relational operations, should return a bool
MP_BINARY_OP_LESS, MP_BINARY_OP_LESS,
MP_BINARY_OP_MORE, MP_BINARY_OP_MORE,
MP_BINARY_OP_EQUAL, MP_BINARY_OP_EQUAL,
MP_BINARY_OP_LESS_EQUAL, MP_BINARY_OP_LESS_EQUAL,
MP_BINARY_OP_MORE_EQUAL, MP_BINARY_OP_MORE_EQUAL,
MP_BINARY_OP_NOT_EQUAL, MP_BINARY_OP_NOT_EQUAL,
MP_BINARY_OP_IN, MP_BINARY_OP_IN,
MP_BINARY_OP_IS, MP_BINARY_OP_IS,
MP_BINARY_OP_EXCEPTION_MATCH, MP_BINARY_OP_EXCEPTION_MATCH,
// these are not supported by the runtime and must be synthesised by the emitter
MP_BINARY_OP_NOT_IN,
MP_BINARY_OP_IS_NOT,
// Arithmetic operations // 12 inplace arithmetic operations
MP_BINARY_OP_INPLACE_OR, MP_BINARY_OP_INPLACE_OR,
MP_BINARY_OP_INPLACE_XOR, MP_BINARY_OP_INPLACE_XOR,
MP_BINARY_OP_INPLACE_AND, MP_BINARY_OP_INPLACE_AND,
MP_BINARY_OP_INPLACE_LSHIFT, MP_BINARY_OP_INPLACE_LSHIFT,
MP_BINARY_OP_INPLACE_RSHIFT, MP_BINARY_OP_INPLACE_RSHIFT,
MP_BINARY_OP_INPLACE_ADD, MP_BINARY_OP_INPLACE_ADD,
MP_BINARY_OP_INPLACE_SUBTRACT, MP_BINARY_OP_INPLACE_SUBTRACT,
MP_BINARY_OP_INPLACE_MULTIPLY, MP_BINARY_OP_INPLACE_MULTIPLY,
MP_BINARY_OP_INPLACE_FLOOR_DIVIDE, MP_BINARY_OP_INPLACE_FLOOR_DIVIDE,
@ -95,13 +92,13 @@ typedef enum {
MP_BINARY_OP_INPLACE_MODULO, MP_BINARY_OP_INPLACE_MODULO,
MP_BINARY_OP_INPLACE_POWER, MP_BINARY_OP_INPLACE_POWER,
// 12 normal arithmetic operations
MP_BINARY_OP_OR, MP_BINARY_OP_OR,
MP_BINARY_OP_XOR, MP_BINARY_OP_XOR,
MP_BINARY_OP_AND, MP_BINARY_OP_AND,
MP_BINARY_OP_LSHIFT, MP_BINARY_OP_LSHIFT,
MP_BINARY_OP_RSHIFT, MP_BINARY_OP_RSHIFT,
MP_BINARY_OP_ADD, MP_BINARY_OP_ADD,
MP_BINARY_OP_SUBTRACT, MP_BINARY_OP_SUBTRACT,
MP_BINARY_OP_MULTIPLY, MP_BINARY_OP_MULTIPLY,
MP_BINARY_OP_FLOOR_DIVIDE, MP_BINARY_OP_FLOOR_DIVIDE,
@ -111,16 +108,16 @@ typedef enum {
// Operations below this line don't appear in bytecode, they // Operations below this line don't appear in bytecode, they
// just identify special methods. // just identify special methods.
MP_BINARY_OP_NUM_BYTECODE,
// MP_BINARY_OP_REVERSE_* must follow immediately after MP_BINARY_OP_* // MP_BINARY_OP_REVERSE_* must follow immediately after MP_BINARY_OP_*
#if MICROPY_PY_REVERSE_SPECIAL_METHODS #if MICROPY_PY_REVERSE_SPECIAL_METHODS
MP_BINARY_OP_REVERSE_OR, MP_BINARY_OP_REVERSE_OR = MP_BINARY_OP_NUM_BYTECODE,
MP_BINARY_OP_REVERSE_XOR, MP_BINARY_OP_REVERSE_XOR,
MP_BINARY_OP_REVERSE_AND, MP_BINARY_OP_REVERSE_AND,
MP_BINARY_OP_REVERSE_LSHIFT, MP_BINARY_OP_REVERSE_LSHIFT,
MP_BINARY_OP_REVERSE_RSHIFT, MP_BINARY_OP_REVERSE_RSHIFT,
MP_BINARY_OP_REVERSE_ADD, MP_BINARY_OP_REVERSE_ADD,
MP_BINARY_OP_REVERSE_SUBTRACT, MP_BINARY_OP_REVERSE_SUBTRACT,
MP_BINARY_OP_REVERSE_MULTIPLY, MP_BINARY_OP_REVERSE_MULTIPLY,
MP_BINARY_OP_REVERSE_FLOOR_DIVIDE, MP_BINARY_OP_REVERSE_FLOOR_DIVIDE,
@ -129,9 +126,18 @@ typedef enum {
MP_BINARY_OP_REVERSE_POWER, MP_BINARY_OP_REVERSE_POWER,
#endif #endif
MP_BINARY_OP_DIVMOD, // not emitted by the compiler but supported by the runtime // This is not emitted by the compiler but is supported by the runtime
MP_BINARY_OP_DIVMOD
#if !MICROPY_PY_REVERSE_SPECIAL_METHODS
= MP_BINARY_OP_NUM_BYTECODE
#endif
,
MP_BINARY_OP_LAST, MP_BINARY_OP_NUM_RUNTIME,
// These 2 are not supported by the runtime and must be synthesised by the emitter
MP_BINARY_OP_NOT_IN,
MP_BINARY_OP_IS_NOT,
} mp_binary_op_t; } mp_binary_op_t;
typedef enum { typedef enum {
@ -181,6 +187,8 @@ typedef enum {
MP_F_NEW_CELL, MP_F_NEW_CELL,
MP_F_MAKE_CLOSURE_FROM_RAW_CODE, MP_F_MAKE_CLOSURE_FROM_RAW_CODE,
MP_F_SETUP_CODE_STATE, MP_F_SETUP_CODE_STATE,
MP_F_SMALL_INT_FLOOR_DIVIDE,
MP_F_SMALL_INT_MODULO,
MP_F_NUMBER_OF, MP_F_NUMBER_OF,
} mp_fun_kind_t; } mp_fun_kind_t;

View File

@ -539,9 +539,9 @@ const byte *mp_bytecode_print_str(const byte *ip) {
printf("LOAD_FAST " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_LOAD_FAST_MULTI); printf("LOAD_FAST " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_LOAD_FAST_MULTI);
} else if (ip[-1] < MP_BC_STORE_FAST_MULTI + 16) { } else if (ip[-1] < MP_BC_STORE_FAST_MULTI + 16) {
printf("STORE_FAST " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_STORE_FAST_MULTI); printf("STORE_FAST " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_STORE_FAST_MULTI);
} else if (ip[-1] < MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NON_BYTECODE) { } else if (ip[-1] < MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NUM_BYTECODE) {
printf("UNARY_OP " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_UNARY_OP_MULTI); printf("UNARY_OP " UINT_FMT, (mp_uint_t)ip[-1] - MP_BC_UNARY_OP_MULTI);
} else if (ip[-1] < MP_BC_BINARY_OP_MULTI + 36) { } else if (ip[-1] < MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_NUM_BYTECODE) {
mp_uint_t op = ip[-1] - MP_BC_BINARY_OP_MULTI; mp_uint_t op = ip[-1] - MP_BC_BINARY_OP_MULTI;
printf("BINARY_OP " UINT_FMT " %s", op, qstr_str(mp_binary_op_method_name[op])); printf("BINARY_OP " UINT_FMT " %s", op, qstr_str(mp_binary_op_method_name[op]));
} else { } else {

View File

@ -109,8 +109,8 @@ static const void *const entry_table[256] = {
[MP_BC_LOAD_CONST_SMALL_INT_MULTI ... MP_BC_LOAD_CONST_SMALL_INT_MULTI + 63] = &&entry_MP_BC_LOAD_CONST_SMALL_INT_MULTI, [MP_BC_LOAD_CONST_SMALL_INT_MULTI ... MP_BC_LOAD_CONST_SMALL_INT_MULTI + 63] = &&entry_MP_BC_LOAD_CONST_SMALL_INT_MULTI,
[MP_BC_LOAD_FAST_MULTI ... MP_BC_LOAD_FAST_MULTI + 15] = &&entry_MP_BC_LOAD_FAST_MULTI, [MP_BC_LOAD_FAST_MULTI ... MP_BC_LOAD_FAST_MULTI + 15] = &&entry_MP_BC_LOAD_FAST_MULTI,
[MP_BC_STORE_FAST_MULTI ... MP_BC_STORE_FAST_MULTI + 15] = &&entry_MP_BC_STORE_FAST_MULTI, [MP_BC_STORE_FAST_MULTI ... MP_BC_STORE_FAST_MULTI + 15] = &&entry_MP_BC_STORE_FAST_MULTI,
[MP_BC_UNARY_OP_MULTI ... MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NON_BYTECODE - 1] = &&entry_MP_BC_UNARY_OP_MULTI, [MP_BC_UNARY_OP_MULTI ... MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NUM_BYTECODE - 1] = &&entry_MP_BC_UNARY_OP_MULTI,
[MP_BC_BINARY_OP_MULTI ... MP_BC_BINARY_OP_MULTI + 35] = &&entry_MP_BC_BINARY_OP_MULTI, [MP_BC_BINARY_OP_MULTI ... MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_NUM_BYTECODE - 1] = &&entry_MP_BC_BINARY_OP_MULTI,
}; };
#if __clang__ #if __clang__

View File

@ -30,21 +30,21 @@
#include "shared-bindings/multiterminal/__init__.h" #include "shared-bindings/multiterminal/__init__.h"
mp_obj_t shared_module_multiterminal_get_secondary_terminal() { mp_obj_t shared_module_multiterminal_get_secondary_terminal() {
if (MP_STATE_PORT(term_obj) == MP_OBJ_NULL) { if (MP_STATE_VM(dupterm_objs[0]) == MP_OBJ_NULL) {
return mp_const_none; return mp_const_none;
} else { } else {
return MP_STATE_PORT(term_obj); return MP_STATE_VM(dupterm_objs[0]);
} }
} }
void shared_module_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal) { void shared_module_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal) {
MP_STATE_PORT(term_obj) = secondary_terminal; MP_STATE_VM(dupterm_objs[0]) = secondary_terminal;
if (MP_STATE_PORT(dupterm_arr_obj) == MP_OBJ_NULL) { if (MP_STATE_PORT(dupterm_arr_obj) == MP_OBJ_NULL) {
MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, ""); MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
} }
} }
void shared_module_multiterminal_clear_secondary_terminal() { void shared_module_multiterminal_clear_secondary_terminal() {
MP_STATE_PORT(term_obj) = MP_OBJ_NULL; MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_NULL;
MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL; MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
} }

View File

@ -43,9 +43,9 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
bc=\\d\+ line=126 bc=\\d\+ line=126
00 LOAD_CONST_NONE 00 LOAD_CONST_NONE
01 LOAD_CONST_FALSE 01 LOAD_CONST_FALSE
02 BINARY_OP 28 __add__ 02 BINARY_OP 26 __add__
03 LOAD_CONST_TRUE 03 LOAD_CONST_TRUE
04 BINARY_OP 28 __add__ 04 BINARY_OP 26 __add__
05 STORE_FAST 0 05 STORE_FAST 0
06 LOAD_CONST_SMALL_INT 0 06 LOAD_CONST_SMALL_INT 0
07 STORE_FAST 0 07 STORE_FAST 0
@ -84,7 +84,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ STORE_FAST 7 \\d\+ STORE_FAST 7
\\d\+ LOAD_FAST 0 \\d\+ LOAD_FAST 0
\\d\+ LOAD_DEREF 14 \\d\+ LOAD_DEREF 14
\\d\+ BINARY_OP 28 __add__ \\d\+ BINARY_OP 26 __add__
\\d\+ STORE_FAST 8 \\d\+ STORE_FAST 8
\\d\+ LOAD_FAST 0 \\d\+ LOAD_FAST 0
\\d\+ UNARY_OP 1 \\d\+ UNARY_OP 1
@ -132,7 +132,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ DUP_TOP_TWO \\d\+ DUP_TOP_TWO
\\d\+ LOAD_SUBSCR \\d\+ LOAD_SUBSCR
\\d\+ LOAD_FAST 12 \\d\+ LOAD_FAST 12
\\d\+ BINARY_OP 16 __iadd__ \\d\+ BINARY_OP 14 __iadd__
\\d\+ ROT_THREE \\d\+ ROT_THREE
\\d\+ STORE_SUBSCR \\d\+ STORE_SUBSCR
\\d\+ LOAD_DEREF 14 \\d\+ LOAD_DEREF 14
@ -369,7 +369,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
42 STORE_FAST_N 19 42 STORE_FAST_N 19
44 LOAD_FAST 9 44 LOAD_FAST 9
45 LOAD_FAST_N 19 45 LOAD_FAST_N 19
47 BINARY_OP 28 __add__ 47 BINARY_OP 26 __add__
48 POP_TOP 48 POP_TOP
49 LOAD_CONST_NONE 49 LOAD_CONST_NONE
50 RETURN_VALUE 50 RETURN_VALUE
@ -521,7 +521,7 @@ arg names: *
bc=\\d\+ line=113 bc=\\d\+ line=113
00 LOAD_DEREF 0 00 LOAD_DEREF 0
02 LOAD_CONST_SMALL_INT 1 02 LOAD_CONST_SMALL_INT 1
03 BINARY_OP 28 __add__ 03 BINARY_OP 26 __add__
04 STORE_FAST 1 04 STORE_FAST 1
05 LOAD_CONST_SMALL_INT 1 05 LOAD_CONST_SMALL_INT 1
06 STORE_DEREF 0 06 STORE_DEREF 0
@ -540,7 +540,7 @@ arg names: * b
bc=\\d\+ line=139 bc=\\d\+ line=139
00 LOAD_FAST 1 00 LOAD_FAST 1
01 LOAD_DEREF 0 01 LOAD_DEREF 0
03 BINARY_OP 28 __add__ 03 BINARY_OP 26 __add__
04 RETURN_VALUE 04 RETURN_VALUE
mem: total=\\d\+, current=\\d\+, peak=\\d\+ mem: total=\\d\+, current=\\d\+, peak=\\d\+
stack: \\d\+ out of \\d\+ stack: \\d\+ out of \\d\+

View File

@ -48,7 +48,12 @@ m = r.match("d")
print(m.group(0)) print(m.group(0))
m = r.match("A") m = r.match("A")
print(m.group(0)) print(m.group(0))
print("===")
# '-' character within character class block
print(re.match("[-a]+", "-a]d").group(0))
print(re.match("[a-]+", "-a]d").group(0))
print("===")
r = re.compile("o+") r = re.compile("o+")
m = r.search("foobar") m = r.search("foobar")

View File

@ -59,6 +59,7 @@ ans = (-1.2) ** -3.4; print("%.5g %.5g" % (ans.real, ans.imag))
# check printing of inf/nan # check printing of inf/nan
print(float('nan') * 1j) print(float('nan') * 1j)
print(float('-nan') * 1j)
print(float('inf') * (1 + 1j)) print(float('inf') * (1 + 1j))
print(float('-inf') * (1 + 1j)) print(float('-inf') * (1 + 1j))

View File

@ -21,6 +21,7 @@ print(float("INF"))
print(float("infinity")) print(float("infinity"))
print(float("INFINITY")) print(float("INFINITY"))
print(float("nan")) print(float("nan"))
print(float("-nan"))
print(float("NaN")) print(float("NaN"))
try: try:
float("") float("")

View File

@ -0,0 +1,51 @@
# Tests domain errors in math functions
try:
import math
except ImportError:
print("SKIP")
raise SystemExit
inf = float('inf')
nan = float('nan')
# single argument functions
for name, f, args in (
('fabs', math.fabs, ()),
('ceil', math.ceil, ()),
('floor', math.floor, ()),
('trunc', math.trunc, ()),
('sqrt', math.sqrt, (-1, 0)),
('exp', math.exp, ()),
('sin', math.sin, ()),
('cos', math.cos, ()),
('tan', math.tan, ()),
('asin', math.asin, (-1.1, 1, 1.1)),
('acos', math.acos, (-1.1, 1, 1.1)),
('atan', math.atan, ()),
('ldexp', lambda x: math.ldexp(x, 0), ()),
('radians', math.radians, ()),
('degrees', math.degrees, ()),
):
for x in args + (inf, nan):
try:
ans = f(x)
print('%.4f' % ans)
except ValueError:
print(name, 'ValueError')
except OverflowError:
print(name, 'OverflowError')
# double argument functions
for name, f, args in (
('pow', math.pow, ((0, 2), (-1, 2), (0, -1), (-1, 2.3))),
('fmod', math.fmod, ((1.2, inf), (1.2, 0), (inf, 1.2))),
('atan2', math.atan2, ((0, 0),)),
('copysign', math.copysign, ()),
):
for x in args + ((0, inf), (inf, 0), (inf, inf), (inf, nan), (nan, inf), (nan, nan)):
try:
ans = f(*x)
print('%.4f' % ans)
except ValueError:
print(name, 'ValueError')

View File

@ -0,0 +1,36 @@
# Tests domain errors in special math functions
try:
import math
math.erf
except (ImportError, AttributeError):
print("SKIP")
raise SystemExit
inf = float('inf')
nan = float('nan')
# single argument functions
for name, f, args in (
('expm1', math.exp, ()),
('log2', math.log2, (-1, 0)),
('log10', math.log10, (-1, 0)),
('sinh', math.sinh, ()),
('cosh', math.cosh, ()),
('tanh', math.tanh, ()),
('asinh', math.asinh, ()),
('acosh', math.acosh, (-1, 0.9, 1)),
('atanh', math.atanh, (-1, 1)),
('erf', math.erf, ()),
('erfc', math.erfc, ()),
('gamma', math.gamma, (-2, -1, 0, 1)),
('lgamma', math.lgamma, (-2, -1, 0, 1)),
):
for x in args + (inf, nan):
try:
ans = f(x)
print('%.4f' % ans)
except ValueError:
print(name, 'ValueError')
except OverflowError:
print(name, 'OverflowError')

View File

@ -0,0 +1,18 @@
# test floor-division and modulo operators
@micropython.viper
def div(x:int, y:int) -> int:
return x // y
@micropython.viper
def mod(x:int, y:int) -> int:
return x % y
def dm(x, y):
print(div(x, y), mod(x, y))
for x in (-6, 6):
for y in range(-7, 8):
if y == 0:
continue
dm(x, y)

View File

@ -0,0 +1,28 @@
0 -6
1 0
1 -1
1 -2
2 0
3 0
6 0
-6 0
-3 0
-2 0
-2 2
-2 4
-1 0
-1 1
-1 -1
-1 0
-2 -4
-2 -2
-2 0
-3 0
-6 0
6 0
3 0
2 0
1 2
1 1
1 0
0 6

View File

@ -6,6 +6,8 @@ try:
import ussl as ssl import ussl as ssl
except: except:
import ssl import ssl
# CPython only supports server_hostname with SSLContext
ssl = ssl.SSLContext()
def test_one(site, opts): def test_one(site, opts):
@ -22,7 +24,7 @@ def test_one(site, opts):
else: else:
s = ssl.wrap_socket(s) s = ssl.wrap_socket(s)
s.write(b"GET / HTTP/1.0\r\n\r\n") s.write(b"GET / HTTP/1.0\r\nHost: %s\r\n\r\n" % bytes(site, 'latin'))
resp = s.read(4096) resp = s.read(4096)
# print(resp) # print(resp)
@ -34,6 +36,7 @@ SITES = [
"google.com", "google.com",
"www.google.com", "www.google.com",
"api.telegram.org", "api.telegram.org",
{"host": "api.pushbullet.com", "sni": True},
# "w9rybpfril.execute-api.ap-southeast-2.amazonaws.com", # "w9rybpfril.execute-api.ap-southeast-2.amazonaws.com",
{"host": "w9rybpfril.execute-api.ap-southeast-2.amazonaws.com", "sni": True}, {"host": "w9rybpfril.execute-api.ap-southeast-2.amazonaws.com", "sni": True},
] ]

Some files were not shown because too many files have changed in this diff Show More