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:
commit
7b393bc406
|
@ -145,3 +145,43 @@ or by an exeption, for example using try/finally::
|
|||
# Use sock
|
||||
finally:
|
||||
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.
|
||||
|
|
|
@ -223,6 +223,17 @@ and is accessed via the :ref:`machine.I2C <machine.I2C>` class::
|
|||
buf = bytearray(10) # create a buffer with 10 bytes
|
||||
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
|
||||
---------------
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@ parameter should be `id`.
|
|||
connection parameters. For various medium types, there are different
|
||||
sets of predefined/recommended parameters, among them:
|
||||
|
||||
* WiFi: *bssid* keyword to connect by BSSID (MAC address) instead
|
||||
of access point name
|
||||
* WiFi: *bssid* keyword to connect to a specific BSSID (MAC address)
|
||||
|
||||
.. method:: disconnect()
|
||||
|
||||
|
@ -225,7 +224,9 @@ parameter should be `id`.
|
|||
==============
|
||||
|
||||
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::
|
||||
|
||||
|
@ -269,6 +270,11 @@ parameter should be `id`.
|
|||
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)])
|
||||
|
||||
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
|
||||
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.
|
||||
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()
|
||||
|
||||
|
@ -413,16 +422,17 @@ parameter should be `id`.
|
|||
Following are commonly supported parameters (availability of a specific parameter
|
||||
depends on network technology type, driver, and `MicroPython port`).
|
||||
|
||||
========= ===========
|
||||
Parameter Description
|
||||
========= ===========
|
||||
mac MAC address (bytes)
|
||||
essid WiFi access point name (string)
|
||||
channel WiFi channel (integer)
|
||||
hidden Whether ESSID is hidden (boolean)
|
||||
authmode Authentication mode supported (enumeration, see module constants)
|
||||
password Access password (string)
|
||||
========= ===========
|
||||
============= ===========
|
||||
Parameter Description
|
||||
============= ===========
|
||||
mac MAC address (bytes)
|
||||
essid WiFi access point name (string)
|
||||
channel WiFi channel (integer)
|
||||
hidden Whether ESSID is hidden (boolean)
|
||||
authmode Authentication mode supported (enumeration, see module constants)
|
||||
password Access password (string)
|
||||
dhcp_hostname The DHCP hostname to use
|
||||
============= ===========
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Accel:
|
||||
|
||||
class Accel -- accelerometer control
|
||||
====================================
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.CAN:
|
||||
|
||||
class CAN -- controller area network communication bus
|
||||
======================================================
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.LCD:
|
||||
|
||||
class LCD -- LCD control for the LCD touch-sensor pyskin
|
||||
========================================================
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Switch:
|
||||
|
||||
class Switch -- switch object
|
||||
=============================
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.USB_HID:
|
||||
|
||||
class USB_HID -- USB Human Interface Device (HID)
|
||||
=================================================
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.USB_VCP:
|
||||
|
||||
class USB_VCP -- USB virtual comm port
|
||||
======================================
|
||||
|
|
|
@ -34,6 +34,8 @@ Supported operators are:
|
|||
|
||||
``'+?'``
|
||||
|
||||
``'|'``
|
||||
|
||||
``'()'``
|
||||
Grouping. Each group is capturing (a substring it captures can be accessed
|
||||
with `match.group()` method).
|
||||
|
|
|
@ -66,12 +66,18 @@ Methods
|
|||
|
||||
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
|
||||
callee-owned tuples. This function provides efficient, allocation-free
|
||||
`callee-owned tuples`. This function provides efficient, allocation-free
|
||||
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
|
||||
:class: attention
|
||||
|
||||
|
|
|
@ -68,7 +68,16 @@ Functions
|
|||
|
||||
.. 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)
|
||||
|
||||
|
@ -80,8 +89,8 @@ Functions
|
|||
|
||||
The following example shows how to connect to a given url::
|
||||
|
||||
s = socket.socket()
|
||||
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
|
||||
s = usocket.socket()
|
||||
s.connect(usocket.getaddrinfo('www.micropython.org', 80)[0][-1])
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
@ -96,13 +105,29 @@ Functions
|
|||
from an exception object). The use of negative values is a provisional
|
||||
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
|
||||
---------
|
||||
|
||||
.. data:: AF_INET
|
||||
AF_INET6
|
||||
|
||||
Address family types. Availability depends on a particular board.
|
||||
Address family types. Availability depends on a particular `MicroPython port`.
|
||||
|
||||
.. data:: SOCK_STREAM
|
||||
SOCK_DGRAM
|
||||
|
@ -112,7 +137,11 @@ Constants
|
|||
.. data:: IPPROTO_UDP
|
||||
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_*
|
||||
|
||||
|
@ -208,12 +237,30 @@ Methods
|
|||
|
||||
.. 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
|
||||
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
|
||||
completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket
|
||||
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
|
||||
:class: attention
|
||||
|
||||
|
@ -281,7 +328,7 @@ Methods
|
|||
|
||||
Return value: number of bytes written.
|
||||
|
||||
.. exception:: socket.error
|
||||
.. exception:: usocket.error
|
||||
|
||||
MicroPython does NOT have this exception.
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ facilities for network sockets, both client-side and server-side.
|
|||
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),
|
||||
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
|
||||
`accept()` on a non-SSL listening server socket.
|
||||
|
||||
Depending on the underlying module implementation for a particular board,
|
||||
some or all keyword arguments above may be not supported.
|
||||
Depending on the underlying module implementation in a particular
|
||||
`MicroPython port`, some or all keyword arguments above may be not supported.
|
||||
|
||||
.. 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.
|
||||
|
||||
Exceptions
|
||||
|
@ -41,8 +41,8 @@ Exceptions
|
|||
Constants
|
||||
---------
|
||||
|
||||
.. data:: ssl.CERT_NONE
|
||||
ssl.CERT_OPTIONAL
|
||||
ssl.CERT_REQUIRED
|
||||
.. data:: ussl.CERT_NONE
|
||||
ussl.CERT_OPTIONAL
|
||||
ussl.CERT_REQUIRED
|
||||
|
||||
Supported values for *cert_reqs* parameter.
|
||||
|
|
|
@ -39,17 +39,32 @@ Use the :mod:`time <utime>` module::
|
|||
start = time.ticks_ms() # get value of millisecond counter
|
||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||
|
||||
LEDs
|
||||
----
|
||||
Internal LEDs
|
||||
-------------
|
||||
|
||||
See :ref:`pyb.LED <pyb.LED>`. ::
|
||||
|
||||
from pyb import LED
|
||||
|
||||
led = LED(1) # red led
|
||||
led = LED(1) # 1=red, 2=green, 3=yellow, 4=blue
|
||||
led.toggle()
|
||||
led.on()
|
||||
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
|
||||
-------------
|
||||
|
@ -99,6 +114,17 @@ See :ref:`pyb.Timer <pyb.Timer>`. ::
|
|||
tim.freq(0.5) # 0.5 Hz
|
||||
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)
|
||||
----------------------------
|
||||
|
||||
|
@ -167,3 +193,25 @@ See :ref:`pyb.I2C <pyb.I2C>`. ::
|
|||
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_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())
|
||||
|
|
|
@ -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:
|
||||
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)
|
||||
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)
|
||||
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.
|
||||
|
|
|
@ -80,7 +80,7 @@ example causes two LED's to flash at different rates.
|
|||
self.led.toggle()
|
||||
|
||||
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()``
|
||||
is called causing LED 1 to change state. The ``green`` instance operates similarly: a timer 2 interrupt
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
|
||||
|
||||
from micropython import const
|
||||
import time
|
||||
import framebuf
|
||||
|
||||
|
||||
|
@ -47,7 +46,6 @@ class SSD1306:
|
|||
self.text = fb.text
|
||||
self.scroll = fb.scroll
|
||||
self.blit = fb.blit
|
||||
self.poweron()
|
||||
self.init_display()
|
||||
|
||||
def init_display(self):
|
||||
|
@ -80,6 +78,9 @@ class SSD1306:
|
|||
def poweroff(self):
|
||||
self.write_cmd(SET_DISP | 0x00)
|
||||
|
||||
def poweron(self):
|
||||
self.write_cmd(SET_DISP | 0x01)
|
||||
|
||||
def contrast(self, contrast):
|
||||
self.write_cmd(SET_CONTRAST)
|
||||
self.write_cmd(contrast)
|
||||
|
@ -123,9 +124,6 @@ class SSD1306_I2C(SSD1306):
|
|||
self.i2c.write(buf)
|
||||
self.i2c.stop()
|
||||
|
||||
def poweron(self):
|
||||
pass
|
||||
|
||||
|
||||
class SSD1306_SPI(SSD1306):
|
||||
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
|
||||
|
@ -137,6 +135,12 @@ class SSD1306_SPI(SSD1306):
|
|||
self.dc = dc
|
||||
self.res = res
|
||||
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)
|
||||
|
||||
def write_cmd(self, cmd):
|
||||
|
@ -154,10 +158,3 @@ class SSD1306_SPI(SSD1306):
|
|||
self.cs(0)
|
||||
self.spi.write(buf)
|
||||
self.cs(1)
|
||||
|
||||
def poweron(self):
|
||||
self.res(1)
|
||||
time.sleep_ms(1)
|
||||
self.res(0)
|
||||
time.sleep_ms(10)
|
||||
self.res(1)
|
||||
|
|
|
@ -52,10 +52,9 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpthread.h"
|
||||
#include "socket.h"
|
||||
|
||||
extern void HAL_Delay(uint32_t);
|
||||
|
||||
#define SOCK_ANY_PORT_NUM 0xC000;
|
||||
|
||||
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
|
||||
return SOCKERR_TIMEOUT;
|
||||
}
|
||||
HAL_Delay(1);
|
||||
MICROPY_THREAD_YIELD();
|
||||
}
|
||||
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
|
||||
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(len <= freesize) break;
|
||||
MICROPY_THREAD_YIELD();
|
||||
}
|
||||
wiz_send_data(sn, buf, len);
|
||||
#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(recvsize != 0) break;
|
||||
HAL_Delay(1);
|
||||
MICROPY_THREAD_YIELD();
|
||||
};
|
||||
if(recvsize < len) len = recvsize;
|
||||
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( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
|
||||
if(len <= freesize) break;
|
||||
HAL_Delay(1);
|
||||
MICROPY_THREAD_YIELD();
|
||||
};
|
||||
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;
|
||||
}
|
||||
////////////
|
||||
HAL_Delay(1);
|
||||
MICROPY_THREAD_YIELD();
|
||||
}
|
||||
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
|
||||
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( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
|
||||
if(pack_len != 0) break;
|
||||
MICROPY_THREAD_YIELD();
|
||||
};
|
||||
}
|
||||
sock_pack_info[sn] = PACK_COMPLETED;
|
||||
|
|
|
@ -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 ret;
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "../wizchip_conf.h"
|
||||
#include "board.h"
|
||||
|
||||
#define _W5500_IO_BASE_ 0x00000000
|
||||
|
||||
|
|
|
@ -56,7 +56,9 @@
|
|||
* @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n
|
||||
* ex> <code> #define \_WIZCHIP_ 5500 </code>
|
||||
*/
|
||||
#ifndef _WIZCHIP_
|
||||
#define _WIZCHIP_ 5200 // 5100, 5200, 5500
|
||||
#endif
|
||||
|
||||
#define _WIZCHIP_IO_MODE_NONE_ 0x0000
|
||||
#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */
|
||||
|
|
|
@ -8,6 +8,12 @@ class LEDClass:
|
|||
def value(self, v):
|
||||
print(self.id, v)
|
||||
|
||||
def on(self):
|
||||
self.value(1)
|
||||
|
||||
def off(self):
|
||||
self.value(0)
|
||||
|
||||
|
||||
LED = LEDClass(1)
|
||||
LED2 = LEDClass(12)
|
||||
|
|
|
@ -35,8 +35,9 @@
|
|||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
|
||||
|
||||
#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_deactivate(const char *msg, mp_obj_t exc);
|
||||
void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc);
|
||||
#else
|
||||
#define mp_uos_dupterm_tx_strn(s, l)
|
||||
#endif
|
||||
|
|
|
@ -1032,7 +1032,7 @@ STATIC mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
|
|||
break;
|
||||
}
|
||||
case MOD_NETWORK_SOCK_DGRAM:
|
||||
mp_raise_NotImplementedError("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,11 @@ struct ssl_args {
|
|||
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) {
|
||||
#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);
|
||||
#endif
|
||||
o->base.type = &ussl_socket_type;
|
||||
o->buf = NULL;
|
||||
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
|
||||
(void)self_in;
|
||||
if (!mp_obj_is_true(flag_in)) {
|
||||
mp_raise_NotImplementedError("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
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_setblocking), MP_ROM_PTR(&socket_setblocking_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);
|
||||
|
|
|
@ -65,23 +65,30 @@ struct ssl_args {
|
|||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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
|
||||
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;
|
||||
|
||||
const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_WRITE);
|
||||
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 (mp_is_nonblocking_error(err)) {
|
||||
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;
|
||||
|
||||
const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_READ);
|
||||
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 (mp_is_nonblocking_error(err)) {
|
||||
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) {
|
||||
#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);
|
||||
#endif
|
||||
o->base.type = &ussl_socket_type;
|
||||
|
||||
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_setblocking), MP_ROM_PTR(&socket_setblocking_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) },
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
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];
|
||||
|
|
|
@ -308,7 +308,7 @@ STATIC mp_obj_t webrepl_set_password(mp_obj_t passwd_in) {
|
|||
size_t len;
|
||||
const char *passwd = mp_obj_str_get_data(passwd_in, &len);
|
||||
if (len > sizeof(webrepl_passwd) - 1) {
|
||||
mp_raise_ValueError("");
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
strcpy(webrepl_passwd, passwd);
|
||||
return mp_const_none;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Paul Sokolovsky
|
||||
* Copyright (c) 2017 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -31,61 +32,114 @@
|
|||
#include "py/objtuple.h"
|
||||
#include "py/objarray.h"
|
||||
#include "py/stream.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
|
||||
#ifdef MICROPY_PY_OS_DUPTERM
|
||||
|
||||
void mp_uos_deactivate(const char *msg, mp_obj_t exc) {
|
||||
mp_obj_t term = MP_STATE_PORT(term_obj);
|
||||
MP_STATE_PORT(term_obj) = NULL;
|
||||
void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc) {
|
||||
mp_obj_t term = MP_STATE_VM(dupterm_objs[dupterm_idx]);
|
||||
MP_STATE_VM(dupterm_objs[dupterm_idx]) = MP_OBJ_NULL;
|
||||
mp_printf(&mp_plat_print, msg);
|
||||
if (exc != MP_OBJ_NULL) {
|
||||
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) {
|
||||
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;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
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;
|
||||
arr->items = (void*)str;
|
||||
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);
|
||||
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->len = 1;
|
||||
nlr_pop();
|
||||
} 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) {
|
||||
if (n_args == 0) {
|
||||
if (MP_STATE_PORT(term_obj) == MP_OBJ_NULL) {
|
||||
return mp_const_none;
|
||||
} 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;
|
||||
mp_int_t idx = 0;
|
||||
if (n_args == 2) {
|
||||
idx = mp_obj_get_int(args[1]);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
#include "extmod/vfs_fat.h"
|
||||
#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
|
||||
// object (starts with / if an absolute path).
|
||||
// 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) {
|
||||
assert(n_args <= PROXY_MAX_ARGS);
|
||||
if (vfs == MP_VFS_NONE) {
|
||||
// mount point not found
|
||||
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
|
||||
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);
|
||||
if (args != NULL) {
|
||||
memcpy(meth + 2, args, n_args * sizeof(*args));
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9b3092eb3b4b230a63c0c389bfbd3c55682c620f
|
||||
Subproject commit dac9176cac58cc5e49669a9a4d404a6f6dd7cc10
|
|
@ -48,16 +48,6 @@ float copysignf(float x, float y) {
|
|||
}
|
||||
#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
|
||||
float log10f(float x) { return logf(x) / (float)_M_LN10; }
|
||||
|
||||
|
|
|
@ -159,41 +159,6 @@ void mp_hal_signal_input(void) {
|
|||
#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 byte lock;
|
||||
if (lock) {
|
||||
|
@ -201,7 +166,7 @@ STATIC void dupterm_task_handler(os_event_t *evt) {
|
|||
}
|
||||
lock = 1;
|
||||
while (1) {
|
||||
int c = call_dupterm_read();
|
||||
int c = mp_uos_dupterm_rx_chr();
|
||||
if (c < 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
if (args[0] != MP_OBJ_NEW_SMALL_INT(1)) {
|
||||
// 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);
|
||||
|
|
|
@ -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:
|
||||
return &wdt_default;
|
||||
default:
|
||||
mp_raise_ValueError("");
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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_init(mp_sys_argv, 0);
|
||||
MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
|
||||
MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
|
||||
|
||||
reset_pins();
|
||||
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
|
||||
extern void esp_native_code_init(void);
|
||||
|
|
|
@ -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_obj_t esp_connect(size_t n_args, const mp_obj_t *args) {
|
||||
require_if(args[0], STATION_IF);
|
||||
STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
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}};
|
||||
size_t len;
|
||||
const char *p;
|
||||
bool set_config = false;
|
||||
|
||||
if (n_args > 1) {
|
||||
p = mp_obj_str_get_data(args[1], &len);
|
||||
// set parameters based on given args
|
||||
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));
|
||||
memcpy(config.ssid, p, len);
|
||||
if (n_args > 2) {
|
||||
p = mp_obj_str_get_data(args[2], &len);
|
||||
len = MIN(len, sizeof(config.password));
|
||||
memcpy(config.password, p, len);
|
||||
set_config = true;
|
||||
}
|
||||
if (args[ARG_password].u_obj != mp_const_none) {
|
||||
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_connect(), "Cannot connect to AP");
|
||||
|
||||
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) {
|
||||
require_if(self_in, STATION_IF);
|
||||
|
|
|
@ -16,12 +16,9 @@ def getpass(prompt):
|
|||
|
||||
def input_pass():
|
||||
while 1:
|
||||
passwd1 = getpass("New password: ")
|
||||
if len(passwd1) < 4:
|
||||
print("Password too short")
|
||||
continue
|
||||
elif len(passwd1) > 9:
|
||||
print("Password too long")
|
||||
passwd1 = getpass("New password (4-9 chars): ")
|
||||
if len(passwd1) < 4 or len(passwd1) > 9:
|
||||
print("Invalid password length")
|
||||
continue
|
||||
passwd2 = getpass("Confirm password: ")
|
||||
if passwd1 == passwd2:
|
||||
|
|
Binary file not shown.
|
@ -287,13 +287,13 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\
|
|||
class/src/usbd_msc_data.c \
|
||||
)
|
||||
|
||||
ifeq ($(MICROPY_PY_WIZNET5K),1)
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
WIZNET5K_DIR=drivers/wiznet5k
|
||||
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 += $(addprefix $(WIZNET5K_DIR)/,\
|
||||
ethernet/w5200/w5200.c \
|
||||
ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
|
||||
ethernet/wizchip_conf.c \
|
||||
ethernet/socket.c \
|
||||
internet/dns/dns.c \
|
||||
|
|
|
@ -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,PA13,JTMS,SWDIO,,,,,,,,,,,,,,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
|
||||
PortB,PB0,,TIM1_CH2N,TIM3_CH3T,IM8_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
|
||||
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,TIM8_CH2N,,,,,UART4_CTS,LCD_R3,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,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,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
|
||||
|
@ -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,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,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,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
|
||||
|
|
|
|
@ -125,7 +125,7 @@ STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin
|
|||
|
||||
if (ip == 0) {
|
||||
// unknown host
|
||||
return MP_ENOENT;
|
||||
return -2;
|
||||
}
|
||||
|
||||
out_ip[0] = ip >> 24;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.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;
|
||||
} else {
|
||||
// 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);
|
||||
if (sr == SOCK_ESTABLISHED) {
|
||||
socket2->u_param = socket->u_param;
|
||||
// TODO need to populate this with the correct values
|
||||
ip[0] = 0;
|
||||
ip[1] = 0;
|
||||
ip[2] = 0;
|
||||
ip[3] = 0;
|
||||
getSn_DIPR((uint8_t)socket2->u_param.fileno, ip);
|
||||
*port = getSn_PORT(socket2->u_param.fileno);
|
||||
|
||||
// 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) {
|
||||
// TODO
|
||||
*_errno = MP_EINVAL;
|
||||
return -1;
|
||||
if (request == MP_STREAM_POLL) {
|
||||
int ret = 0;
|
||||
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
|
||||
|
@ -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.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.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.TIMode = SPI_TIMODE_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) {
|
||||
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) {
|
||||
printf("\nWiz SREG[%d]:", sn);
|
||||
|
@ -410,7 +422,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
|
|||
if (i % 16 == 0) {
|
||||
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");
|
||||
|
@ -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_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)])
|
||||
/// Get/set IP address, subnet mask, gateway and DNS.
|
||||
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[] = {
|
||||
{ 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_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/builtin.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
|
||||
|
||||
// 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[] = {
|
||||
{ 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_standby), MP_ROM_PTR(&machine_deepsleep_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_hid_mouse), MP_ROM_PTR(&pyb_usb_hid_mouse_obj) },
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "lib/timeutils/timeutils.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.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);
|
||||
#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[] = {
|
||||
{ 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
|
||||
|
||||
// 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_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
||||
|
|
|
@ -390,29 +390,48 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
|||
size_t hlen;
|
||||
const char *host = mp_obj_str_get_data(host_in, &hlen);
|
||||
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
|
||||
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) {
|
||||
uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
||||
int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
|
||||
if (ret != 0) {
|
||||
// TODO CPython raises: socket.gaierror: [Errno -2] Name or service not known
|
||||
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);
|
||||
if (hlen > 0) {
|
||||
// check if host is already in IP form
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG);
|
||||
have_ip = true;
|
||||
nlr_pop();
|
||||
} else {
|
||||
// swallow exception: host was not in IP form so need to do DNS lookup
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
#define MICROPY_PY_USELECT (1)
|
||||
#define MICROPY_PY_UTIMEQ (1)
|
||||
#define MICROPY_PY_UTIME_MP_HAL (1)
|
||||
#define MICROPY_PY_OS_DUPTERM (1)
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_MACHINE_PULSE (1)
|
||||
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
|
||||
|
@ -326,6 +327,8 @@ static inline mp_uint_t disable_irq(void) {
|
|||
__WFI(); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define MICROPY_THREAD_YIELD() pyb_thread_yield()
|
||||
#else
|
||||
#define MICROPY_EVENT_POLL_HOOK \
|
||||
do { \
|
||||
|
@ -333,8 +336,13 @@ static inline mp_uint_t disable_irq(void) {
|
|||
mp_handle_pending(); \
|
||||
__WFI(); \
|
||||
} while (0);
|
||||
|
||||
#define MICROPY_THREAD_YIELD()
|
||||
#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
|
||||
// garbage-collected heap. For completeness, emulate C heap via
|
||||
// GC heap. Note that MicroPython core never uses malloc() and friends,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# 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
|
||||
|
||||
# cc3k module for wifi support
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "usb.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))) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -56,15 +61,26 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
|||
if (usb_vcp_is_enabled()) {
|
||||
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) {
|
||||
// send stdout to UART and USB CDC VCP
|
||||
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
|
||||
uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len);
|
||||
const char *last = str;
|
||||
while (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()) {
|
||||
usb_vcp_send_strn_cooked(str, len);
|
||||
if (str > last) {
|
||||
mp_hal_stdout_tx_strn(last, str - last);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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) {
|
||||
int 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
|
||||
void uart_irq_handler(mp_uint_t uart_id) {
|
||||
// get the uart object
|
||||
|
|
|
@ -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);
|
||||
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_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
|
||||
|
||||
#endif // MICROPY_INCLUDED_STMHAL_UART_H
|
||||
|
|
|
@ -178,20 +178,6 @@ void usb_vcp_send_strn(const char *str, int len) {
|
|||
#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
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ void pyb_usb_dev_deinit(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
|
||||
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_process(void);
|
||||
|
|
|
@ -57,10 +57,14 @@
|
|||
#define CDC_SEND_BREAK 0x23
|
||||
|
||||
uint8_t *usbd_cdc_init(usbd_cdc_itf_t *cdc, usbd_cdc_msc_hid_state_t *usbd) {
|
||||
// Link the parent state
|
||||
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_get = 0;
|
||||
cdc->tx_buf_ptr_in = 0;
|
||||
cdc->tx_buf_ptr_out = 0;
|
||||
cdc->tx_buf_ptr_out_shadow = 0;
|
||||
cdc->tx_buf_ptr_wait_count = 0;
|
||||
|
|
|
@ -43,8 +43,8 @@ typedef struct _usbd_cdc_itf_t {
|
|||
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
|
||||
uint16_t tx_buf_ptr_in; // increment this pointer modulo APP_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
|
||||
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 USBD_CDC_TX_DATA_SIZE when data is drained
|
||||
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_need_empty_packet; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size
|
||||
|
|
|
@ -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) {
|
||||
// send stdout to UART and USB CDC VCP
|
||||
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);
|
||||
}
|
||||
if (usb_vcp_is_enabled()) {
|
||||
|
|
|
@ -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,
|
||||
/// otherwise the same buffer that was passed in to `recv`.
|
||||
#if 0
|
||||
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_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
};
|
||||
#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) {
|
||||
// TODO assumes transmission size is 8-bits wide
|
||||
|
|
|
@ -97,7 +97,7 @@ SRC_MOD += modtermios.c
|
|||
endif
|
||||
ifeq ($(MICROPY_PY_SOCKET),1)
|
||||
CFLAGS_MOD += -DMICROPY_PY_SOCKET=1
|
||||
SRC_MOD += modsocket.c
|
||||
SRC_MOD += modusocket.c
|
||||
endif
|
||||
ifeq ($(MICROPY_PY_THREAD),1)
|
||||
CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
mp_raise_NotImplementedError("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
|
||||
if (!JJ(IsInstanceOf, self->obj, List_class)) {
|
||||
|
|
|
@ -60,8 +60,6 @@
|
|||
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
|
||||
// fields should have the same layout.
|
||||
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,
|
||||
};
|
||||
|
||||
#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)
|
||||
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);
|
||||
|
@ -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_ntop), MP_ROM_PTR(&mod_socket_inet_ntop_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) }
|
||||
C(AF_UNIX),
|
|
@ -85,6 +85,7 @@
|
|||
#define MICROPY_PY_BUILTINS_POW3 (1)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (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_BUILTINS_SLICE_ATTRS (1)
|
||||
#define MICROPY_PY_SYS_EXIT (1)
|
||||
|
|
|
@ -108,11 +108,11 @@ void mp_hal_stdio_mode_orig(void) {
|
|||
#endif
|
||||
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
static int call_dupterm_read(void) {
|
||||
static int call_dupterm_read(size_t idx) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
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);
|
||||
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
|
||||
if (res == mp_const_none) {
|
||||
|
@ -122,18 +122,18 @@ static int call_dupterm_read(void) {
|
|||
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
|
||||
if (bufinfo.len == 0) {
|
||||
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;
|
||||
}
|
||||
nlr_pop();
|
||||
return *(byte*)bufinfo.buf;
|
||||
} else {
|
||||
// Temporarily disable dupterm to avoid infinite recursion
|
||||
mp_obj_t save_term = MP_STATE_PORT(term_obj);
|
||||
MP_STATE_PORT(term_obj) = NULL;
|
||||
mp_obj_t save_term = MP_STATE_VM(dupterm_objs[idx]);
|
||||
MP_STATE_VM(dupterm_objs[idx]) = NULL;
|
||||
mp_printf(&mp_plat_print, "dupterm: ");
|
||||
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;
|
||||
|
@ -143,10 +143,11 @@ static int call_dupterm_read(void) {
|
|||
int mp_hal_stdin_rx_chr(void) {
|
||||
unsigned char c;
|
||||
#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;
|
||||
do {
|
||||
c = call_dupterm_read();
|
||||
c = call_dupterm_read(0);
|
||||
} while (c == -2);
|
||||
if (c == -1) {
|
||||
goto main_term;
|
||||
|
|
|
@ -60,7 +60,9 @@ static char *stack_top;
|
|||
static char heap[MICROPY_HEAP_SIZE];
|
||||
|
||||
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
|
||||
if (net_if_get_default() == NULL) {
|
||||
// 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}}};
|
||||
net_if_ipv6_addr_add(net_if_get_default(), &in6addr_my, NET_ADDR_MANUAL, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int real_main(void) {
|
||||
|
|
|
@ -4,6 +4,12 @@ CONFIG_REBOOT=y
|
|||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_CONSOLE_HANDLER=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_FLOAT=y
|
||||
CONFIG_MAIN_STACK_SIZE=4096
|
||||
|
@ -18,6 +24,14 @@ CONFIG_NET_SOCKETS=y
|
|||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
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
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# Interrupt-driven UART console has emulation artifacts under QEMU,
|
||||
# disable it
|
||||
CONFIG_CONSOLE_PULL=n
|
||||
|
||||
# Networking drivers
|
||||
# SLIP driver for QEMU
|
||||
CONFIG_NET_SLIP_TAP=y
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# Interrupt-driven UART console has emulation artifacts under QEMU,
|
||||
# disable it
|
||||
CONFIG_CONSOLE_PULL=n
|
||||
|
||||
# Networking drivers
|
||||
# SLIP driver for QEMU
|
||||
CONFIG_NET_SLIP_TAP=y
|
||||
|
|
|
@ -24,11 +24,16 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <zephyr.h>
|
||||
#include <console.h>
|
||||
#include "zephyr_getchar.h"
|
||||
|
||||
int real_main(void);
|
||||
|
||||
void main(void) {
|
||||
#ifdef CONFIG_CONSOLE_PULL
|
||||
console_init();
|
||||
#else
|
||||
zephyr_getchar_init();
|
||||
#endif
|
||||
real_main();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "src/zephyr_getchar.h"
|
||||
// Zephyr headers
|
||||
#include <uart.h>
|
||||
#include <console.h>
|
||||
|
||||
/*
|
||||
* Core UART functions to implement for a port
|
||||
|
@ -35,11 +36,23 @@
|
|||
|
||||
// Receive single character
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
#ifdef CONFIG_CONSOLE_PULL
|
||||
return console_getchar();
|
||||
#else
|
||||
return zephyr_getchar();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send string of given length
|
||||
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;
|
||||
if (uart_console_dev == NULL) {
|
||||
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--) {
|
||||
uart_poll_out(uart_console_dev, *str++);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || defined(_MSC_VER)
|
||||
NORETURN void mp_arg_error_terse_mismatch(void) {
|
||||
mp_raise_TypeError("argument num/types mismatch");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
NORETURN void mp_arg_error_unimpl_kw(void) {
|
||||
|
|
6
py/bc.c
6
py/bc.c
|
@ -322,7 +322,7 @@ STATIC const byte opcode_format_table[64] = {
|
|||
OC4(O, O, U, U), // 0x38-0x3b
|
||||
OC4(U, O, B, O), // 0x3c-0x3f
|
||||
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), // 0x4c-0x4f
|
||||
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), // 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), // 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), // 0xf4-0xf7
|
||||
OC4(B, B, B, U), // 0xf8-0xfb
|
||||
OC4(U, U, U, U), // 0xf8-0xfb
|
||||
OC4(U, U, U, U), // 0xfc-0xff
|
||||
};
|
||||
#undef OC4
|
||||
|
|
4
py/bc0.h
4
py/bc0.h
|
@ -113,7 +113,7 @@
|
|||
#define MP_BC_LOAD_CONST_SMALL_INT_MULTI (0x70) // + N(64)
|
||||
#define MP_BC_LOAD_FAST_MULTI (0xb0) // + 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_BINARY_OP_MULTI (0xd7) // + op(36)
|
||||
#define MP_BC_UNARY_OP_MULTI (0xd0) // + op(<MP_UNARY_OP_NUM_BYTECODE)
|
||||
#define MP_BC_BINARY_OP_MULTI (0xd7) // + op(<MP_BINARY_OP_NUM_BYTECODE)
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_BC0_H
|
||||
|
|
|
@ -123,6 +123,8 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
|
|||
[MP_F_NEW_CELL] = 1,
|
||||
[MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3,
|
||||
[MP_F_SETUP_CODE_STATE] = 5,
|
||||
[MP_F_SMALL_INT_FLOOR_DIVIDE] = 2,
|
||||
[MP_F_SMALL_INT_MODULO] = 2,
|
||||
};
|
||||
|
||||
#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_rhs = peek_vtype(emit, 0);
|
||||
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
|
||||
// special cases for x86 and shifting
|
||||
if (op == MP_BINARY_OP_LSHIFT
|
||||
|| op == MP_BINARY_OP_INPLACE_LSHIFT
|
||||
|| op == MP_BINARY_OP_RSHIFT
|
||||
|| op == MP_BINARY_OP_INPLACE_RSHIFT) {
|
||||
if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_RSHIFT) {
|
||||
#if N_X64
|
||||
emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X64_REG_RCX, &vtype_lhs, REG_RET);
|
||||
#else
|
||||
emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X86_REG_ECX, &vtype_lhs, REG_RET);
|
||||
#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);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
#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;
|
||||
emit_pre_pop_reg_flexible(emit, &vtype_rhs, ®_rhs, REG_RET, REG_ARG_2);
|
||||
emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2);
|
||||
if (0) {
|
||||
// dummy
|
||||
#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);
|
||||
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);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
#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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (MP_BINARY_OP_LESS <= op && op <= MP_BINARY_OP_NOT_EQUAL) {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "py/formatfloat.h"
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -68,12 +69,10 @@ union floatbits {
|
|||
uint32_t u;
|
||||
};
|
||||
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; }
|
||||
static inline int fp_isinf(float x) { union floatbits fb = {x}; return (fb.u & FLT_MAN_MASK) == 0; }
|
||||
#define fp_isnan(x) isnan(x)
|
||||
#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_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
|
||||
|
||||
|
@ -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 FPDECEXP 256
|
||||
#define FPMIN_BUF_SIZE 7 // +9e+199
|
||||
#include <math.h>
|
||||
#define fp_signbit(x) signbit(x)
|
||||
#define fp_isspecial(x) 1
|
||||
#define fp_isnan(x) isnan(x)
|
||||
#define fp_isinf(x) isinf(x)
|
||||
#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;
|
||||
}
|
||||
if (fp_signbit(f)) {
|
||||
if (fp_signbit(f) && !fp_isnan(f)) {
|
||||
*s++ = '-';
|
||||
f = -f;
|
||||
} 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.
|
||||
int buf_remaining = buf_size - 1 - (s - buf);
|
||||
|
||||
if (fp_isspecial(f)) {
|
||||
{
|
||||
char uc = fmt & 0x20;
|
||||
if (fp_isinf(f)) {
|
||||
*s++ = 'I' ^ uc;
|
||||
|
|
|
@ -108,7 +108,15 @@ def parse_input_headers(infiles):
|
|||
continue
|
||||
|
||||
# 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:
|
||||
sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n")
|
||||
|
|
|
@ -68,13 +68,7 @@ LD += -m32
|
|||
endif
|
||||
|
||||
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
|
||||
endif
|
||||
MPY_TOOL = $(TOP)/tools/mpy-tool.py
|
||||
|
||||
all:
|
||||
|
|
|
@ -144,13 +144,13 @@ $(PROG): $(OBJ)
|
|||
# we may want to compile using Thumb, but link with non-Thumb libc.
|
||||
$(Q)$(CC) -o $@ $^ $(LIB) $(LDFLAGS)
|
||||
ifndef DEBUG
|
||||
$(Q)$(STRIP) $(STRIPFLAGS_EXTRA) $(PROG)$(PROG_EXT)
|
||||
$(Q)$(STRIP) $(STRIPFLAGS_EXTRA) $(PROG)
|
||||
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-prog:
|
||||
$(RM) -f $(PROG)$(PROG_EXT)
|
||||
$(RM) -f $(PROG)
|
||||
$(RM) -f $(PROG).map
|
||||
|
||||
.PHONY: clean-prog
|
||||
|
|
|
@ -348,31 +348,16 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
|
|||
if (MP_OBJ_IS_STR(o_in)) {
|
||||
len = unichar_charlen(str, len);
|
||||
if (len == 1) {
|
||||
if (!UTF8_IS_NONASCII(*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);
|
||||
return mp_obj_new_int(utf8_get_char((const byte*)str));
|
||||
}
|
||||
} else {
|
||||
// a bytes object
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// a bytes object, or a str without unicode support (don't sign extend the char)
|
||||
if (len == 1) {
|
||||
return_first_byte:
|
||||
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) {
|
||||
mp_raise_TypeError("ord expects a character");
|
||||
|
|
75
py/modmath.c
75
py/modmath.c
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* 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
|
||||
* 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");
|
||||
}
|
||||
|
||||
#define MATH_FUN_1(py_name, c_name) \
|
||||
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))); } \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
STATIC mp_obj_t math_generic_1(mp_obj_t x_obj, mp_float_t (*f)(mp_float_t)) {
|
||||
mp_float_t x = mp_obj_get_float(x_obj);
|
||||
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 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))); } \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_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)) {
|
||||
mp_float_t x = mp_obj_get_float(x_obj);
|
||||
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) \
|
||||
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_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) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { \
|
||||
mp_float_t x = mp_obj_get_float(x_obj); \
|
||||
if (error_condition) { \
|
||||
math_error(); \
|
||||
} \
|
||||
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(x)); \
|
||||
#define MATH_FUN_2(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { \
|
||||
return math_generic_2(x_obj, y_obj, MICROPY_FLOAT_C_FUN(c_name)); \
|
||||
} \
|
||||
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
|
||||
#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
|
||||
|
||||
// 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
|
||||
MATH_FUN_2(pow, pow)
|
||||
// exp(x)
|
||||
|
@ -81,9 +104,9 @@ MATH_FUN_1(exp, exp)
|
|||
// expm1(x)
|
||||
MATH_FUN_1(expm1, expm1)
|
||||
// log2(x)
|
||||
MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0))
|
||||
MATH_FUN_1(log2, log2)
|
||||
// log10(x)
|
||||
MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0))
|
||||
MATH_FUN_1(log10, log10)
|
||||
// cosh(x)
|
||||
MATH_FUN_1(cosh, cosh)
|
||||
// sinh(x)
|
||||
|
@ -114,9 +137,15 @@ MATH_FUN_2(atan2, atan2)
|
|||
// ceil(x)
|
||||
MATH_FUN_1_TO_INT(ceil, ceil)
|
||||
// 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)
|
||||
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)
|
||||
MATH_FUN_1_TO_INT(floor, floor) //TODO: delegate to x.__floor__() if x is not a float
|
||||
// fmod(x, y)
|
||||
|
@ -130,7 +159,7 @@ MATH_FUN_1_TO_BOOL(isnan, isnan)
|
|||
// trunc(x)
|
||||
MATH_FUN_1_TO_INT(trunc, trunc)
|
||||
// ldexp(x, exp)
|
||||
MATH_FUN_2(ldexp, ldexp)
|
||||
MATH_FUN_2_FLT_INT(ldexp, ldexp)
|
||||
#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
|
||||
// erf(x): return the error function of x
|
||||
MATH_FUN_1(erf, erf)
|
||||
|
|
|
@ -775,16 +775,24 @@ typedef double mp_float_t;
|
|||
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (0)
|
||||
#endif
|
||||
|
||||
// Whether to support complete set of special methods
|
||||
// for user classes, or only the most used ones. "Reverse"
|
||||
// methods are controlled by MICROPY_PY_REVERSE_SPECIAL_METHODS
|
||||
// below.
|
||||
// Whether to support complete set of special methods for user
|
||||
// classes, or only the most used ones. "Inplace" methods are
|
||||
// controlled by MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS below.
|
||||
// "Reverse" methods are controlled by
|
||||
// MICROPY_PY_REVERSE_SPECIAL_METHODS below.
|
||||
#ifndef MICROPY_PY_ALL_SPECIAL_METHODS
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
|
||||
#endif
|
||||
|
||||
// Whether to support reverse arithmetic operarions methods
|
||||
// (__radd__, etc.)
|
||||
// Whether to support all inplace arithmetic operarion methods
|
||||
// (__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
|
||||
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
|
||||
#endif
|
||||
|
@ -1111,6 +1119,8 @@ typedef double mp_float_t;
|
|||
|
||||
#ifndef MICROPY_PY_USSL
|
||||
#define MICROPY_PY_USSL (0)
|
||||
// Whether to add finaliser code to ussl objects
|
||||
#define MICROPY_PY_USSL_FINALISER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_WEBSOCKET
|
||||
|
|
|
@ -168,7 +168,7 @@ typedef struct _mp_state_vm_t {
|
|||
// root pointers for extmod
|
||||
|
||||
#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;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/emitglue.h"
|
||||
#include "py/bc.h"
|
||||
|
||||
|
@ -170,6 +171,8 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
|
|||
mp_obj_new_cell,
|
||||
mp_make_closure_from_raw_code,
|
||||
mp_setup_code_state,
|
||||
mp_small_int_floor_divide,
|
||||
mp_small_int_modulo,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
if (MP_OBJ_IS_INT(rhs_in) || mp_obj_is_float(rhs_in)) {
|
||||
mp_raise_NotImplementedError("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
|
||||
return mp_const_false;
|
||||
|
|
|
@ -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_bound_slice_t 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;
|
||||
|
@ -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_bound_slice_t 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);
|
||||
//printf("Len adj: %d\n", len_adj);
|
||||
|
|
98
py/objtype.c
98
py/objtype.c
|
@ -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);
|
||||
}
|
||||
|
||||
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_LEN] = MP_QSTR___len__,
|
||||
[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_NEGATIVE] = MP_QSTR___neg__,
|
||||
[MP_UNARY_OP_INVERT] = MP_QSTR___invert__,
|
||||
[MP_UNARY_OP_ABS] = MP_QSTR___abs__,
|
||||
#endif
|
||||
#if MICROPY_PY_SYS_GETSIZEOF
|
||||
[MP_UNARY_OP_SIZEOF] = MP_QSTR_getsizeof,
|
||||
[MP_UNARY_OP_SIZEOF] = MP_QSTR___sizeof__,
|
||||
#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) {
|
||||
|
@ -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[] = {
|
||||
/*
|
||||
MP_BINARY_OP_OR,
|
||||
MP_BINARY_OP_XOR,
|
||||
MP_BINARY_OP_AND,
|
||||
MP_BINARY_OP_LSHIFT,
|
||||
MP_BINARY_OP_RSHIFT,
|
||||
*/
|
||||
// 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
|
||||
// fail). They can be added at the expense of code size for the qstr.
|
||||
// Qstrs for special methods are guaranteed to have a small value, so we use byte
|
||||
// type to represent them.
|
||||
const byte mp_binary_op_method_name[MP_BINARY_OP_NUM_RUNTIME] = {
|
||||
[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_SUBTRACT] = MP_QSTR___sub__,
|
||||
#if MICROPY_PY_ALL_SPECIAL_METHODS
|
||||
[MP_BINARY_OP_MULTIPLY] = MP_QSTR___mul__,
|
||||
[MP_BINARY_OP_FLOOR_DIVIDE] = MP_QSTR___floordiv__,
|
||||
[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
|
||||
/*
|
||||
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
|
||||
[MP_BINARY_OP_REVERSE_ADD] = MP_QSTR___radd__,
|
||||
[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_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
|
||||
|
||||
[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) {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "py/smallint.h"
|
||||
|
||||
// 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
|
||||
// affect the generate bytecode.
|
||||
|
|
|
@ -108,6 +108,13 @@ void mp_init(void) {
|
|||
MP_STATE_VM(mp_module_builtins_override_dict) = NULL;
|
||||
#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
|
||||
// zero out the pointers to the user-mounted devices
|
||||
memset(MP_STATE_VM(fs_user_mount) + MICROPY_FATFS_NUM_PERSISTENT, 0,
|
||||
|
|
|
@ -57,8 +57,8 @@ typedef struct _mp_arg_t {
|
|||
} mp_arg_t;
|
||||
|
||||
// Tables mapping operator enums to qstrs, defined in objtype.c
|
||||
extern const uint16_t mp_unary_op_method_name[];
|
||||
extern const uint16_t mp_binary_op_method_name[];
|
||||
extern const byte mp_unary_op_method_name[];
|
||||
extern const byte mp_binary_op_method_name[];
|
||||
|
||||
void mp_init(void);
|
||||
void mp_deinit(void);
|
||||
|
|
|
@ -53,41 +53,38 @@ typedef enum {
|
|||
MP_UNARY_OP_NOT,
|
||||
|
||||
// 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_HASH, // __hash__; must return a small int
|
||||
MP_UNARY_OP_ABS, // __abs__
|
||||
MP_UNARY_OP_SIZEOF, // for sys.getsizeof()
|
||||
|
||||
MP_UNARY_OP_NUM_RUNTIME,
|
||||
} 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.
|
||||
typedef enum {
|
||||
// Relational operations, should return a bool
|
||||
// 9 relational operations, should return a bool
|
||||
MP_BINARY_OP_LESS,
|
||||
MP_BINARY_OP_MORE,
|
||||
MP_BINARY_OP_EQUAL,
|
||||
MP_BINARY_OP_LESS_EQUAL,
|
||||
MP_BINARY_OP_MORE_EQUAL,
|
||||
MP_BINARY_OP_NOT_EQUAL,
|
||||
|
||||
MP_BINARY_OP_IN,
|
||||
MP_BINARY_OP_IS,
|
||||
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_XOR,
|
||||
MP_BINARY_OP_INPLACE_AND,
|
||||
MP_BINARY_OP_INPLACE_LSHIFT,
|
||||
MP_BINARY_OP_INPLACE_RSHIFT,
|
||||
MP_BINARY_OP_INPLACE_ADD,
|
||||
|
||||
MP_BINARY_OP_INPLACE_SUBTRACT,
|
||||
MP_BINARY_OP_INPLACE_MULTIPLY,
|
||||
MP_BINARY_OP_INPLACE_FLOOR_DIVIDE,
|
||||
|
@ -95,13 +92,13 @@ typedef enum {
|
|||
MP_BINARY_OP_INPLACE_MODULO,
|
||||
MP_BINARY_OP_INPLACE_POWER,
|
||||
|
||||
// 12 normal arithmetic operations
|
||||
MP_BINARY_OP_OR,
|
||||
MP_BINARY_OP_XOR,
|
||||
MP_BINARY_OP_AND,
|
||||
MP_BINARY_OP_LSHIFT,
|
||||
MP_BINARY_OP_RSHIFT,
|
||||
MP_BINARY_OP_ADD,
|
||||
|
||||
MP_BINARY_OP_SUBTRACT,
|
||||
MP_BINARY_OP_MULTIPLY,
|
||||
MP_BINARY_OP_FLOOR_DIVIDE,
|
||||
|
@ -111,16 +108,16 @@ typedef enum {
|
|||
|
||||
// Operations below this line don't appear in bytecode, they
|
||||
// just identify special methods.
|
||||
MP_BINARY_OP_NUM_BYTECODE,
|
||||
|
||||
// MP_BINARY_OP_REVERSE_* must follow immediately after MP_BINARY_OP_*
|
||||
#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_AND,
|
||||
MP_BINARY_OP_REVERSE_LSHIFT,
|
||||
MP_BINARY_OP_REVERSE_RSHIFT,
|
||||
MP_BINARY_OP_REVERSE_ADD,
|
||||
|
||||
MP_BINARY_OP_REVERSE_SUBTRACT,
|
||||
MP_BINARY_OP_REVERSE_MULTIPLY,
|
||||
MP_BINARY_OP_REVERSE_FLOOR_DIVIDE,
|
||||
|
@ -129,9 +126,18 @@ typedef enum {
|
|||
MP_BINARY_OP_REVERSE_POWER,
|
||||
#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;
|
||||
|
||||
typedef enum {
|
||||
|
@ -181,6 +187,8 @@ typedef enum {
|
|||
MP_F_NEW_CELL,
|
||||
MP_F_MAKE_CLOSURE_FROM_RAW_CODE,
|
||||
MP_F_SETUP_CODE_STATE,
|
||||
MP_F_SMALL_INT_FLOOR_DIVIDE,
|
||||
MP_F_SMALL_INT_MODULO,
|
||||
MP_F_NUMBER_OF,
|
||||
} mp_fun_kind_t;
|
||||
|
||||
|
|
|
@ -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);
|
||||
} 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);
|
||||
} 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);
|
||||
} 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;
|
||||
printf("BINARY_OP " UINT_FMT " %s", op, qstr_str(mp_binary_op_method_name[op]));
|
||||
} else {
|
||||
|
|
|
@ -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_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_UNARY_OP_MULTI ... MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NON_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_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 + MP_BINARY_OP_NUM_BYTECODE - 1] = &&entry_MP_BC_BINARY_OP_MULTI,
|
||||
};
|
||||
|
||||
#if __clang__
|
||||
|
|
|
@ -30,21 +30,21 @@
|
|||
#include "shared-bindings/multiterminal/__init__.h"
|
||||
|
||||
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;
|
||||
} 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) {
|
||||
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) {
|
||||
MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -43,9 +43,9 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
|||
bc=\\d\+ line=126
|
||||
00 LOAD_CONST_NONE
|
||||
01 LOAD_CONST_FALSE
|
||||
02 BINARY_OP 28 __add__
|
||||
02 BINARY_OP 26 __add__
|
||||
03 LOAD_CONST_TRUE
|
||||
04 BINARY_OP 28 __add__
|
||||
04 BINARY_OP 26 __add__
|
||||
05 STORE_FAST 0
|
||||
06 LOAD_CONST_SMALL_INT 0
|
||||
07 STORE_FAST 0
|
||||
|
@ -84,7 +84,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
|||
\\d\+ STORE_FAST 7
|
||||
\\d\+ LOAD_FAST 0
|
||||
\\d\+ LOAD_DEREF 14
|
||||
\\d\+ BINARY_OP 28 __add__
|
||||
\\d\+ BINARY_OP 26 __add__
|
||||
\\d\+ STORE_FAST 8
|
||||
\\d\+ LOAD_FAST 0
|
||||
\\d\+ UNARY_OP 1
|
||||
|
@ -132,7 +132,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
|||
\\d\+ DUP_TOP_TWO
|
||||
\\d\+ LOAD_SUBSCR
|
||||
\\d\+ LOAD_FAST 12
|
||||
\\d\+ BINARY_OP 16 __iadd__
|
||||
\\d\+ BINARY_OP 14 __iadd__
|
||||
\\d\+ ROT_THREE
|
||||
\\d\+ STORE_SUBSCR
|
||||
\\d\+ LOAD_DEREF 14
|
||||
|
@ -369,7 +369,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
|||
42 STORE_FAST_N 19
|
||||
44 LOAD_FAST 9
|
||||
45 LOAD_FAST_N 19
|
||||
47 BINARY_OP 28 __add__
|
||||
47 BINARY_OP 26 __add__
|
||||
48 POP_TOP
|
||||
49 LOAD_CONST_NONE
|
||||
50 RETURN_VALUE
|
||||
|
@ -521,7 +521,7 @@ arg names: *
|
|||
bc=\\d\+ line=113
|
||||
00 LOAD_DEREF 0
|
||||
02 LOAD_CONST_SMALL_INT 1
|
||||
03 BINARY_OP 28 __add__
|
||||
03 BINARY_OP 26 __add__
|
||||
04 STORE_FAST 1
|
||||
05 LOAD_CONST_SMALL_INT 1
|
||||
06 STORE_DEREF 0
|
||||
|
@ -540,7 +540,7 @@ arg names: * b
|
|||
bc=\\d\+ line=139
|
||||
00 LOAD_FAST 1
|
||||
01 LOAD_DEREF 0
|
||||
03 BINARY_OP 28 __add__
|
||||
03 BINARY_OP 26 __add__
|
||||
04 RETURN_VALUE
|
||||
mem: total=\\d\+, current=\\d\+, peak=\\d\+
|
||||
stack: \\d\+ out of \\d\+
|
||||
|
|
|
@ -48,7 +48,12 @@ m = r.match("d")
|
|||
print(m.group(0))
|
||||
m = r.match("A")
|
||||
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+")
|
||||
m = r.search("foobar")
|
||||
|
|
|
@ -59,6 +59,7 @@ ans = (-1.2) ** -3.4; print("%.5g %.5g" % (ans.real, ans.imag))
|
|||
|
||||
# check printing of inf/nan
|
||||
print(float('nan') * 1j)
|
||||
print(float('-nan') * 1j)
|
||||
print(float('inf') * (1 + 1j))
|
||||
print(float('-inf') * (1 + 1j))
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ print(float("INF"))
|
|||
print(float("infinity"))
|
||||
print(float("INFINITY"))
|
||||
print(float("nan"))
|
||||
print(float("-nan"))
|
||||
print(float("NaN"))
|
||||
try:
|
||||
float("")
|
||||
|
|
|
@ -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')
|
|
@ -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')
|
|
@ -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)
|
|
@ -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
|
|
@ -6,6 +6,8 @@ try:
|
|||
import ussl as ssl
|
||||
except:
|
||||
import ssl
|
||||
# CPython only supports server_hostname with SSLContext
|
||||
ssl = ssl.SSLContext()
|
||||
|
||||
|
||||
def test_one(site, opts):
|
||||
|
@ -22,7 +24,7 @@ def test_one(site, opts):
|
|||
else:
|
||||
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)
|
||||
# print(resp)
|
||||
|
||||
|
@ -34,6 +36,7 @@ SITES = [
|
|||
"google.com",
|
||||
"www.google.com",
|
||||
"api.telegram.org",
|
||||
{"host": "api.pushbullet.com", "sni": True},
|
||||
# "w9rybpfril.execute-api.ap-southeast-2.amazonaws.com",
|
||||
{"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
Loading…
Reference in New Issue