This commit is contained in:
Amir Gonnen 2019-09-28 00:13:21 +03:00
commit 39a93b48cd
222 changed files with 5417 additions and 923 deletions

3
.gitignore vendored
View File

@ -30,9 +30,10 @@ Session.vim
tags tags
TAGS TAGS
# Build directory # Build directories
###################### ######################
build/ build/
build-*/
# Test failure outputs # Test failure outputs
###################### ######################

View File

@ -115,6 +115,17 @@ jobs:
- make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1" - make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1"
- make ${MAKEOPTS} -C ports/unix CC=clang test - make ${MAKEOPTS} -C ports/unix CC=clang test
# unix with sys.settrace
- stage: test
env: NAME="unix port with sys.settrace build and tests"
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_PY_SYS_SETTRACE=1" test
- make ${MAKEOPTS} -C ports/unix clean
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" test
after_failure:
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
# windows port via mingw # windows port via mingw
- stage: test - stage: test
env: NAME="windows port build via mingw" env: NAME="windows port build via mingw"

View File

@ -36,6 +36,51 @@ Functions
Read the raw value of the internal Hall sensor, returning an integer. Read the raw value of the internal Hall sensor, returning an integer.
Flash partitions
----------------
This class gives access to the partitions in the device's flash memory.
.. class:: Partition(id)
Create an object representing a partition. *id* can be a string which is the label
of the partition to retrieve, or one of the constants: ``BOOT`` or ``RUNNING``.
.. classmethod:: Partition.find(type=TYPE_APP, subtype=0xff, label=None)
Find a partition specified by *type*, *subtype* and *label*. Returns a
(possibly empty) list of Partition objects.
.. method:: Partition.info()
Returns a 6-tuple ``(type, subtype, addr, size, label, encrypted)``.
.. method:: Partition.readblocks(block_num, buf)
.. method:: Partition.writeblocks(block_num, buf)
.. method:: Partition.ioctl(cmd, arg)
These methods implement the block protocol defined by :class:`uos.AbstractBlockDev`.
.. method:: Partition.set_boot()
Sets the partition as the boot partition.
.. method:: Partition.get_next_update()
Gets the next update partition after this one, and returns a new Partition object.
Constants
~~~~~~~~~
.. data:: Partition.BOOT
Partition.RUNNING
Used in the `Partition` constructor to fetch various partitions.
.. data:: Partition.TYPE_APP
Partition.TYPE_DATA
Used in `Partition.find` to specify the partition type.
The Ultra-Low-Power co-processor The Ultra-Low-Power co-processor
-------------------------------- --------------------------------

View File

@ -136,6 +136,7 @@ The following libraries and classes are specific to the WiPy.
:maxdepth: 2 :maxdepth: 2
wipy.rst wipy.rst
machine.ADCWiPy.rst
machine.TimerWiPy.rst machine.TimerWiPy.rst

View File

@ -4,71 +4,32 @@
class ADC -- analog to digital conversion class ADC -- analog to digital conversion
========================================= =========================================
Usage:: The ADC class provides an interface to analog-to-digital convertors, and
represents a single endpoint that can sample a continuous voltage and
convert it to a discretised value.
Example usage::
import machine import machine
adc = machine.ADC() # create an ADC object adc = machine.ADC(pin) # create an ADC object acting on a pin
apin = adc.channel(pin='GP3') # create an analog pin on GP3 val = adc.read_u16() # read a raw analog value in the range 0-65535
val = apin() # read an analog value
Constructors Constructors
------------ ------------
.. class:: ADC(id=0, \*, bits=12) .. class:: ADC(id)
Create an ADC object associated with the given pin. Access the ADC associated with a source identified by *id*. This
This allows you to then read analog values on that pin. *id* may be an integer (usually specifying a channel number), a
For more info check the `pinout and alternate functions :ref:`Pin <machine.Pin>` object, or other value supported by the
table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ underlying machine.
.. warning::
ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it
can withstand). When GP2, GP3, GP4 or GP5 are remapped to the
ADC block, 1.8 V is the maximum. If these pins are used in digital mode,
then the maximum allowed input is 3.6V.
Methods Methods
------- -------
.. method:: ADC.channel(id, \*, pin) .. method:: ADC.read_u16()
Create an analog pin. If only channel ID is given, the correct pin will Take an analog reading and return an integer in the range 0-65535.
be selected. Alternatively, only the pin can be passed and the correct The return value represents the raw reading taken by the ADC, scaled
channel will be selected. Examples:: such that the minimum value is 0 and the maximum value is 65535.
# all of these are equivalent and enable ADC channel 1 on GP3
apin = adc.channel(1)
apin = adc.channel(pin='GP3')
apin = adc.channel(id=1, pin='GP3')
.. method:: ADC.init()
Enable the ADC block.
.. method:: ADC.deinit()
Disable the ADC block.
class ADCChannel --- read analog values from internal or external sources
=========================================================================
ADC channels can be connected to internal points of the MCU or to GPIO pins.
ADC channels are created using the ADC.channel method.
.. method:: adcchannel()
Fast method to read the channel value.
.. method:: adcchannel.value()
Read the channel value.
.. method:: adcchannel.init()
Re-init (and effectively enable) the ADC channel.
.. method:: adcchannel.deinit()
Disable the ADC channel.

View File

@ -0,0 +1,81 @@
.. currentmodule:: machine
.. _machine.ADCWiPy:
class ADCWiPy -- analog to digital conversion
=============================================
.. note::
This class is a non-standard ADC implementation for the WiPy.
It is available simply as ``machine.ADC`` on the WiPy but is named in the
documentation below as ``machine.ADCWiPy`` to distinguish it from the
more general :ref:`machine.ADC <machine.ADC>` class.
Usage::
import machine
adc = machine.ADC() # create an ADC object
apin = adc.channel(pin='GP3') # create an analog pin on GP3
val = apin() # read an analog value
Constructors
------------
.. class:: ADCWiPy(id=0, \*, bits=12)
Create an ADC object associated with the given pin.
This allows you to then read analog values on that pin.
For more info check the `pinout and alternate functions
table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
.. warning::
ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it
can withstand). When GP2, GP3, GP4 or GP5 are remapped to the
ADC block, 1.8 V is the maximum. If these pins are used in digital mode,
then the maximum allowed input is 3.6V.
Methods
-------
.. method:: ADCWiPy.channel(id, \*, pin)
Create an analog pin. If only channel ID is given, the correct pin will
be selected. Alternatively, only the pin can be passed and the correct
channel will be selected. Examples::
# all of these are equivalent and enable ADC channel 1 on GP3
apin = adc.channel(1)
apin = adc.channel(pin='GP3')
apin = adc.channel(id=1, pin='GP3')
.. method:: ADCWiPy.init()
Enable the ADC block.
.. method:: ADCWiPy.deinit()
Disable the ADC block.
class ADCChannel --- read analog values from internal or external sources
=========================================================================
ADC channels can be connected to internal points of the MCU or to GPIO pins.
ADC channels are created using the ADC.channel method.
.. method:: adcchannel()
Fast method to read the channel value.
.. method:: adcchannel.value()
Read the channel value.
.. method:: adcchannel.init()
Re-init (and effectively enable) the ADC channel.
.. method:: adcchannel.deinit()
Disable the ADC channel.

View File

@ -93,9 +93,9 @@ Methods
.. method:: DAC.triangle(freq) .. method:: DAC.triangle(freq)
Generate a triangle wave. The value on the DAC output changes at Generate a triangle wave. The value on the DAC output changes at the given
the given frequency, and the frequency of the repeating triangle wave frequency and ramps through the full 12-bit range (up and down). Therefore
itself is 2048 times smaller. the frequency of the repeating triangle wave itself is 8192 times smaller.
.. method:: DAC.write(value) .. method:: DAC.write(value)

View File

@ -259,34 +259,45 @@ Miscellaneous functions
Returns a string of 12 bytes (96 bits), which is the unique ID of the MCU. Returns a string of 12 bytes (96 bits), which is the unique ID of the MCU.
.. function:: usb_mode([modestr], vid=0xf055, pid=0x9801, hid=pyb.hid_mouse) .. function:: usb_mode([modestr], port=-1, vid=0xf055, pid=-1, msc=(), hid=pyb.hid_mouse, high_speed=False)
If called with no arguments, return the current USB mode as a string. If called with no arguments, return the current USB mode as a string.
If called with ``modestr`` provided, attempts to set USB mode. If called with *modestr* provided, attempts to configure the USB mode.
This can only be done when called from ``boot.py`` before The following values of *modestr* are understood:
:meth:`pyb.main()` has been called. The following values of
``modestr`` are understood:
- ``None``: disables USB - ``None``: disables USB
- ``'VCP'``: enable with VCP (Virtual COM Port) interface - ``'VCP'``: enable with VCP (Virtual COM Port) interface
- ``'MSC'``: enable with MSC (mass storage device class) interface - ``'MSC'``: enable with MSC (mass storage device class) interface
- ``'VCP+MSC'``: enable with VCP and MSC - ``'VCP+MSC'``: enable with VCP and MSC
- ``'VCP+HID'``: enable with VCP and HID (human interface device) - ``'VCP+HID'``: enable with VCP and HID (human interface device)
- ``'VCP+MSC+HID'``: enabled with VCP, MSC and HID (only available on PYBD boards)
For backwards compatibility, ``'CDC'`` is understood to mean For backwards compatibility, ``'CDC'`` is understood to mean
``'VCP'`` (and similarly for ``'CDC+MSC'`` and ``'CDC+HID'``). ``'VCP'`` (and similarly for ``'CDC+MSC'`` and ``'CDC+HID'``).
The ``vid`` and ``pid`` parameters allow you to specify the VID The *port* parameter should be an integer (0, 1, ...) and selects which
(vendor id) and PID (product id). USB port to use if the board supports multiple ports. A value of -1 uses
the default or automatically selected port.
The *vid* and *pid* parameters allow you to specify the VID (vendor id)
and PID (product id). A *pid* value of -1 will select a PID based on the
value of *modestr*.
If enabling MSC mode, the *msc* parameter can be used to specify a list
of SCSI LUNs to expose on the mass storage interface. For example
``msc=(pyb.Flash(), pyb.SDCard())``.
If enabling HID mode, you may also specify the HID details by If enabling HID mode, you may also specify the HID details by
passing the ``hid`` keyword parameter. It takes a tuple of passing the *hid* keyword parameter. It takes a tuple of
(subclass, protocol, max packet length, polling interval, report (subclass, protocol, max packet length, polling interval, report
descriptor). By default it will set appropriate values for a USB descriptor). By default it will set appropriate values for a USB
mouse. There is also a ``pyb.hid_keyboard`` constant, which is an mouse. There is also a ``pyb.hid_keyboard`` constant, which is an
appropriate tuple for a USB keyboard. appropriate tuple for a USB keyboard.
The *high_speed* parameter, when set to ``True``, enables USB HS mode if
it is supported by the hardware.
Classes Classes
------- -------

View File

@ -15,6 +15,19 @@ Functions
function raise as `SystemExit` exception. If an argument is given, its function raise as `SystemExit` exception. If an argument is given, its
value given as an argument to `SystemExit`. value given as an argument to `SystemExit`.
.. function:: atexit(func)
Register *func* to be called upon termination. *func* must be a callable
that takes no arguments, or ``None`` to disable the call. The ``atexit``
function will return the previous value set by this function, which is
initially ``None``.
.. admonition:: Difference to CPython
:class: attention
This function is a MicroPython extension intended to provide similar
functionality to the :mod:`atexit` module in CPython.
.. function:: print_exception(exc, file=sys.stdout) .. function:: print_exception(exc, file=sys.stdout)
Print exception with a traceback to a file-like object *file* (or Print exception with a traceback to a file-like object *file* (or
@ -121,3 +134,9 @@ Constants
.. data:: version_info .. data:: version_info
Python language version that this implementation conforms to, as a tuple of ints. Python language version that this implementation conforms to, as a tuple of ints.
.. admonition:: Difference to CPython
:class: attention
Only the first three version numbers (major, minor, micro) are supported and
they can be referenced only by index, not by name.

View File

@ -31,7 +31,7 @@ have as to what happens next:
We will get the serial device working in the next tutorial. We will get the serial device working in the next tutorial.
- **Mac**: Your pyboard will appear on the desktop as a removable disc. - **Mac**: Your pyboard will appear on the desktop as a removable disc.
It will probably be called "NONAME". Click on it to open the pyboard folder. It will probably be called ``PYBFLASH``. Click on it to open the pyboard folder.
- **Linux**: Your pyboard will appear as a removable medium. On Ubuntu - **Linux**: Your pyboard will appear as a removable medium. On Ubuntu
it will mount automatically and pop-up a window with the pyboard folder. it will mount automatically and pop-up a window with the pyboard folder.
@ -46,17 +46,17 @@ a window (or command line) should be showing the files on the pyboard drive.
The drive you are looking at is known as ``/flash`` by the pyboard, and should contain The drive you are looking at is known as ``/flash`` by the pyboard, and should contain
the following 4 files: the following 4 files:
* `boot.py <http://micropython.org/resources/fresh-pyboard/boot.py>`_ -- this script is executed when the pyboard boots up. It sets * `boot.py <http://micropython.org/resources/fresh-pyboard/boot.py>`_ -- the various configuration options for the pyboard.
up various configuration options for the pyboard. It is executed when the pyboard boots up.
* `main.py <http://micropython.org/resources/fresh-pyboard/main.py>`_ -- this is the main script that will contain your Python program. * `main.py <http://micropython.org/resources/fresh-pyboard/main.py>`_ -- the Python program to be run.
It is executed after ``boot.py``. It is executed after ``boot.py``.
* `README.txt <http://micropython.org/resources/fresh-pyboard/README.txt>`_ -- this contains some very basic information about getting * `README.txt <http://micropython.org/resources/fresh-pyboard/README.txt>`_ -- basic information about getting started with the pyboard.
started with the pyboard. This provides pointers for new users and can be safely deleted.
* `pybcdc.inf <http://micropython.org/resources/fresh-pyboard/pybcdc.inf>`_ -- this is a Windows driver file to configure the serial USB * `pybcdc.inf <http://micropython.org/resources/fresh-pyboard/pybcdc.inf>`_ -- the Windows driver file to configure the serial USB device.
device. More about this in the next tutorial. More about this in the next tutorial.
Editing ``main.py`` Editing ``main.py``
------------------- -------------------

View File

@ -39,14 +39,15 @@ Sending mouse events by hand
To get the py-mouse to do anything we need to send mouse events to the PC. To get the py-mouse to do anything we need to send mouse events to the PC.
We will first do this manually using the REPL prompt. Connect to your We will first do this manually using the REPL prompt. Connect to your
pyboard using your serial program and type the following:: pyboard using your serial program and type the following (no need to type
the ``#`` and text following it)::
>>> hid = pyb.USB_HID() >>> hid = pyb.USB_HID()
>>> hid.send((0, 10, 0, 0)) >>> hid.send((0, 100, 0, 0)) # (button status, x-direction, y-direction, scroll)
Your mouse should move 10 pixels to the right! In the command above you Your mouse should move 100 pixels to the right! In the command above you
are sending 4 pieces of information: button status, x, y and scroll. The are sending 4 pieces of information: **button status**, **x-direction**, **y-direction**, and **scroll**. The
number 10 is telling the PC that the mouse moved 10 pixels in the x direction. number 100 is telling the PC that the mouse moved 100 pixels in the x direction.
Let's make the mouse oscillate left and right:: Let's make the mouse oscillate left and right::

View File

@ -165,7 +165,7 @@ by caching the object in a local variable:
class foo(object): class foo(object):
def __init__(self): def __init__(self):
ba = bytearray(100) self.ba = bytearray(100)
def bar(self, obj_display): def bar(self, obj_display):
ba_ref = self.ba ba_ref = self.ba
fb = obj_display.framebuffer fb = obj_display.framebuffer
@ -293,10 +293,12 @@ microseconds. The rules for casting are as follows:
* The argument to a bool cast must be integral type (boolean or integer); when used as a return * The argument to a bool cast must be integral type (boolean or integer); when used as a return
type the viper function will return True or False objects. type the viper function will return True or False objects.
* If the argument is a Python object and the cast is ``ptr``, ``ptr``, ``ptr16`` or ``ptr32``, * If the argument is a Python object and the cast is ``ptr``, ``ptr``, ``ptr16`` or ``ptr32``,
then the Python object must either have the buffer protocol with read-write capabilities then the Python object must either have the buffer protocol (in which case a pointer to the
(in which case a pointer to the start of the buffer is returned) or it must be of integral start of the buffer is returned) or it must be of integral type (in which case the value of
type (in which case the value of that integral object is returned). that integral object is returned).
Writing to a pointer which points to a read-only object will lead to undefined behaviour.
The following example illustrates the use of a ``ptr16`` cast to toggle pin X1 ``n`` times: The following example illustrates the use of a ``ptr16`` cast to toggle pin X1 ``n`` times:
.. code:: python .. code:: python

View File

@ -82,7 +82,7 @@ See :ref:`machine.Pin <machine.Pin>` and :ref:`machine.Timer <machine.Timer>`. :
ADC (analog to digital conversion) ADC (analog to digital conversion)
---------------------------------- ----------------------------------
See :ref:`machine.ADC <machine.ADC>`. :: See :ref:`machine.ADCWiPy <machine.ADCWiPy>`. ::
from machine import ADC from machine import ADC

View File

@ -41,7 +41,7 @@ mp_obj_t execute_from_str(const char *str) {
qstr src_name = 1/*MP_QSTR_*/; qstr src_name = 1/*MP_QSTR_*/;
mp_lexer_t *lex = mp_lexer_new_from_str_len(src_name, str, strlen(str), false); mp_lexer_t *lex = mp_lexer_new_from_str_len(src_name, str, strlen(str), false);
mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_obj_t module_fun = mp_compile(&pt, src_name, MP_EMIT_OPT_NONE, false); mp_obj_t module_fun = mp_compile(&pt, src_name, false);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
return 0; return 0;

View File

@ -1,7 +1,8 @@
/********************************************************************* /*********************************************************************
* Source: https://github.com/B-Con/crypto-algorithms
* Filename: sha256.c * Filename: sha256.c
* Author: Brad Conte (brad AT bradconte.com) * Author: Brad Conte (brad AT bradconte.com)
* Copyright: * Copyright: This code is released into the public domain.
* Disclaimer: This code is presented "as is" without any guarantees. * Disclaimer: This code is presented "as is" without any guarantees.
* Details: Implementation of the SHA-256 hashing algorithm. * Details: Implementation of the SHA-256 hashing algorithm.
SHA-256 is one of the three algorithms in the SHA2 SHA-256 is one of the three algorithms in the SHA2

View File

@ -1,7 +1,8 @@
/********************************************************************* /*********************************************************************
* Source: https://github.com/B-Con/crypto-algorithms
* Filename: sha256.h * Filename: sha256.h
* Author: Brad Conte (brad AT bradconte.com) * Author: Brad Conte (brad AT bradconte.com)
* Copyright: * Copyright: This code is released into the public domain.
* Disclaimer: This code is presented "as is" without any guarantees. * Disclaimer: This code is presented "as is" without any guarantees.
* Details: Defines the API for the corresponding SHA1 implementation. * Details: Defines the API for the corresponding SHA1 implementation.
*********************************************************************/ *********************************************************************/

View File

@ -89,7 +89,7 @@ typedef struct _mp_obj_aes_t {
uint8_t key_type: 2; uint8_t key_type: 2;
} mp_obj_aes_t; } mp_obj_aes_t;
STATIC inline bool is_ctr_mode(int block_mode) { static inline bool is_ctr_mode(int block_mode) {
#if MICROPY_PY_UCRYPTOLIB_CTR #if MICROPY_PY_UCRYPTOLIB_CTR
return block_mode == UCRYPTOLIB_MODE_CTR; return block_mode == UCRYPTOLIB_MODE_CTR;
#else #else
@ -97,7 +97,7 @@ STATIC inline bool is_ctr_mode(int block_mode) {
#endif #endif
} }
STATIC inline struct ctr_params *ctr_params_from_aes(mp_obj_aes_t *o) { static inline struct ctr_params *ctr_params_from_aes(mp_obj_aes_t *o) {
// ctr_params follows aes object struct // ctr_params follows aes object struct
return (struct ctr_params*)&o[1]; return (struct ctr_params*)&o[1];
} }

View File

@ -299,13 +299,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(uctypes_struct_sizeof_obj, 1, 2, ucty
static inline mp_obj_t get_unaligned(uint val_type, byte *p, int big_endian) { static inline mp_obj_t get_unaligned(uint val_type, byte *p, int big_endian) {
char struct_type = big_endian ? '>' : '<'; char struct_type = big_endian ? '>' : '<';
static const char type2char[16] = "BbHhIiQq------fd"; static const char type2char[16] = "BbHhIiQq------fd";
return mp_binary_get_val(struct_type, type2char[val_type], &p); return mp_binary_get_val(struct_type, type2char[val_type], p, &p);
} }
static inline void set_unaligned(uint val_type, byte *p, int big_endian, mp_obj_t val) { static inline void set_unaligned(uint val_type, byte *p, int big_endian, mp_obj_t val) {
char struct_type = big_endian ? '>' : '<'; char struct_type = big_endian ? '>' : '<';
static const char type2char[16] = "BbHhIiQq------fd"; static const char type2char[16] = "BbHhIiQq------fd";
mp_binary_set_val(struct_type, type2char[val_type], val, &p); mp_binary_set_val(struct_type, type2char[val_type], val, p, &p);
} }
static inline mp_uint_t get_aligned_basic(uint val_type, void *p) { static inline mp_uint_t get_aligned_basic(uint val_type, void *p) {

View File

@ -31,14 +31,14 @@
// the algorithm here is modelled on CPython's heapq.py // the algorithm here is modelled on CPython's heapq.py
STATIC mp_obj_list_t *get_heap(mp_obj_t heap_in) { STATIC mp_obj_list_t *uheapq_get_heap(mp_obj_t heap_in) {
if (!mp_obj_is_type(heap_in, &mp_type_list)) { if (!mp_obj_is_type(heap_in, &mp_type_list)) {
mp_raise_TypeError("heap must be a list"); mp_raise_TypeError("heap must be a list");
} }
return MP_OBJ_TO_PTR(heap_in); return MP_OBJ_TO_PTR(heap_in);
} }
STATIC void heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t pos) { STATIC void uheapq_heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
mp_obj_t item = heap->items[pos]; mp_obj_t item = heap->items[pos];
while (pos > start_pos) { while (pos > start_pos) {
mp_uint_t parent_pos = (pos - 1) >> 1; mp_uint_t parent_pos = (pos - 1) >> 1;
@ -53,7 +53,7 @@ STATIC void heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t po
heap->items[pos] = item; heap->items[pos] = item;
} }
STATIC void heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) { STATIC void uheapq_heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
mp_uint_t start_pos = pos; mp_uint_t start_pos = pos;
mp_uint_t end_pos = heap->len; mp_uint_t end_pos = heap->len;
mp_obj_t item = heap->items[pos]; mp_obj_t item = heap->items[pos];
@ -67,19 +67,19 @@ STATIC void heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
pos = child_pos; pos = child_pos;
} }
heap->items[pos] = item; heap->items[pos] = item;
heap_siftdown(heap, start_pos, pos); uheapq_heap_siftdown(heap, start_pos, pos);
} }
STATIC mp_obj_t mod_uheapq_heappush(mp_obj_t heap_in, mp_obj_t item) { STATIC mp_obj_t mod_uheapq_heappush(mp_obj_t heap_in, mp_obj_t item) {
mp_obj_list_t *heap = get_heap(heap_in); mp_obj_list_t *heap = uheapq_get_heap(heap_in);
mp_obj_list_append(heap_in, item); mp_obj_list_append(heap_in, item);
heap_siftdown(heap, 0, heap->len - 1); uheapq_heap_siftdown(heap, 0, heap->len - 1);
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush);
STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) { STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) {
mp_obj_list_t *heap = get_heap(heap_in); mp_obj_list_t *heap = uheapq_get_heap(heap_in);
if (heap->len == 0) { if (heap->len == 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap")); nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap"));
} }
@ -88,16 +88,16 @@ STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) {
heap->items[0] = heap->items[heap->len]; heap->items[0] = heap->items[heap->len];
heap->items[heap->len] = MP_OBJ_NULL; // so we don't retain a pointer heap->items[heap->len] = MP_OBJ_NULL; // so we don't retain a pointer
if (heap->len) { if (heap->len) {
heap_siftup(heap, 0); uheapq_heap_siftup(heap, 0);
} }
return item; return item;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_uheapq_heappop_obj, mod_uheapq_heappop); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_uheapq_heappop_obj, mod_uheapq_heappop);
STATIC mp_obj_t mod_uheapq_heapify(mp_obj_t heap_in) { STATIC mp_obj_t mod_uheapq_heapify(mp_obj_t heap_in) {
mp_obj_list_t *heap = get_heap(heap_in); mp_obj_list_t *heap = uheapq_get_heap(heap_in);
for (mp_uint_t i = heap->len / 2; i > 0;) { for (mp_uint_t i = heap->len / 2; i > 0;) {
heap_siftup(heap, --i); uheapq_heap_siftup(heap, --i);
} }
return mp_const_none; return mp_const_none;
} }

View File

@ -3,7 +3,7 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2014-2016 Damien P. George * Copyright (c) 2014-2019 Damien P. George
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -281,9 +281,9 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
size_t len; mp_buffer_info_t bufinfo;
const char *buf = mp_obj_str_get_data(obj, &len); mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
vstr_t vstr = {len, len, (char*)buf, true}; vstr_t vstr = {bufinfo.len, bufinfo.len, (char*)bufinfo.buf, true};
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL}; mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
return mod_ujson_load(MP_OBJ_FROM_PTR(&sio)); return mod_ujson_load(MP_OBJ_FROM_PTR(&sio));
} }

View File

@ -382,6 +382,7 @@ STATIC const mp_obj_type_t re_type = {
}; };
STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
(void)n_args;
const char *re_str = mp_obj_str_get_str(args[0]); const char *re_str = mp_obj_str_get_str(args[0]);
int size = re1_5_sizecode(re_str); int size = re1_5_sizecode(re_str);
if (size == -1) { if (size == -1) {
@ -389,18 +390,22 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
} }
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size); mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
o->base.type = &re_type; o->base.type = &re_type;
#if MICROPY_PY_URE_DEBUG
int flags = 0; int flags = 0;
if (n_args > 1) { if (n_args > 1) {
flags = mp_obj_get_int(args[1]); flags = mp_obj_get_int(args[1]);
} }
#endif
int error = re1_5_compilecode(&o->re, re_str); int error = re1_5_compilecode(&o->re, re_str);
if (error != 0) { if (error != 0) {
error: error:
mp_raise_ValueError("Error in regex"); mp_raise_ValueError("Error in regex");
} }
#if MICROPY_PY_URE_DEBUG
if (flags & FLAG_DEBUG) { if (flags & FLAG_DEBUG) {
re1_5_dumpcode(&o->re); re1_5_dumpcode(&o->re);
} }
#endif
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);
@ -440,7 +445,9 @@ STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = {
#if MICROPY_PY_URE_SUB #if MICROPY_PY_URE_SUB
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) }, { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) },
#endif #endif
#if MICROPY_PY_URE_DEBUG
{ MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) }, { MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) },
#endif
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table);
@ -455,7 +462,9 @@ const mp_obj_module_t mp_module_ure = {
#define re1_5_fatal(x) assert(!x) #define re1_5_fatal(x) assert(!x)
#include "re1.5/compilecode.c" #include "re1.5/compilecode.c"
#if MICROPY_PY_URE_DEBUG
#include "re1.5/dumpcode.c" #include "re1.5/dumpcode.c"
#endif
#include "re1.5/recursiveloop.c" #include "re1.5/recursiveloop.c"
#include "re1.5/charclass.c" #include "re1.5/charclass.c"

View File

@ -54,7 +54,7 @@ struct ssl_args {
STATIC const mp_obj_type_t ussl_socket_type; STATIC const mp_obj_type_t ussl_socket_type;
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { STATIC mp_obj_ssl_socket_t *ussl_socket_new(mp_obj_t sock, struct ssl_args *args) {
#if MICROPY_PY_USSL_FINALISER #if MICROPY_PY_USSL_FINALISER
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t); mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
#else #else
@ -118,13 +118,13 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
return o; return o;
} }
STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { STATIC void ussl_socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind; (void)kind;
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "<_SSLSocket %p>", self->ssl_sock); mp_printf(print, "<_SSLSocket %p>", self->ssl_sock);
} }
STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { STATIC mp_uint_t ussl_socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
if (o->ssl_sock == NULL) { if (o->ssl_sock == NULL) {
@ -173,7 +173,7 @@ eagain:
return size; return size;
} }
STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) { STATIC mp_uint_t ussl_socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
if (o->ssl_sock == NULL) { if (o->ssl_sock == NULL) {
@ -189,7 +189,7 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
return r; return r;
} }
STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { STATIC mp_uint_t ussl_socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in); mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in);
if (request == MP_STREAM_CLOSE && self->ssl_sock != NULL) { if (request == MP_STREAM_CLOSE && self->ssl_sock != NULL) {
ssl_free(self->ssl_sock); ssl_free(self->ssl_sock);
@ -200,7 +200,7 @@ STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, i
return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode); return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode);
} }
STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { STATIC mp_obj_t ussl_socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(self_in); mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(self_in);
mp_obj_t sock = o->sock; mp_obj_t sock = o->sock;
mp_obj_t dest[3]; mp_obj_t dest[3];
@ -210,14 +210,14 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
o->blocking = mp_obj_is_true(flag_in); o->blocking = mp_obj_is_true(flag_in);
return res; return res;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); STATIC MP_DEFINE_CONST_FUN_OBJ_2(ussl_socket_setblocking_obj, ussl_socket_setblocking);
STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&ussl_socket_setblocking_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
#if MICROPY_PY_USSL_FINALISER #if MICROPY_PY_USSL_FINALISER
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
@ -227,16 +227,16 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
STATIC const mp_stream_p_t ussl_socket_stream_p = { STATIC const mp_stream_p_t ussl_socket_stream_p = {
.read = socket_read, .read = ussl_socket_read,
.write = socket_write, .write = ussl_socket_write,
.ioctl = socket_ioctl, .ioctl = ussl_socket_ioctl,
}; };
STATIC const mp_obj_type_t ussl_socket_type = { STATIC const mp_obj_type_t ussl_socket_type = {
{ &mp_type_type }, { &mp_type_type },
// Save on qstr's, reuse same as for module // Save on qstr's, reuse same as for module
.name = MP_QSTR_ussl, .name = MP_QSTR_ussl,
.print = socket_print, .print = ussl_socket_print,
.getiter = NULL, .getiter = NULL,
.iternext = NULL, .iternext = NULL,
.protocol = &ussl_socket_stream_p, .protocol = &ussl_socket_stream_p,
@ -260,7 +260,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args);
return MP_OBJ_FROM_PTR(socket_new(sock, &args)); return MP_OBJ_FROM_PTR(ussl_socket_new(sock, &args));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket);

View File

@ -55,7 +55,7 @@ typedef struct _mp_obj_utimeq_t {
STATIC mp_uint_t utimeq_id; STATIC mp_uint_t utimeq_id;
STATIC mp_obj_utimeq_t *get_heap(mp_obj_t heap_in) { STATIC mp_obj_utimeq_t *utimeq_get_heap(mp_obj_t heap_in) {
return MP_OBJ_TO_PTR(heap_in); return MP_OBJ_TO_PTR(heap_in);
} }
@ -85,7 +85,7 @@ STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, size_t
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
STATIC void heap_siftdown(mp_obj_utimeq_t *heap, mp_uint_t start_pos, mp_uint_t pos) { STATIC void utimeq_heap_siftdown(mp_obj_utimeq_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
struct qentry item = heap->items[pos]; struct qentry item = heap->items[pos];
while (pos > start_pos) { while (pos > start_pos) {
mp_uint_t parent_pos = (pos - 1) >> 1; mp_uint_t parent_pos = (pos - 1) >> 1;
@ -101,7 +101,7 @@ STATIC void heap_siftdown(mp_obj_utimeq_t *heap, mp_uint_t start_pos, mp_uint_t
heap->items[pos] = item; heap->items[pos] = item;
} }
STATIC void heap_siftup(mp_obj_utimeq_t *heap, mp_uint_t pos) { STATIC void utimeq_heap_siftup(mp_obj_utimeq_t *heap, mp_uint_t pos) {
mp_uint_t start_pos = pos; mp_uint_t start_pos = pos;
mp_uint_t end_pos = heap->len; mp_uint_t end_pos = heap->len;
struct qentry item = heap->items[pos]; struct qentry item = heap->items[pos];
@ -118,13 +118,13 @@ STATIC void heap_siftup(mp_obj_utimeq_t *heap, mp_uint_t pos) {
pos = child_pos; pos = child_pos;
} }
heap->items[pos] = item; heap->items[pos] = item;
heap_siftdown(heap, start_pos, pos); utimeq_heap_siftdown(heap, start_pos, pos);
} }
STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
(void)n_args; (void)n_args;
mp_obj_t heap_in = args[0]; mp_obj_t heap_in = args[0];
mp_obj_utimeq_t *heap = get_heap(heap_in); mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
if (heap->len == heap->alloc) { if (heap->len == heap->alloc) {
mp_raise_msg(&mp_type_IndexError, "queue overflow"); mp_raise_msg(&mp_type_IndexError, "queue overflow");
} }
@ -133,14 +133,14 @@ STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
heap->items[l].id = utimeq_id++; heap->items[l].id = utimeq_id++;
heap->items[l].callback = args[2]; heap->items[l].callback = args[2];
heap->items[l].args = args[3]; heap->items[l].args = args[3];
heap_siftdown(heap, 0, heap->len); utimeq_heap_siftdown(heap, 0, heap->len);
heap->len++; heap->len++;
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_utimeq_heappush); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_utimeq_heappush);
STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) { STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
mp_obj_utimeq_t *heap = get_heap(heap_in); mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
if (heap->len == 0) { if (heap->len == 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap")); nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap"));
} }
@ -158,14 +158,14 @@ STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
heap->items[heap->len].callback = MP_OBJ_NULL; // so we don't retain a pointer heap->items[heap->len].callback = MP_OBJ_NULL; // so we don't retain a pointer
heap->items[heap->len].args = MP_OBJ_NULL; heap->items[heap->len].args = MP_OBJ_NULL;
if (heap->len) { if (heap->len) {
heap_siftup(heap, 0); utimeq_heap_siftup(heap, 0);
} }
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_heappop_obj, mod_utimeq_heappop); STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_heappop_obj, mod_utimeq_heappop);
STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) { STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) {
mp_obj_utimeq_t *heap = get_heap(heap_in); mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
if (heap->len == 0) { if (heap->len == 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap")); nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap"));
} }
@ -177,7 +177,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_utimeq_peektime_obj, mod_utimeq_peektime);
#if DEBUG #if DEBUG
STATIC mp_obj_t mod_utimeq_dump(mp_obj_t heap_in) { STATIC mp_obj_t mod_utimeq_dump(mp_obj_t heap_in) {
mp_obj_utimeq_t *heap = get_heap(heap_in); mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
for (int i = 0; i < heap->len; i++) { for (int i = 0; i < heap->len; i++) {
printf(UINT_FMT "\t%p\t%p\n", heap->items[i].time, printf(UINT_FMT "\t%p\t%p\n", heap->items[i].time,
MP_OBJ_TO_PTR(heap->items[i].callback), MP_OBJ_TO_PTR(heap->items[i].args)); MP_OBJ_TO_PTR(heap->items[i].callback), MP_OBJ_TO_PTR(heap->items[i].args));

View File

@ -219,7 +219,7 @@ STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size
// TODO gc hook to close the file if not already closed // TODO gc hook to close the file if not already closed
STATIC const mp_rom_map_elem_t rawfile_locals_dict_table[] = { STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
@ -234,10 +234,10 @@ STATIC const mp_rom_map_elem_t rawfile_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&file_obj___exit___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&file_obj___exit___obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(vfs_fat_rawfile_locals_dict, vfs_fat_rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO #if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = { STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = {
.read = file_obj_read, .read = file_obj_read,
.write = file_obj_write, .write = file_obj_write,
.ioctl = file_obj_ioctl, .ioctl = file_obj_ioctl,
@ -250,12 +250,12 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = {
.make_new = file_obj_make_new, .make_new = file_obj_make_new,
.getiter = mp_identity_getiter, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &fileio_stream_p, .protocol = &vfs_fat_fileio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict, .locals_dict = (mp_obj_dict_t*)&vfs_fat_rawfile_locals_dict,
}; };
#endif #endif
STATIC const mp_stream_p_t textio_stream_p = { STATIC const mp_stream_p_t vfs_fat_textio_stream_p = {
.read = file_obj_read, .read = file_obj_read,
.write = file_obj_write, .write = file_obj_write,
.ioctl = file_obj_ioctl, .ioctl = file_obj_ioctl,
@ -269,8 +269,8 @@ const mp_obj_type_t mp_type_vfs_fat_textio = {
.make_new = file_obj_make_new, .make_new = file_obj_make_new,
.getiter = mp_identity_getiter, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &textio_stream_p, .protocol = &vfs_fat_textio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict, .locals_dict = (mp_obj_dict_t*)&vfs_fat_rawfile_locals_dict,
}; };
// Factory function for I/O stream classes // Factory function for I/O stream classes

View File

@ -200,7 +200,7 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
} }
} }
STATIC const mp_rom_map_elem_t rawfile_locals_dict_table[] = { STATIC const mp_rom_map_elem_t vfs_posix_rawfile_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_fileno), MP_ROM_PTR(&vfs_posix_file_fileno_obj) }, { MP_ROM_QSTR(MP_QSTR_fileno), MP_ROM_PTR(&vfs_posix_file_fileno_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
@ -215,10 +215,10 @@ STATIC const mp_rom_map_elem_t rawfile_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&vfs_posix_file___exit___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&vfs_posix_file___exit___obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(vfs_posix_rawfile_locals_dict, vfs_posix_rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO #if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = { STATIC const mp_stream_p_t vfs_posix_fileio_stream_p = {
.read = vfs_posix_file_read, .read = vfs_posix_file_read,
.write = vfs_posix_file_write, .write = vfs_posix_file_write,
.ioctl = vfs_posix_file_ioctl, .ioctl = vfs_posix_file_ioctl,
@ -231,12 +231,12 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = {
.make_new = vfs_posix_file_make_new, .make_new = vfs_posix_file_make_new,
.getiter = mp_identity_getiter, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &fileio_stream_p, .protocol = &vfs_posix_fileio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict, .locals_dict = (mp_obj_dict_t*)&vfs_posix_rawfile_locals_dict,
}; };
#endif #endif
STATIC const mp_stream_p_t textio_stream_p = { STATIC const mp_stream_p_t vfs_posix_textio_stream_p = {
.read = vfs_posix_file_read, .read = vfs_posix_file_read,
.write = vfs_posix_file_write, .write = vfs_posix_file_write,
.ioctl = vfs_posix_file_ioctl, .ioctl = vfs_posix_file_ioctl,
@ -250,8 +250,8 @@ const mp_obj_type_t mp_type_vfs_posix_textio = {
.make_new = vfs_posix_file_make_new, .make_new = vfs_posix_file_make_new,
.getiter = mp_identity_getiter, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &textio_stream_p, .protocol = &vfs_posix_textio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict, .locals_dict = (mp_obj_dict_t*)&vfs_posix_rawfile_locals_dict,
}; };
const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_textio}, STDIN_FILENO}; const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_textio}, STDIN_FILENO};

@ -1 +1 @@
Subproject commit a717b4456b3771ed8a3e1e9aa4802a43e501c003 Subproject commit a29af27883dacb96e0b7bf1b75573a1d26026696

View File

@ -101,7 +101,7 @@ void upytest_execute_test(const char *src) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
} else { } else {

View File

@ -89,7 +89,7 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
// source is a lexer, parse and compile the script // source is a lexer, parse and compile the script
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL); module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL);
#else #else
mp_raise_msg(&mp_type_RuntimeError, "script compilation not supported"); mp_raise_msg(&mp_type_RuntimeError, "script compilation not supported");
#endif #endif

View File

@ -72,7 +72,7 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
#endif #endif
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_raw_code_t *rc = mp_compile_to_raw_code(&parse_tree, source_name, emit_opt, false); mp_raw_code_t *rc = mp_compile_to_raw_code(&parse_tree, source_name, false);
vstr_t vstr; vstr_t vstr;
vstr_init(&vstr, 16); vstr_init(&vstr, 16);
@ -115,7 +115,11 @@ STATIC int usage(char **argv) {
); );
int impl_opts_cnt = 0; int impl_opts_cnt = 0;
printf( printf(
#if MICROPY_EMIT_NATIVE
" emit={bytecode,native,viper} -- set the default code emitter\n" " emit={bytecode,native,viper} -- set the default code emitter\n"
#else
" emit=bytecode -- set the default code emitter\n"
#endif
); );
impl_opts_cnt++; impl_opts_cnt++;
printf( printf(
@ -140,10 +144,12 @@ STATIC void pre_process_options(int argc, char **argv) {
} }
if (strcmp(argv[a + 1], "emit=bytecode") == 0) { if (strcmp(argv[a + 1], "emit=bytecode") == 0) {
emit_opt = MP_EMIT_OPT_BYTECODE; emit_opt = MP_EMIT_OPT_BYTECODE;
#if MICROPY_EMIT_NATIVE
} else if (strcmp(argv[a + 1], "emit=native") == 0) { } else if (strcmp(argv[a + 1], "emit=native") == 0) {
emit_opt = MP_EMIT_OPT_NATIVE_PYTHON; emit_opt = MP_EMIT_OPT_NATIVE_PYTHON;
} else if (strcmp(argv[a + 1], "emit=viper") == 0) { } else if (strcmp(argv[a + 1], "emit=viper") == 0) {
emit_opt = MP_EMIT_OPT_VIPER; emit_opt = MP_EMIT_OPT_VIPER;
#endif
} else if (strncmp(argv[a + 1], "heapsize=", sizeof("heapsize=") - 1) == 0) { } else if (strncmp(argv[a + 1], "heapsize=", sizeof("heapsize=") - 1) == 0) {
char *end; char *end;
heap_size = strtol(argv[a + 1] + sizeof("heapsize=") - 1, &end, 0); heap_size = strtol(argv[a + 1] + sizeof("heapsize=") - 1, &end, 0);
@ -190,6 +196,13 @@ MP_NOINLINE int main_(int argc, char **argv) {
mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_path, 0);
mp_obj_list_init(mp_sys_argv, 0); mp_obj_list_init(mp_sys_argv, 0);
#if MICROPY_EMIT_NATIVE
// Set default emitter options
MP_STATE_VM(default_emit_opt) = emit_opt;
#else
(void)emit_opt;
#endif
// set default compiler configuration // set default compiler configuration
mp_dynamic_compiler.small_int_bits = 31; mp_dynamic_compiler.small_int_bits = 31;
mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0; mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0;

View File

@ -13,7 +13,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
} else { } else {

View File

@ -1,7 +1,31 @@
# Select the board to build for: if not given on the command line,
# then default to GENERIC.
BOARD ?= GENERIC
# If the build directory is not given, make it reflect the board name.
BUILD ?= build-$(BOARD)
BOARD_DIR ?= boards/$(BOARD)
ifeq ($(wildcard $(BOARD_DIR)/.),)
$(error Invalid BOARD specified: $(BOARD_DIR))
endif
include ../../py/mkenv.mk include ../../py/mkenv.mk
# Optional (not currently used for ESP32)
-include mpconfigport.mk
ifneq ($(SDKCONFIG),)
$(error Use the BOARD variable instead of SDKCONFIG)
endif
# Expected to set SDKCONFIG
include $(BOARD_DIR)/mpconfigboard.mk
# qstr definitions (must come before including py.mk) # qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h QSTR_DEFS = qstrdefsport.h
QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h
QSTR_GLOBAL_REQUIREMENTS = $(SDKCONFIG_H)
MICROPY_PY_USSL = 0 MICROPY_PY_USSL = 0
MICROPY_SSL_AXTLS = 0 MICROPY_SSL_AXTLS = 0
@ -23,12 +47,11 @@ FLASH_SIZE ?= 4MB
CROSS_COMPILE ?= xtensa-esp32-elf- CROSS_COMPILE ?= xtensa-esp32-elf-
OBJDUMP = $(CROSS_COMPILE)objdump OBJDUMP = $(CROSS_COMPILE)objdump
# SDKCONFIG should be overridden to get a different configuration SDKCONFIG_COMBINED = $(BUILD)/sdkconfig.combined
SDKCONFIG ?= boards/sdkconfig
SDKCONFIG_H = $(BUILD)/sdkconfig.h SDKCONFIG_H = $(BUILD)/sdkconfig.h
# the git hash of the currently supported ESP IDF version # the git hash of the currently supported ESP IDF version
ESPIDF_SUPHASH := 6b3da6b1882f3b72e904cc90be67e9c4e3f369a9 ESPIDF_SUPHASH := 6ccb4cf5b7d1fdddb8c2492f9cbc926abaf230df
# paths to ESP IDF and its components # paths to ESP IDF and its components
ifeq ($(ESPIDF),) ifeq ($(ESPIDF),)
@ -75,6 +98,7 @@ INC += -I$(BUILD)
INC_ESPCOMP += -I$(ESPCOMP)/bootloader_support/include INC_ESPCOMP += -I$(ESPCOMP)/bootloader_support/include
INC_ESPCOMP += -I$(ESPCOMP)/bootloader_support/include_bootloader INC_ESPCOMP += -I$(ESPCOMP)/bootloader_support/include_bootloader
INC_ESPCOMP += -I$(ESPCOMP)/console
INC_ESPCOMP += -I$(ESPCOMP)/driver/include INC_ESPCOMP += -I$(ESPCOMP)/driver/include
INC_ESPCOMP += -I$(ESPCOMP)/driver/include/driver INC_ESPCOMP += -I$(ESPCOMP)/driver/include/driver
INC_ESPCOMP += -I$(ESPCOMP)/nghttp/port/include INC_ESPCOMP += -I$(ESPCOMP)/nghttp/port/include
@ -104,6 +128,9 @@ INC_ESPCOMP += -I$(ESPCOMP)/lwip/port/esp32/include
INC_ESPCOMP += -I$(ESPCOMP)/lwip/include/apps INC_ESPCOMP += -I$(ESPCOMP)/lwip/include/apps
INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/mbedtls/include INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/mbedtls/include
INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/port/include INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/port/include
INC_ESPCOMP += -I$(ESPCOMP)/mdns/include
INC_ESPCOMP += -I$(ESPCOMP)/mdns/private_include
INC_ESPCOMP += -I$(ESPCOMP)/micro-ecc/micro-ecc
INC_ESPCOMP += -I$(ESPCOMP)/spi_flash/include INC_ESPCOMP += -I$(ESPCOMP)/spi_flash/include
INC_ESPCOMP += -I$(ESPCOMP)/ulp/include INC_ESPCOMP += -I$(ESPCOMP)/ulp/include
INC_ESPCOMP += -I$(ESPCOMP)/vfs/include INC_ESPCOMP += -I$(ESPCOMP)/vfs/include
@ -128,6 +155,7 @@ CFLAGS_BASE = -std=gnu99 $(CFLAGS_COMMON) -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_co
CFLAGS = $(CFLAGS_BASE) $(INC) $(INC_ESPCOMP) CFLAGS = $(CFLAGS_BASE) $(INC) $(INC_ESPCOMP)
CFLAGS += -DIDF_VER=\"$(IDF_VER)\" CFLAGS += -DIDF_VER=\"$(IDF_VER)\"
CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA) CFLAGS += $(CFLAGS_MOD) $(CFLAGS_EXTRA)
CFLAGS += -I$(BOARD_DIR)
# this is what ESPIDF uses for c++ compilation # this is what ESPIDF uses for c++ compilation
CXXFLAGS = -std=gnu++11 $(CFLAGS_COMMON) $(INC) $(INC_ESPCOMP) CXXFLAGS = -std=gnu++11 $(CFLAGS_COMMON) $(INC) $(INC_ESPCOMP)
@ -191,6 +219,7 @@ SRC_C = \
network_ppp.c \ network_ppp.c \
modsocket.c \ modsocket.c \
modesp.c \ modesp.c \
esp32_partition.c \
esp32_ulp.c \ esp32_ulp.c \
modesp32.c \ modesp32.c \
espneopixel.c \ espneopixel.c \
@ -199,6 +228,7 @@ SRC_C = \
mpthreadport.c \ mpthreadport.c \
machine_rtc.c \ machine_rtc.c \
machine_sdcard.c \ machine_sdcard.c \
$(wildcard $(BOARD_DIR)/*.c) \
$(SRC_MOD) $(SRC_MOD)
EXTMOD_SRC_C = $(addprefix extmod/,\ EXTMOD_SRC_C = $(addprefix extmod/,\
@ -266,7 +296,11 @@ SRC_QSTR_AUTO_DEPS +=
################################################################################ ################################################################################
# Generate sdkconfig.h from sdkconfig # Generate sdkconfig.h from sdkconfig
$(SDKCONFIG_H): $(SDKCONFIG) $(SDKCONFIG_COMBINED): $(SDKCONFIG)
$(Q)$(MKDIR) -p $(dir $@)
$(Q)$(CAT) $^ > $@
$(SDKCONFIG_H): $(SDKCONFIG_COMBINED)
$(ECHO) "GEN $@" $(ECHO) "GEN $@"
$(Q)$(MKDIR) -p $(dir $@) $(Q)$(MKDIR) -p $(dir $@)
$(Q)$(PYTHON) $(ESPIDF)/tools/kconfig_new/confgen.py \ $(Q)$(PYTHON) $(ESPIDF)/tools/kconfig_new/confgen.py \
@ -279,11 +313,15 @@ $(SDKCONFIG_H): $(SDKCONFIG)
--env "COMPONENT_KCONFIGS_PROJBUILD=$(ESPCOMP_KCONFIGS_PROJBUILD)" --env "COMPONENT_KCONFIGS_PROJBUILD=$(ESPCOMP_KCONFIGS_PROJBUILD)"
$(Q)touch $@ $(Q)touch $@
$(HEADER_BUILD)/qstrdefs.generated.h: $(SDKCONFIG_H) $(HEADER_BUILD)/qstrdefs.generated.h: $(SDKCONFIG_H) $(BOARD_DIR)/mpconfigboard.h
################################################################################ ################################################################################
# List of object files from the ESP32 IDF components # List of object files from the ESP32 IDF components
ESPIDF_BOOTLOADER_SUPPORT_O = $(patsubst %.c,%.o,\
$(filter-out $(ESPCOMP)/bootloader_support/src/bootloader_init.c,\
$(wildcard $(ESPCOMP)/bootloader_support/src/*.c)))
ESPIDF_DRIVER_O = $(patsubst %.c,%.o,$(wildcard $(ESPCOMP)/driver/*.c)) ESPIDF_DRIVER_O = $(patsubst %.c,%.o,$(wildcard $(ESPCOMP)/driver/*.c))
ESPIDF_EFUSE_O = $(patsubst %.c,%.o,\ ESPIDF_EFUSE_O = $(patsubst %.c,%.o,\
@ -373,6 +411,8 @@ ESPIDF_MBEDTLS_O = $(patsubst %.c,%.o,\
$(wildcard $(ESPCOMP)/mbedtls/port/*.c) \ $(wildcard $(ESPCOMP)/mbedtls/port/*.c) \
) )
ESPIDF_MDNS_O = $(patsubst %.c,%.o,$(wildcard $(ESPCOMP)/mdns/*.c))
$(BUILD)/$(ESPCOMP)/wpa_supplicant/%.o: CFLAGS += -DEMBEDDED_SUPP -DIEEE8021X_EAPOL -DEAP_PEER_METHOD -DEAP_MSCHAPv2 -DEAP_TTLS -DEAP_TLS -DEAP_PEAP -DUSE_WPA2_TASK -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -DESPRESSIF_USE -DESP32_WORKAROUND -DALLOW_EVEN_MOD -D__ets__ -Wno-strict-aliasing $(BUILD)/$(ESPCOMP)/wpa_supplicant/%.o: CFLAGS += -DEMBEDDED_SUPP -DIEEE8021X_EAPOL -DEAP_PEER_METHOD -DEAP_MSCHAPv2 -DEAP_TTLS -DEAP_TLS -DEAP_PEAP -DUSE_WPA2_TASK -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -DESPRESSIF_USE -DESP32_WORKAROUND -DALLOW_EVEN_MOD -D__ets__ -Wno-strict-aliasing
ESPIDF_WPA_SUPPLICANT_O = $(patsubst %.c,%.o,\ ESPIDF_WPA_SUPPLICANT_O = $(patsubst %.c,%.o,\
$(wildcard $(ESPCOMP)/wpa_supplicant/port/*.c) \ $(wildcard $(ESPCOMP)/wpa_supplicant/port/*.c) \
@ -393,6 +433,7 @@ $(BUILD_ESPIDF_LIB)/$(1)/lib$(1).a: $(addprefix $$(BUILD)/,$(2))
$(Q)$(AR) cru $$@ $$^ $(Q)$(AR) cru $$@ $$^
endef endef
$(eval $(call gen_espidf_lib_rule,bootloader_support,$(ESPIDF_BOOTLOADER_SUPPORT_O)))
$(eval $(call gen_espidf_lib_rule,driver,$(ESPIDF_DRIVER_O))) $(eval $(call gen_espidf_lib_rule,driver,$(ESPIDF_DRIVER_O)))
$(eval $(call gen_espidf_lib_rule,efuse,$(ESPIDF_EFUSE_O))) $(eval $(call gen_espidf_lib_rule,efuse,$(ESPIDF_EFUSE_O)))
$(eval $(call gen_espidf_lib_rule,esp32,$(ESPIDF_ESP32_O))) $(eval $(call gen_espidf_lib_rule,esp32,$(ESPIDF_ESP32_O)))
@ -417,6 +458,7 @@ $(eval $(call gen_espidf_lib_rule,spi_flash,$(ESPIDF_SPI_FLASH_O)))
$(eval $(call gen_espidf_lib_rule,ulp,$(ESPIDF_ULP_O))) $(eval $(call gen_espidf_lib_rule,ulp,$(ESPIDF_ULP_O)))
$(eval $(call gen_espidf_lib_rule,lwip,$(ESPIDF_LWIP_O))) $(eval $(call gen_espidf_lib_rule,lwip,$(ESPIDF_LWIP_O)))
$(eval $(call gen_espidf_lib_rule,mbedtls,$(ESPIDF_MBEDTLS_O))) $(eval $(call gen_espidf_lib_rule,mbedtls,$(ESPIDF_MBEDTLS_O)))
$(eval $(call gen_espidf_lib_rule,mdns,$(ESPIDF_MDNS_O)))
$(eval $(call gen_espidf_lib_rule,wpa_supplicant,$(ESPIDF_WPA_SUPPLICANT_O))) $(eval $(call gen_espidf_lib_rule,wpa_supplicant,$(ESPIDF_WPA_SUPPLICANT_O)))
$(eval $(call gen_espidf_lib_rule,sdmmc,$(ESPIDF_SDMMC_O))) $(eval $(call gen_espidf_lib_rule,sdmmc,$(ESPIDF_SDMMC_O)))
@ -450,12 +492,12 @@ $(eval $(foreach lib,$(LIB_ESPIDF),$(eval $(call gen_sections_info_rule,$(BUILD_
$(LDGEN_SECTION_INFOS): $(LDGEN_SECTIONS_INFO) $(ESPIDF)/make/ldgen.mk $(LDGEN_SECTION_INFOS): $(LDGEN_SECTIONS_INFO) $(ESPIDF)/make/ldgen.mk
$(Q)printf "$(foreach info,$(LDGEN_SECTIONS_INFO),$(info)\n)" > $@ $(Q)printf "$(foreach info,$(LDGEN_SECTIONS_INFO),$(info)\n)" > $@
$(BUILD)/esp32.project.ld: $(ESPCOMP)/esp32/ld/esp32.project.ld.in $(LDGEN_FRAGMENTS) $(SDKCONFIG) $(LDGEN_SECTION_INFOS) $(BUILD)/esp32.project.ld: $(ESPCOMP)/esp32/ld/esp32.project.ld.in $(LDGEN_FRAGMENTS) $(SDKCONFIG_COMBINED) $(LDGEN_SECTION_INFOS)
$(ECHO) "GEN $@" $(ECHO) "GEN $@"
$(Q)$(PYTHON) $(ESPIDF)/tools/ldgen/ldgen.py \ $(Q)$(PYTHON) $(ESPIDF)/tools/ldgen/ldgen.py \
--input $< \ --input $< \
--output $@ \ --output $@ \
--config $(SDKCONFIG) \ --config $(SDKCONFIG_COMBINED) \
--kconfig $(ESPIDF)/Kconfig \ --kconfig $(ESPIDF)/Kconfig \
--fragments $(LDGEN_FRAGMENTS) \ --fragments $(LDGEN_FRAGMENTS) \
--sections $(LDGEN_SECTION_INFOS) \ --sections $(LDGEN_SECTION_INFOS) \
@ -493,6 +535,7 @@ OBJ = $(OBJ_MP)
APP_LD_ARGS = APP_LD_ARGS =
APP_LD_ARGS += $(LDFLAGS_MOD) APP_LD_ARGS += $(LDFLAGS_MOD)
APP_LD_ARGS += $(addprefix -T,$(LD_FILES))
APP_LD_ARGS += --start-group APP_LD_ARGS += --start-group
APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc
APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++ APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++
@ -674,7 +717,9 @@ $(BUILD)/bootloader.elf: $(BOOTLOADER_OBJ) $(addprefix $(BOOTLOADER_LIB_DIR)/lib
# Declarations to build the partitions # Declarations to build the partitions
PYTHON2 ?= python2 PYTHON2 ?= python2
PART_SRC = partitions.csv
# Can be overriden by mkconfigboard.mk.
PART_SRC ?= partitions.csv
$(BUILD)/partitions.bin: $(PART_SRC) $(BUILD)/partitions.bin: $(PART_SRC)
$(ECHO) "Create $@" $(ECHO) "Create $@"

View File

@ -74,11 +74,11 @@ variables for the build. In that case, create a new file in the esp32
directory called `makefile` and add the following lines to that file: directory called `makefile` and add the following lines to that file:
``` ```
ESPIDF = <path to root of esp-idf repository> ESPIDF = <path to root of esp-idf repository>
BOARD = GENERIC
#PORT = /dev/ttyUSB0 #PORT = /dev/ttyUSB0
#FLASH_MODE = qio #FLASH_MODE = qio
#FLASH_SIZE = 4MB #FLASH_SIZE = 4MB
#CROSS_COMPILE = xtensa-esp32-elf- #CROSS_COMPILE = xtensa-esp32-elf-
#SDKCONFIG = boards/sdkconfig.spiram
include Makefile include Makefile
``` ```
@ -92,16 +92,18 @@ are `PORT` for the serial port of your esp32 module, and `FLASH_MODE`
(which may need to be `dio` for some modules) (which may need to be `dio` for some modules)
and `FLASH_SIZE`. See the Makefile for further information. and `FLASH_SIZE`. See the Makefile for further information.
The default ESP IDF configuration settings are provided in the file The default ESP IDF configuration settings are provided by the `GENERIC`
`boards/sdkconfig`, and this file is specified in the build by the make board definition in the directory `boards/GENERIC`. For a custom configuration
variable `SDKCONFIG`. To use a custom configuration either set `SDKCONFIG` you can define your own board directory.
in your custom `makefile` (or `GNUmakefile`) or set this variable on the
command line: The `BOARD` variable can be set on the make command line:
```bash ```bash
$ make SDKCONFIG=sdkconfig.myboard $ make BOARD=TINYPICO
``` ```
The file `boards/sdkconfig.spiram` is provided for ESP32 modules that have or added to your custom `makefile` (or `GNUmakefile`) described above. There
external SPIRAM. is also a `GENERIC_SPIRAM` board for for ESP32 modules that have external
SPIRAM, but prefer to use a specific board target (or define your own as
necessary).
Building the firmware Building the firmware
--------------------- ---------------------

View File

@ -0,0 +1,2 @@
#define MICROPY_HW_BOARD_NAME "ESP32 module"
#define MICROPY_HW_MCU_NAME "ESP32"

View File

@ -0,0 +1 @@
SDKCONFIG += boards/sdkconfig.base

View File

@ -0,0 +1,2 @@
#define MICROPY_HW_BOARD_NAME "Generic ESP32-D2WD module"
#define MICROPY_HW_MCU_NAME "ESP32-D2WD"

View File

@ -0,0 +1,5 @@
SDKCONFIG += boards/sdkconfig.base
PART_SRC = partitions-2MiB.csv
FLASH_SIZE = 2MB
FLASH_MODE = dio
FLASH_FREQ = 40m

View File

@ -0,0 +1,2 @@
#define MICROPY_HW_BOARD_NAME "ESP32 module (spiram)"
#define MICROPY_HW_MCU_NAME "ESP32"

View File

@ -0,0 +1,2 @@
SDKCONFIG += boards/sdkconfig.base
SDKCONFIG += boards/sdkconfig.spiram

View File

@ -0,0 +1,2 @@
#define MICROPY_HW_BOARD_NAME "TinyPICO"
#define MICROPY_HW_MCU_NAME "ESP32-PICO-D4"

View File

@ -0,0 +1,5 @@
FLASH_FREQ = 80m
SDKCONFIG += boards/sdkconfig.base
SDKCONFIG += boards/sdkconfig.spiram
SDKCONFIG += boards/TINYPICO/sdkconfig.board

View File

@ -0,0 +1,3 @@
CONFIG_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_SPIRAM_SPEED_80M=y

View File

@ -1,34 +1,5 @@
# MicroPython on ESP32, ESP IDF configuration with SPIRAM support # MicroPython on ESP32, ESP IDF configuration with SPIRAM support
# The following options override the defaults
CONFIG_IDF_TARGET="esp32"
# Application manager
CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y
CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y
# Bootloader config
CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y
# ESP32-specific
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
CONFIG_SPIRAM_SUPPORT=y CONFIG_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_IGNORE_NOTFOUND=y CONFIG_SPIRAM_IGNORE_NOTFOUND=y
CONFIG_SPIRAM_USE_MEMMAP=y CONFIG_SPIRAM_USE_MEMMAP=y
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=n
CONFIG_ESP32_XTAL_FREQ_AUTO=y
CONFIG_FREERTOS_INTERRUPT_BACKTRACE=n
# Power Management
CONFIG_PM_ENABLE=y
# FreeRTOS
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
CONFIG_SUPPORT_STATIC_ALLOCATION=y
CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK=y
# UDP
CONFIG_PPP_SUPPORT=y
CONFIG_PPP_PAP_SUPPORT=y
CONFIG_PPP_CHAP_SUPPORT=y

View File

@ -0,0 +1,223 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "py/runtime.h"
#include "py/mperrno.h"
#include "extmod/vfs.h"
#include "modesp32.h"
#include "esp_ota_ops.h"
// esp_partition_read and esp_partition_write can operate on arbitrary bytes
// but esp_partition_erase_range operates on 4k blocks. But to make a partition
// implement the standard block protocol all operations are done on 4k blocks.
#define BLOCK_SIZE_BYTES (4096)
enum {
ESP32_PARTITION_BOOT,
ESP32_PARTITION_RUNNING,
};
typedef struct _esp32_partition_obj_t {
mp_obj_base_t base;
const esp_partition_t *part;
} esp32_partition_obj_t;
static inline void check_esp_err(esp_err_t e) {
if (e != ESP_OK) {
mp_raise_OSError(-e);
}
}
STATIC esp32_partition_obj_t *esp32_partition_new(const esp_partition_t *part) {
if (part == NULL) {
mp_raise_OSError(MP_ENOENT);
}
esp32_partition_obj_t *self = m_new_obj(esp32_partition_obj_t);
self->base.type = &esp32_partition_type;
self->part = part;
return self;
}
STATIC void esp32_partition_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "<Partition type=%u, subtype=%u, address=%u, size=%u, label=%s, encrypted=%u>",
self->part->type, self->part->subtype,
self->part->address, self->part->size,
&self->part->label[0], self->part->encrypted
);
}
STATIC mp_obj_t esp32_partition_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
// Check args
mp_arg_check_num(n_args, n_kw, 1, 1, false);
// Get requested partition
const esp_partition_t *part;
if (mp_obj_is_int(all_args[0])) {
// Integer given, get that particular partition
switch (mp_obj_get_int(all_args[0])) {
case ESP32_PARTITION_BOOT:
part = esp_ota_get_boot_partition();
break;
case ESP32_PARTITION_RUNNING:
part = esp_ota_get_running_partition();
break;
default:
mp_raise_ValueError(NULL);
}
} else {
// String given, search for partition with that label
const char *label = mp_obj_str_get_str(all_args[0]);
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, label);
if (part == NULL) {
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, label);
}
}
// Return new object
return MP_OBJ_FROM_PTR(esp32_partition_new(part));
}
STATIC mp_obj_t esp32_partition_find(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
// Parse args
enum { ARG_type, ARG_subtype, ARG_label };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_type, MP_ARG_INT, {.u_int = ESP_PARTITION_TYPE_APP} },
{ MP_QSTR_subtype, MP_ARG_INT, {.u_int = ESP_PARTITION_SUBTYPE_ANY} },
{ MP_QSTR_label, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
// Get optional label string
const char *label = NULL;
if (args[ARG_label].u_obj != mp_const_none) {
label = mp_obj_str_get_str(args[ARG_label].u_obj);
}
// Build list of matching partitions
mp_obj_t list = mp_obj_new_list(0, NULL);
esp_partition_iterator_t iter = esp_partition_find(args[ARG_type].u_int, args[ARG_subtype].u_int, label);
while (iter != NULL) {
mp_obj_list_append(list, MP_OBJ_FROM_PTR(esp32_partition_new(esp_partition_get(iter))));
iter = esp_partition_next(iter);
}
esp_partition_iterator_release(iter);
return list;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_partition_find_fun_obj, 0, esp32_partition_find);
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(esp32_partition_find_obj, MP_ROM_PTR(&esp32_partition_find_fun_obj));
STATIC mp_obj_t esp32_partition_info(mp_obj_t self_in) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_t tuple[] = {
MP_OBJ_NEW_SMALL_INT(self->part->type),
MP_OBJ_NEW_SMALL_INT(self->part->subtype),
mp_obj_new_int_from_uint(self->part->address),
mp_obj_new_int_from_uint(self->part->size),
mp_obj_new_str(&self->part->label[0], strlen(&self->part->label[0])),
mp_obj_new_bool(self->part->encrypted),
};
return mp_obj_new_tuple(6, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_partition_info_obj, esp32_partition_info);
STATIC mp_obj_t esp32_partition_readblocks(mp_obj_t self_in, mp_obj_t block_num, mp_obj_t buf_in) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t offset = mp_obj_get_int(block_num) * BLOCK_SIZE_BYTES;
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
check_esp_err(esp_partition_read(self->part, offset, bufinfo.buf, bufinfo.len));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp32_partition_readblocks_obj, esp32_partition_readblocks);
STATIC mp_obj_t esp32_partition_writeblocks(mp_obj_t self_in, mp_obj_t block_num, mp_obj_t buf_in) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t offset = mp_obj_get_int(block_num) * BLOCK_SIZE_BYTES;
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
check_esp_err(esp_partition_erase_range(self->part, offset, bufinfo.len));
check_esp_err(esp_partition_write(self->part, offset, bufinfo.buf, bufinfo.len));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp32_partition_writeblocks_obj, esp32_partition_writeblocks);
STATIC mp_obj_t esp32_partition_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_int_t cmd = mp_obj_get_int(cmd_in);
switch (cmd) {
case BP_IOCTL_INIT: return MP_OBJ_NEW_SMALL_INT(0);
case BP_IOCTL_DEINIT: return MP_OBJ_NEW_SMALL_INT(0);
case BP_IOCTL_SYNC: return MP_OBJ_NEW_SMALL_INT(0);
case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(self->part->size / BLOCK_SIZE_BYTES);
case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(BLOCK_SIZE_BYTES);
default: return mp_const_none;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp32_partition_ioctl_obj, esp32_partition_ioctl);
STATIC mp_obj_t esp32_partition_set_boot(mp_obj_t self_in) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
esp_ota_set_boot_partition(self->part);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_partition_set_boot_obj, esp32_partition_set_boot);
STATIC mp_obj_t esp32_partition_get_next_update(mp_obj_t self_in) {
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_FROM_PTR(esp32_partition_new(esp_ota_get_next_update_partition(self->part)));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_partition_get_next_update_obj, esp32_partition_get_next_update);
STATIC const mp_rom_map_elem_t esp32_partition_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_find), MP_ROM_PTR(&esp32_partition_find_obj) },
{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&esp32_partition_info_obj) },
{ MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&esp32_partition_readblocks_obj) },
{ MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&esp32_partition_writeblocks_obj) },
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&esp32_partition_ioctl_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_boot), MP_ROM_PTR(&esp32_partition_set_boot_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_next_update), MP_ROM_PTR(&esp32_partition_get_next_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_INT(ESP32_PARTITION_BOOT) },
{ MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(ESP32_PARTITION_RUNNING) },
{ MP_ROM_QSTR(MP_QSTR_TYPE_APP), MP_ROM_INT(ESP_PARTITION_TYPE_APP) },
{ MP_ROM_QSTR(MP_QSTR_TYPE_DATA), MP_ROM_INT(ESP_PARTITION_TYPE_DATA) },
};
STATIC MP_DEFINE_CONST_DICT(esp32_partition_locals_dict, esp32_partition_locals_dict_table);
const mp_obj_type_t esp32_partition_type = {
{ &mp_type_type },
.name = MP_QSTR_Partition,
.print = esp32_partition_print,
.make_new = esp32_partition_make_new,
.locals_dict = (mp_obj_dict_t*)&esp32_partition_locals_dict,
};

View File

@ -53,12 +53,15 @@ STATIC const madc_obj_t madc_obj[] = {
{{&machine_adc_type}, GPIO_NUM_35, ADC1_CHANNEL_7}, {{&machine_adc_type}, GPIO_NUM_35, ADC1_CHANNEL_7},
}; };
STATIC uint8_t adc_bit_width;
STATIC mp_obj_t madc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, STATIC mp_obj_t madc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
const mp_obj_t *args) { const mp_obj_t *args) {
static int initialized = 0; static int initialized = 0;
if (!initialized) { if (!initialized) {
adc1_config_width(ADC_WIDTH_12Bit); adc1_config_width(ADC_WIDTH_12Bit);
adc_bit_width = 12;
initialized = 1; initialized = 1;
} }
@ -79,6 +82,17 @@ STATIC void madc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
mp_printf(print, "ADC(Pin(%u))", self->gpio_id); mp_printf(print, "ADC(Pin(%u))", self->gpio_id);
} }
// read_u16()
STATIC mp_obj_t madc_read_u16(mp_obj_t self_in) {
madc_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t raw = adc1_get_raw(self->adc1_id);
// Scale raw reading to 16 bit value using a Taylor expansion (for 8 <= bits <= 16)
uint32_t u16 = raw << (16 - adc_bit_width) | raw >> (2 * adc_bit_width - 16);
return MP_OBJ_NEW_SMALL_INT(u16);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(madc_read_u16_obj, madc_read_u16);
// Legacy method
STATIC mp_obj_t madc_read(mp_obj_t self_in) { STATIC mp_obj_t madc_read(mp_obj_t self_in) {
madc_obj_t *self = self_in; madc_obj_t *self = self_in;
int val = adc1_get_raw(self->adc1_id); int val = adc1_get_raw(self->adc1_id);
@ -99,13 +113,24 @@ MP_DEFINE_CONST_FUN_OBJ_2(madc_atten_obj, madc_atten);
STATIC mp_obj_t madc_width(mp_obj_t cls_in, mp_obj_t width_in) { STATIC mp_obj_t madc_width(mp_obj_t cls_in, mp_obj_t width_in) {
adc_bits_width_t width = mp_obj_get_int(width_in); adc_bits_width_t width = mp_obj_get_int(width_in);
esp_err_t err = adc1_config_width(width); esp_err_t err = adc1_config_width(width);
if (err == ESP_OK) return mp_const_none; if (err != ESP_OK) {
mp_raise_ValueError("Parameter Error"); mp_raise_ValueError("Parameter Error");
}
switch (width) {
case ADC_WIDTH_9Bit: adc_bit_width = 9; break;
case ADC_WIDTH_10Bit: adc_bit_width = 10; break;
case ADC_WIDTH_11Bit: adc_bit_width = 11; break;
case ADC_WIDTH_12Bit: adc_bit_width = 12; break;
default: break;
}
return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_2(madc_width_fun_obj, madc_width); MP_DEFINE_CONST_FUN_OBJ_2(madc_width_fun_obj, madc_width);
MP_DEFINE_CONST_CLASSMETHOD_OBJ(madc_width_obj, MP_ROM_PTR(&madc_width_fun_obj)); MP_DEFINE_CONST_CLASSMETHOD_OBJ(madc_width_obj, MP_ROM_PTR(&madc_width_fun_obj));
STATIC const mp_rom_map_elem_t madc_locals_dict_table[] = { STATIC const mp_rom_map_elem_t madc_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read_u16), MP_ROM_PTR(&madc_read_u16_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&madc_read_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&madc_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_atten), MP_ROM_PTR(&madc_atten_obj) }, { MP_ROM_QSTR(MP_QSTR_atten), MP_ROM_PTR(&madc_atten_obj) },
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&madc_width_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&madc_width_obj) },

View File

@ -154,6 +154,7 @@ STATIC const mp_rom_map_elem_t esp32_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_raw_temperature), MP_ROM_PTR(&esp32_raw_temperature_obj) }, { MP_ROM_QSTR(MP_QSTR_raw_temperature), MP_ROM_PTR(&esp32_raw_temperature_obj) },
{ MP_ROM_QSTR(MP_QSTR_hall_sensor), MP_ROM_PTR(&esp32_hall_sensor_obj) }, { MP_ROM_QSTR(MP_QSTR_hall_sensor), MP_ROM_PTR(&esp32_hall_sensor_obj) },
{ MP_ROM_QSTR(MP_QSTR_Partition), MP_ROM_PTR(&esp32_partition_type) },
{ MP_ROM_QSTR(MP_QSTR_ULP), MP_ROM_PTR(&esp32_ulp_type) }, { MP_ROM_QSTR(MP_QSTR_ULP), MP_ROM_PTR(&esp32_ulp_type) },
{ MP_ROM_QSTR(MP_QSTR_WAKEUP_ALL_LOW), MP_ROM_PTR(&mp_const_false_obj) }, { MP_ROM_QSTR(MP_QSTR_WAKEUP_ALL_LOW), MP_ROM_PTR(&mp_const_false_obj) },

View File

@ -26,6 +26,7 @@
#define RTC_LAST_EXT_PIN 39 #define RTC_LAST_EXT_PIN 39
#define RTC_IS_VALID_EXT_PIN(pin_id) ((1ll << (pin_id)) & RTC_VALID_EXT_PINS) #define RTC_IS_VALID_EXT_PIN(pin_id) ((1ll << (pin_id)) & RTC_VALID_EXT_PINS)
extern const mp_obj_type_t esp32_partition_type;
extern const mp_obj_type_t esp32_ulp_type; extern const mp_obj_type_t esp32_ulp_type;
#endif // MICROPY_INCLUDED_ESP32_MODESP32_H #endif // MICROPY_INCLUDED_ESP32_MODESP32_H

View File

@ -48,6 +48,7 @@
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "tcpip_adapter.h" #include "tcpip_adapter.h"
#include "mdns.h"
#include "modnetwork.h" #include "modnetwork.h"
@ -128,6 +129,11 @@ static bool wifi_sta_connected = false;
// Store the current status. 0 means None here, safe to do so as first enum value is WIFI_REASON_UNSPECIFIED=1. // Store the current status. 0 means None here, safe to do so as first enum value is WIFI_REASON_UNSPECIFIED=1.
static uint8_t wifi_sta_disconn_reason = 0; static uint8_t wifi_sta_disconn_reason = 0;
#if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER
// Whether mDNS has been initialised or not
static bool mdns_initialised = false;
#endif
// This function is called by the system-event task and so runs in a different // This function is called by the system-event task and so runs in a different
// thread to the main MicroPython task. It must not raise any Python exceptions. // thread to the main MicroPython task. It must not raise any Python exceptions.
static esp_err_t event_handler(void *ctx, system_event_t *event) { static esp_err_t event_handler(void *ctx, system_event_t *event) {
@ -142,6 +148,20 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) {
ESP_LOGI("network", "GOT_IP"); ESP_LOGI("network", "GOT_IP");
wifi_sta_connected = true; wifi_sta_connected = true;
wifi_sta_disconn_reason = 0; // Success so clear error. (in case of new error will be replaced anyway) wifi_sta_disconn_reason = 0; // Success so clear error. (in case of new error will be replaced anyway)
#if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER
if (!mdns_initialised) {
mdns_init();
#if MICROPY_HW_ENABLE_MDNS_RESPONDER
const char *hostname = NULL;
if (tcpip_adapter_get_hostname(WIFI_IF_STA, &hostname) != ESP_OK || hostname == NULL) {
hostname = "esp32";
}
mdns_hostname_set(hostname);
mdns_instance_name_set(hostname);
#endif
mdns_initialised = true;
}
#endif
break; break;
case SYSTEM_EVENT_STA_DISCONNECTED: { case SYSTEM_EVENT_STA_DISCONNECTED: {
// This is a workaround as ESP32 WiFi libs don't currently // This is a workaround as ESP32 WiFi libs don't currently
@ -530,17 +550,24 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
// get the config for the interface bool is_wifi = self->if_id == WIFI_IF_AP || self->if_id == WIFI_IF_STA;
wifi_config_t cfg; wifi_config_t cfg;
ESP_EXCEPTIONS(esp_wifi_get_config(self->if_id, &cfg)); if (is_wifi) {
ESP_EXCEPTIONS(esp_wifi_get_config(self->if_id, &cfg));
}
#define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x)
if (kwargs->used != 0) { if (kwargs->used != 0) {
if (!is_wifi) {
goto unknown;
}
for (size_t i = 0; i < kwargs->alloc; i++) { for (size_t i = 0; i < kwargs->alloc; i++) {
if (mp_map_slot_is_filled(kwargs, i)) { if (mp_map_slot_is_filled(kwargs, i)) {
int req_if = -1; int req_if = -1;
#define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x)
switch ((uintptr_t)kwargs->table[i].key) { switch ((uintptr_t)kwargs->table[i].key) {
case QS(MP_QSTR_mac): { case QS(MP_QSTR_mac): {
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
@ -592,7 +619,6 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
default: default:
goto unknown; goto unknown;
} }
#undef QS
// We post-check interface requirements to save on code size // We post-check interface requirements to save on code size
if (req_if >= 0) { if (req_if >= 0) {
@ -613,20 +639,34 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
} }
int req_if = -1; int req_if = -1;
mp_obj_t val; mp_obj_t val = mp_const_none;
#define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x)
switch ((uintptr_t)args[1]) { switch ((uintptr_t)args[1]) {
case QS(MP_QSTR_mac): { case QS(MP_QSTR_mac): {
uint8_t mac[6]; uint8_t mac[6];
ESP_EXCEPTIONS(esp_wifi_get_mac(self->if_id, mac)); switch (self->if_id) {
return mp_obj_new_bytes(mac, sizeof(mac)); case WIFI_IF_AP: // fallthrough intentional
case WIFI_IF_STA:
ESP_EXCEPTIONS(esp_wifi_get_mac(self->if_id, mac));
return mp_obj_new_bytes(mac, sizeof(mac));
case ESP_IF_ETH:
esp_eth_get_mac(mac);
return mp_obj_new_bytes(mac, sizeof(mac));
default:
goto unknown;
}
} }
case QS(MP_QSTR_essid): case QS(MP_QSTR_essid):
if (self->if_id == WIFI_IF_STA) { switch (self->if_id) {
val = mp_obj_new_str((char*)cfg.sta.ssid, strlen((char*)cfg.sta.ssid)); case WIFI_IF_STA:
} else { val = mp_obj_new_str((char*)cfg.sta.ssid, strlen((char*)cfg.sta.ssid));
val = mp_obj_new_str((char*)cfg.ap.ssid, cfg.ap.ssid_len); break;
case WIFI_IF_AP:
val = mp_obj_new_str((char*)cfg.ap.ssid, cfg.ap.ssid_len);
break;
default:
req_if = WIFI_IF_AP;
} }
break; break;
case QS(MP_QSTR_hidden): case QS(MP_QSTR_hidden):
@ -650,6 +690,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
default: default:
goto unknown; goto unknown;
} }
#undef QS #undef QS
// We post-check interface requirements to save on code size // We post-check interface requirements to save on code size
@ -662,8 +703,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
unknown: unknown:
mp_raise_ValueError("unknown config param"); mp_raise_ValueError("unknown config param");
} }
MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config);
STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = { STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&esp_active_obj) }, { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&esp_active_obj) },

View File

@ -31,6 +31,7 @@ enum { PHY_LAN8720, PHY_TLK110 };
MP_DECLARE_CONST_FUN_OBJ_KW(get_lan_obj); MP_DECLARE_CONST_FUN_OBJ_KW(get_lan_obj);
MP_DECLARE_CONST_FUN_OBJ_1(ppp_make_new_obj); MP_DECLARE_CONST_FUN_OBJ_1(ppp_make_new_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj);
MP_DECLARE_CONST_FUN_OBJ_KW(esp_config_obj);
void usocket_events_deinit(void); void usocket_events_deinit(void);

View File

@ -47,6 +47,7 @@
#include "py/mperrno.h" #include "py/mperrno.h"
#include "lib/netutils/netutils.h" #include "lib/netutils/netutils.h"
#include "tcpip_adapter.h" #include "tcpip_adapter.h"
#include "mdns.h"
#include "modnetwork.h" #include "modnetwork.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
@ -56,6 +57,8 @@
#include "esp_log.h" #include "esp_log.h"
#define SOCKET_POLL_US (100000) #define SOCKET_POLL_US (100000)
#define MDNS_QUERY_TIMEOUT_MS (5000)
#define MDNS_LOCAL_SUFFIX ".local"
typedef struct _socket_obj_t { typedef struct _socket_obj_t {
mp_obj_base_t base; mp_obj_base_t base;
@ -150,6 +153,58 @@ static inline void check_for_exceptions(void) {
mp_handle_pending(); mp_handle_pending();
} }
// This function mimics lwip_getaddrinfo, with added support for mDNS queries
static int _socket_getaddrinfo3(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res) {
#if MICROPY_HW_ENABLE_MDNS_QUERIES
int nodename_len = strlen(nodename);
const int local_len = sizeof(MDNS_LOCAL_SUFFIX) - 1;
if (nodename_len > local_len
&& strcasecmp(nodename + nodename_len - local_len, MDNS_LOCAL_SUFFIX) == 0) {
// mDNS query
char nodename_no_local[nodename_len - local_len + 1];
memcpy(nodename_no_local, nodename, nodename_len - local_len);
nodename_no_local[nodename_len - local_len] = '\0';
struct ip4_addr addr = {0};
esp_err_t err = mdns_query_a(nodename_no_local, MDNS_QUERY_TIMEOUT_MS, &addr);
if (err != ESP_OK) {
if (err == ESP_ERR_NOT_FOUND){
*res = NULL;
return 0;
}
*res = NULL;
return err;
}
struct addrinfo *ai = memp_malloc(MEMP_NETDB);
if (ai == NULL) {
*res = NULL;
return EAI_MEMORY;
}
memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
struct sockaddr_in *sa = (struct sockaddr_in*)((uint8_t*)ai + sizeof(struct addrinfo));
inet_addr_from_ip4addr(&sa->sin_addr, &addr);
sa->sin_family = AF_INET;
sa->sin_len = sizeof(struct sockaddr_in);
sa->sin_port = lwip_htons((u16_t)atoi(servname));
ai->ai_family = AF_INET;
ai->ai_canonname = ((char*)sa + sizeof(struct sockaddr_storage));
memcpy(ai->ai_canonname, nodename, nodename_len + 1);
ai->ai_addrlen = sizeof(struct sockaddr_storage);
ai->ai_addr = (struct sockaddr*)sa;
*res = ai;
return 0;
}
#endif
// Normal query
return lwip_getaddrinfo(nodename, servname, hints, res);
}
static int _socket_getaddrinfo2(const mp_obj_t host, const mp_obj_t portx, struct addrinfo **resp) { static int _socket_getaddrinfo2(const mp_obj_t host, const mp_obj_t portx, struct addrinfo **resp) {
const struct addrinfo hints = { const struct addrinfo hints = {
.ai_family = AF_INET, .ai_family = AF_INET,
@ -172,7 +227,7 @@ static int _socket_getaddrinfo2(const mp_obj_t host, const mp_obj_t portx, struc
} }
MP_THREAD_GIL_EXIT(); MP_THREAD_GIL_EXIT();
int res = lwip_getaddrinfo(host_str, port_str, &hints, resp); int res = _socket_getaddrinfo3(host_str, port_str, &hints, resp);
MP_THREAD_GIL_ENTER(); MP_THREAD_GIL_ENTER();
return res; return res;

View File

@ -1,34 +1,4 @@
import esp from esp32 import Partition
class FlashBdev: bdev = Partition.find(Partition.TYPE_DATA, label='vfs')
bdev = bdev[0] if bdev else None
SEC_SIZE = 4096
START_SEC = esp.flash_user_start() // SEC_SIZE
def __init__(self, blocks):
self.blocks = blocks
def readblocks(self, n, buf):
#print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
esp.flash_read((n + self.START_SEC) * self.SEC_SIZE, buf)
def writeblocks(self, n, buf):
#print("writeblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
#assert len(buf) <= self.SEC_SIZE, len(buf)
esp.flash_erase(n + self.START_SEC)
esp.flash_write((n + self.START_SEC) * self.SEC_SIZE, buf)
def ioctl(self, op, arg):
#print("ioctl(%d, %r)" % (op, arg))
if op == 4: # BP_IOCTL_SEC_COUNT
return self.blocks
if op == 5: # BP_IOCTL_SEC_SIZE
return self.SEC_SIZE
size = esp.flash_size()
if size < 1024*1024:
# flash too small for a filesystem
bdev = None
else:
# for now we use a fixed size for the filesystem
bdev = FlashBdev(2048 * 1024 // FlashBdev.SEC_SIZE)

View File

@ -2,7 +2,7 @@ import uos
from flashbdev import bdev from flashbdev import bdev
def check_bootsec(): def check_bootsec():
buf = bytearray(bdev.SEC_SIZE) buf = bytearray(bdev.ioctl(5, 0)) # 5 is SEC_SIZE
bdev.readblocks(0, buf) bdev.readblocks(0, buf)
empty = True empty = True
for b in buf: for b in buf:
@ -29,8 +29,7 @@ def setup():
print("Performing initial setup") print("Performing initial setup")
uos.VfsFat.mkfs(bdev) uos.VfsFat.mkfs(bdev)
vfs = uos.VfsFat(bdev) vfs = uos.VfsFat(bdev)
uos.mount(vfs, '/flash') uos.mount(vfs, '/')
uos.chdir('/flash')
with open("boot.py", "w") as f: with open("boot.py", "w") as f:
f.write("""\ f.write("""\
# This file is executed on every boot (including wake-boot from deepsleep) # This file is executed on every boot (including wake-boot from deepsleep)

View File

@ -0,0 +1,486 @@
#
# Small ftp server for ESP8266 Micropython
# Based on the work of chrisgp - Christopher Popp and pfalcon - Paul Sokolovsky
#
# The server accepts passive mode only. It runs in background.
# Start the server with:
#
# import uftpd
# uftpd.start([port = 21][, verbose = level])
#
# port is the port number (default 21)
# verbose controls the level of printed activity messages, values 0, 1, 2
#
# Copyright (c) 2016 Christopher Popp (initial ftp server framework)
# Copyright (c) 2016 Paul Sokolovsky (background execution control structure)
# Copyright (c) 2016 Robert Hammelrath (putting the pieces together and a
# few extensions)
# Distributed under MIT License
#
import socket
import network
import uos
import gc
from time import sleep_ms, localtime
from micropython import alloc_emergency_exception_buf
# constant definitions
_CHUNK_SIZE = const(1024)
_SO_REGISTER_HANDLER = const(20)
_COMMAND_TIMEOUT = const(300)
_DATA_TIMEOUT = const(100)
_DATA_PORT = const(13333)
# Global variables
ftpsocket = None
datasocket = None
client_list = []
verbose_l = 0
client_busy = False
# Interfaces: (IP-Address (string), IP-Address (integer), Netmask (integer))
AP_addr = ("0.0.0.0", 0, 0xffffff00)
STA_addr = ("0.0.0.0", 0, 0xffffff00)
_month_name = ("", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
class FTP_client:
def __init__(self, ftpsocket):
global AP_addr, STA_addr
self.command_client, self.remote_addr = ftpsocket.accept()
self.remote_addr = self.remote_addr[0]
self.command_client.settimeout(_COMMAND_TIMEOUT)
log_msg(1, "FTP Command connection from:", self.remote_addr)
self.command_client.setsockopt(socket.SOL_SOCKET,
_SO_REGISTER_HANDLER,
self.exec_ftp_command)
self.command_client.sendall("220 Hello, this is the ESP8266.\r\n")
self.cwd = '/'
self.fromname = None
# self.logged_in = False
self.act_data_addr = self.remote_addr
self.DATA_PORT = 20
self.active = True
# check which interface was used by comparing the caller's ip
# adress with the ip adresses of STA and AP; consider netmask;
# select IP address for passive mode
if ((AP_addr[1] & AP_addr[2]) ==
(num_ip(self.remote_addr) & AP_addr[2])):
self.pasv_data_addr = AP_addr[0]
elif ((STA_addr[1] & STA_addr[2]) ==
(num_ip(self.remote_addr) & STA_addr[2])):
self.pasv_data_addr = STA_addr[0]
else:
self.pasv_data_addr = "0.0.0.0" # Ivalid value
def send_list_data(self, path, data_client, full):
try:
for fname in uos.listdir(path):
data_client.sendall(self.make_description(path, fname, full))
except: # path may be a file name or pattern
path, pattern = self.split_path(path)
try:
for fname in uos.listdir(path):
if self.fncmp(fname, pattern):
data_client.sendall(
self.make_description(path, fname, full))
except:
pass
def make_description(self, path, fname, full):
global _month_name
if full:
stat = uos.stat(self.get_absolute_path(path, fname))
file_permissions = ("drwxr-xr-x"
if (stat[0] & 0o170000 == 0o040000)
else "-rw-r--r--")
file_size = stat[6]
tm = localtime(stat[7])
if tm[0] != localtime()[0]:
description = "{} 1 owner group {:>10} {} {:2} {:>5} {}\r\n".\
format(file_permissions, file_size,
_month_name[tm[1]], tm[2], tm[0], fname)
else:
description = "{} 1 owner group {:>10} {} {:2} {:02}:{:02} {}\r\n".\
format(file_permissions, file_size,
_month_name[tm[1]], tm[2], tm[3], tm[4], fname)
else:
description = fname + "\r\n"
return description
def send_file_data(self, path, data_client):
with open(path, "r") as file:
chunk = file.read(_CHUNK_SIZE)
while len(chunk) > 0:
data_client.sendall(chunk)
chunk = file.read(_CHUNK_SIZE)
data_client.close()
def save_file_data(self, path, data_client, mode):
with open(path, mode) as file:
chunk = data_client.recv(_CHUNK_SIZE)
while len(chunk) > 0:
file.write(chunk)
chunk = data_client.recv(_CHUNK_SIZE)
data_client.close()
def get_absolute_path(self, cwd, payload):
# Just a few special cases "..", "." and ""
# If payload start's with /, set cwd to /
# and consider the remainder a relative path
if payload.startswith('/'):
cwd = "/"
for token in payload.split("/"):
if token == '..':
cwd = self.split_path(cwd)[0]
elif token != '.' and token != '':
if cwd == '/':
cwd += token
else:
cwd = cwd + '/' + token
return cwd
def split_path(self, path): # instead of path.rpartition('/')
tail = path.split('/')[-1]
head = path[:-(len(tail) + 1)]
return ('/' if head == '' else head, tail)
# compare fname against pattern. Pattern may contain
# the wildcards ? and *.
def fncmp(self, fname, pattern):
pi = 0
si = 0
while pi < len(pattern) and si < len(fname):
if (fname[si] == pattern[pi]) or (pattern[pi] == '?'):
si += 1
pi += 1
else:
if pattern[pi] == '*': # recurse
if pi == len(pattern.rstrip("*?")): # only wildcards left
return True
while si < len(fname):
if self.fncmp(fname[si:], pattern[pi + 1:]):
return True
else:
si += 1
return False
else:
return False
if pi == len(pattern.rstrip("*")) and si == len(fname):
return True
else:
return False
def open_dataclient(self):
if self.active: # active mode
data_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data_client.settimeout(_DATA_TIMEOUT)
data_client.connect((self.act_data_addr, self.DATA_PORT))
log_msg(1, "FTP Data connection with:", self.act_data_addr)
else: # passive mode
data_client, data_addr = datasocket.accept()
log_msg(1, "FTP Data connection with:", data_addr[0])
return data_client
def exec_ftp_command(self, cl):
global datasocket
global client_busy
global my_ip_addr
try:
gc.collect()
data = cl.readline().decode("utf-8").rstrip("\r\n")
if len(data) <= 0:
# No data, close
# This part is NOT CLEAN; there is still a chance that a
# closing data connection will be signalled as closing
# command connection
log_msg(1, "*** No data, assume QUIT")
close_client(cl)
return
if client_busy: # check if another client is busy
cl.sendall("400 Device busy.\r\n") # tell so the remote client
return # and quit
client_busy = True # now it's my turn
# check for log-in state may done here, like
# if self.logged_in == False and not command in\
# ("USER", "PASS", "QUIT"):
# cl.sendall("530 Not logged in.\r\n")
# return
command = data.split()[0].upper()
payload = data[len(command):].lstrip() # partition is missing
path = self.get_absolute_path(self.cwd, payload)
log_msg(1, "Command={}, Payload={}".format(command, payload))
if command == "USER":
# self.logged_in = True
cl.sendall("230 Logged in.\r\n")
# If you want to see a password,return
# "331 Need password.\r\n" instead
# If you want to reject an user, return
# "530 Not logged in.\r\n"
elif command == "PASS":
# you may check here for a valid password and return
# "530 Not logged in.\r\n" in case it's wrong
# self.logged_in = True
cl.sendall("230 Logged in.\r\n")
elif command == "SYST":
cl.sendall("215 UNIX Type: L8\r\n")
elif command in ("TYPE", "NOOP", "ABOR"): # just accept & ignore
cl.sendall('200 OK\r\n')
elif command == "QUIT":
cl.sendall('221 Bye.\r\n')
close_client(cl)
elif command == "PWD" or command == "XPWD":
cl.sendall('257 "{}"\r\n'.format(self.cwd))
elif command == "CWD" or command == "XCWD":
try:
if (uos.stat(path)[0] & 0o170000) == 0o040000:
self.cwd = path
cl.sendall('250 OK\r\n')
else:
cl.sendall('550 Fail\r\n')
except:
cl.sendall('550 Fail\r\n')
elif command == "PASV":
cl.sendall('227 Entering Passive Mode ({},{},{}).\r\n'.format(
self.pasv_data_addr.replace('.', ','),
_DATA_PORT >> 8, _DATA_PORT % 256))
self.active = False
elif command == "PORT":
items = payload.split(",")
if len(items) >= 6:
self.act_data_addr = '.'.join(items[:4])
if self.act_data_addr == "127.0.1.1":
# replace by command session addr
self.act_data_addr = self.remote_addr
self.DATA_PORT = int(items[4]) * 256 + int(items[5])
cl.sendall('200 OK\r\n')
self.active = True
else:
cl.sendall('504 Fail\r\n')
elif command == "LIST" or command == "NLST":
if payload.startswith("-"):
option = payload.split()[0].lower()
path = self.get_absolute_path(
self.cwd, payload[len(option):].lstrip())
else:
option = ""
try:
data_client = self.open_dataclient()
cl.sendall("150 Directory listing:\r\n")
self.send_list_data(path, data_client,
command == "LIST" or 'l' in option)
cl.sendall("226 Done.\r\n")
data_client.close()
except:
cl.sendall('550 Fail\r\n')
if data_client is not None:
data_client.close()
elif command == "RETR":
try:
data_client = self.open_dataclient()
cl.sendall("150 Opened data connection.\r\n")
self.send_file_data(path, data_client)
# if the next statement is reached,
# the data_client was closed.
data_client = None
cl.sendall("226 Done.\r\n")
except:
cl.sendall('550 Fail\r\n')
if data_client is not None:
data_client.close()
elif command == "STOR" or command == "APPE":
try:
data_client = self.open_dataclient()
cl.sendall("150 Opened data connection.\r\n")
self.save_file_data(path, data_client,
"w" if command == "STOR" else "a")
# if the next statement is reached,
# the data_client was closed.
data_client = None
cl.sendall("226 Done.\r\n")
except:
cl.sendall('550 Fail\r\n')
if data_client is not None:
data_client.close()
elif command == "SIZE":
try:
cl.sendall('213 {}\r\n'.format(uos.stat(path)[6]))
except:
cl.sendall('550 Fail\r\n')
elif command == "STAT":
if payload == "":
cl.sendall("211-Connected to ({})\r\n"
" Data address ({})\r\n"
" TYPE: Binary STRU: File MODE: Stream\r\n"
" Session timeout {}\r\n"
"211 Client count is {}\r\n".format(
self.remote_addr, self.pasv_data_addr,
_COMMAND_TIMEOUT, len(client_list)))
else:
cl.sendall("213-Directory listing:\r\n")
self.send_list_data(path, cl, True)
cl.sendall("213 Done.\r\n")
elif command == "DELE":
try:
uos.remove(path)
cl.sendall('250 OK\r\n')
except:
cl.sendall('550 Fail\r\n')
elif command == "RNFR":
try:
# just test if the name exists, exception if not
uos.stat(path)
self.fromname = path
cl.sendall("350 Rename from\r\n")
except:
cl.sendall('550 Fail\r\n')
elif command == "RNTO":
try:
uos.rename(self.fromname, path)
cl.sendall('250 OK\r\n')
except:
cl.sendall('550 Fail\r\n')
self.fromname = None
elif command == "CDUP" or command == "XCUP":
self.cwd = self.get_absolute_path(self.cwd, "..")
cl.sendall('250 OK\r\n')
elif command == "RMD" or command == "XRMD":
try:
uos.rmdir(path)
cl.sendall('250 OK\r\n')
except:
cl.sendall('550 Fail\r\n')
elif command == "MKD" or command == "XMKD":
try:
uos.mkdir(path)
cl.sendall('250 OK\r\n')
except:
cl.sendall('550 Fail\r\n')
else:
cl.sendall("502 Unsupported command.\r\n")
# log_msg(2,
# "Unsupported command {} with payload {}".format(command,
# payload))
# handle unexpected errors
except Exception as err:
log_msg(1, "Exception in exec_ftp_command: {}".format(err))
# tidy up before leaving
client_busy = False
def log_msg(level, *args):
global verbose_l
if verbose_l >= level:
print(*args)
# close client and remove it from the list
def close_client(cl):
cl.setsockopt(socket.SOL_SOCKET, _SO_REGISTER_HANDLER, None)
cl.close()
for i, client in enumerate(client_list):
if client.command_client == cl:
del client_list[i]
break
def accept_ftp_connect(ftpsocket):
# Accept new calls for the server
try:
client_list.append(FTP_client(ftpsocket))
except:
log_msg(1, "Attempt to connect failed")
# try at least to reject
try:
temp_client, temp_addr = ftpsocket.accept()
temp_client.close()
except:
pass
def num_ip(ip):
items = ip.split(".")
return (int(items[0]) << 24 | int(items[1]) << 16 |
int(items[2]) << 8 | int(items[3]))
def stop():
global ftpsocket, datasocket
global client_list
global client_busy
for client in client_list:
client.command_client.setsockopt(socket.SOL_SOCKET,
_SO_REGISTER_HANDLER, None)
client.command_client.close()
del client_list
client_list = []
client_busy = False
if ftpsocket is not None:
ftpsocket.setsockopt(socket.SOL_SOCKET, _SO_REGISTER_HANDLER, None)
ftpsocket.close()
if datasocket is not None:
datasocket.close()
# start listening for ftp connections on port 21
def start(port=21, verbose=0, splash=True):
global ftpsocket, datasocket
global verbose_l
global client_list
global client_busy
global AP_addr, STA_addr
alloc_emergency_exception_buf(100)
verbose_l = verbose
client_list = []
client_busy = False
ftpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
datasocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ftpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
datasocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ftpsocket.bind(('0.0.0.0', port))
datasocket.bind(('0.0.0.0', _DATA_PORT))
ftpsocket.listen(0)
datasocket.listen(0)
datasocket.settimeout(10)
ftpsocket.setsockopt(socket.SOL_SOCKET,
_SO_REGISTER_HANDLER, accept_ftp_connect)
wlan = network.WLAN(network.AP_IF)
if wlan.active():
ifconfig = wlan.ifconfig()
# save IP address string and numerical values of IP adress and netmask
AP_addr = (ifconfig[0], num_ip(ifconfig[0]), num_ip(ifconfig[1]))
if splash:
print("FTP server started on {}:{}".format(ifconfig[0], port))
wlan = network.WLAN(network.STA_IF)
if wlan.active():
ifconfig = wlan.ifconfig()
# save IP address string and numerical values of IP adress and netmask
STA_addr = (ifconfig[0], num_ip(ifconfig[0]), num_ip(ifconfig[1]))
if splash:
print("FTP server started on {}:{}".format(ifconfig[0], port))
def restart(port=21, verbose=0, splash=True):
stop()
sleep_ms(200)
start(port, verbose, splash)
start(splash=True)

View File

@ -1,6 +1,9 @@
// Options to control how MicroPython is built for this port, // Options to control how MicroPython is built for this port,
// overriding defaults in py/mpconfig.h. // overriding defaults in py/mpconfig.h.
// Board-specific definitions
#include "mpconfigboard.h"
#include <stdint.h> #include <stdint.h>
#include <alloca.h> #include <alloca.h>
#include "rom/ets_sys.h" #include "rom/ets_sys.h"
@ -96,6 +99,7 @@
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
#define MICROPY_PY_MATH (1) #define MICROPY_PY_MATH (1)
#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1)
#define MICROPY_PY_MATH_ISCLOSE (1)
#define MICROPY_PY_CMATH (1) #define MICROPY_PY_CMATH (1)
#define MICROPY_PY_GC (1) #define MICROPY_PY_GC (1)
#define MICROPY_PY_IO (1) #define MICROPY_PY_IO (1)
@ -290,7 +294,12 @@ typedef long mp_off_t;
#include <sys/types.h> #include <sys/types.h>
// board specifics // board specifics
#define MICROPY_HW_BOARD_NAME "ESP32 module"
#define MICROPY_HW_MCU_NAME "ESP32"
#define MICROPY_PY_SYS_PLATFORM "esp32" #define MICROPY_PY_SYS_PLATFORM "esp32"
#ifndef MICROPY_HW_ENABLE_MDNS_QUERIES
#define MICROPY_HW_ENABLE_MDNS_QUERIES (1)
#endif
#ifndef MICROPY_HW_ENABLE_MDNS_RESPONDER
#define MICROPY_HW_ENABLE_MDNS_RESPONDER (1)
#endif

View File

@ -205,6 +205,7 @@ STATIC const mp_rom_map_elem_t lan_if_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&lan_active_obj) }, { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&lan_active_obj) },
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&lan_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&lan_isconnected_obj) },
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&lan_status_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&lan_status_obj) },
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&esp_config_obj) },
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_ifconfig_obj) },
}; };

View File

@ -129,29 +129,26 @@ STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
if (self->pcb == NULL) { if (self->pcb == NULL) {
mp_raise_msg(&mp_type_RuntimeError, "init failed"); mp_raise_msg(&mp_type_RuntimeError, "init failed");
} }
pppapi_set_default(self->pcb);
ppp_set_usepeerdns(self->pcb, 1);
pppapi_connect(self->pcb, 0);
xTaskCreatePinnedToCore(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t*)&self->client_task_handle, MP_TASK_COREID);
self->active = true; self->active = true;
} else { } else {
if (!self->active) { if (!self->active) {
return mp_const_false; return mp_const_false;
} }
// Wait for PPPERR_USER, with timeout if (self->client_task_handle != NULL) { // is connecting or connected?
pppapi_close(self->pcb, 0); // Wait for PPPERR_USER, with timeout
uint32_t t0 = mp_hal_ticks_ms(); pppapi_close(self->pcb, 0);
while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) { uint32_t t0 = mp_hal_ticks_ms();
mp_hal_delay_ms(10); while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
} mp_hal_delay_ms(10);
}
// Shutdown task // Shutdown task
xTaskNotifyGive(self->client_task_handle); xTaskNotifyGive(self->client_task_handle);
t0 = mp_hal_ticks_ms(); t0 = mp_hal_ticks_ms();
while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) { while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
mp_hal_delay_ms(10); mp_hal_delay_ms(10);
}
} }
// Release PPP // Release PPP
@ -166,6 +163,59 @@ STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_active_obj, 1, 2, ppp_active); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_active_obj, 1, 2, ppp_active);
STATIC mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
enum { ARG_authmode, ARG_username, ARG_password };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_authmode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PPPAUTHTYPE_NONE} },
{ MP_QSTR_username, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
{ MP_QSTR_password, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
};
mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args);
ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
if (!self->active) {
mp_raise_msg(&mp_type_OSError, "must be active");
}
if (self->client_task_handle != NULL) {
mp_raise_OSError(MP_EALREADY);
}
switch (parsed_args[ARG_authmode].u_int) {
case PPPAUTHTYPE_NONE:
case PPPAUTHTYPE_PAP:
case PPPAUTHTYPE_CHAP:
break;
default:
mp_raise_msg(&mp_type_ValueError, "invalid auth");
}
if (parsed_args[ARG_authmode].u_int != PPPAUTHTYPE_NONE) {
const char* username_str = mp_obj_str_get_str(parsed_args[ARG_username].u_obj);
const char* password_str = mp_obj_str_get_str(parsed_args[ARG_password].u_obj);
pppapi_set_auth(self->pcb, parsed_args[ARG_authmode].u_int, username_str, password_str);
}
if (pppapi_set_default(self->pcb) != ESP_OK) {
mp_raise_msg(&mp_type_OSError, "set default failed");
}
ppp_set_usepeerdns(self->pcb, true);
if (pppapi_connect(self->pcb, 0) != ESP_OK) {
mp_raise_msg(&mp_type_OSError, "connect failed");
}
if (xTaskCreatePinnedToCore(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t*)&self->client_task_handle, MP_TASK_COREID) != pdPASS) {
mp_raise_msg(&mp_type_RuntimeError, "failed to create worker task");
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(ppp_connect_obj, 1, ppp_connect_py);
STATIC mp_obj_t ppp_delete(mp_obj_t self_in) { STATIC mp_obj_t ppp_delete(mp_obj_t self_in) {
ppp_if_obj_t* self = MP_OBJ_TO_PTR(self_in); ppp_if_obj_t* self = MP_OBJ_TO_PTR(self_in);
mp_obj_t args[] = {self, mp_const_false}; mp_obj_t args[] = {self, mp_const_false};
@ -216,10 +266,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ppp_isconnected_obj, ppp_isconnected);
STATIC const mp_rom_map_elem_t ppp_if_locals_dict_table[] = { STATIC const mp_rom_map_elem_t ppp_if_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&ppp_active_obj) }, { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&ppp_active_obj) },
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&ppp_connect_obj) },
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&ppp_isconnected_obj) }, { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&ppp_isconnected_obj) },
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) },
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) },
{ MP_ROM_QSTR(MP_QSTR_AUTH_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) },
{ MP_ROM_QSTR(MP_QSTR_AUTH_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) },
{ MP_ROM_QSTR(MP_QSTR_AUTH_CHAP), MP_ROM_INT(PPPAUTHTYPE_CHAP) },
}; };
STATIC MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table);

View File

@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 0x110000,
vfs, data, fat, 0x120000, 0xA0000,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 0x110000,
6 vfs, data, fat, 0x120000, 0xA0000,

View File

@ -2,4 +2,5 @@
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000, phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 0x190000, factory, app, factory, 0x10000, 0x200000,
vfs, data, fat, 0x210000, 0x1f0000,

1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 0x190000, factory, app, factory, 0x10000, 0x200000,
6 vfs, data, fat, 0x210000, 0x1f0000,

View File

@ -110,6 +110,7 @@ SECTIONS
*py/obj*.o*(.literal* .text*) *py/obj*.o*(.literal* .text*)
*py/opmethods.o*(.literal* .text*) *py/opmethods.o*(.literal* .text*)
*py/parse*.o*(.literal* .text*) *py/parse*.o*(.literal* .text*)
*py/profile*.o*(.literal* .text*)
*py/qstr.o*(.literal* .text*) *py/qstr.o*(.literal* .text*)
*py/repl.o*(.literal* .text*) *py/repl.o*(.literal* .text*)
*py/runtime.o*(.literal* .text*) *py/runtime.o*(.literal* .text*)

View File

@ -28,54 +28,71 @@
#include <string.h> #include <string.h>
#include "py/runtime.h" #include "py/runtime.h"
#include "py/mphal.h"
#include "user_interface.h" #include "user_interface.h"
const mp_obj_type_t pyb_adc_type; typedef struct _machine_adc_obj_t {
typedef struct _pyb_adc_obj_t {
mp_obj_base_t base; mp_obj_base_t base;
bool isvdd; bool isvdd;
} pyb_adc_obj_t; } machine_adc_obj_t;
STATIC pyb_adc_obj_t pyb_adc_vdd3 = {{&pyb_adc_type}, true}; extern const mp_obj_type_t machine_adc_type;
STATIC pyb_adc_obj_t pyb_adc_adc = {{&pyb_adc_type}, false};
STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, STATIC machine_adc_obj_t machine_adc_vdd3 = {{&machine_adc_type}, true};
const mp_obj_t *args) { STATIC machine_adc_obj_t machine_adc_adc = {{&machine_adc_type}, false};
STATIC uint16_t adc_read(machine_adc_obj_t *self) {
if (self->isvdd) {
return system_get_vdd33();
} else {
return system_adc_read();
}
}
void machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "ADC(%u)", self->isvdd);
}
mp_obj_t machine_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 1, false); mp_arg_check_num(n_args, n_kw, 1, 1, false);
mp_int_t chn = mp_obj_get_int(args[0]); mp_int_t chn = mp_obj_get_int(args[0]);
switch (chn) { switch (chn) {
case 0: case 0:
return &pyb_adc_adc; return &machine_adc_adc;
case 1: case 1:
return &pyb_adc_vdd3; return &machine_adc_vdd3;
default: default:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ADC(%d) doesn't exist", chn));
"not a valid ADC Channel: %d", chn));
} }
} }
STATIC mp_obj_t pyb_adc_read(mp_obj_t self_in) { // read_u16()
pyb_adc_obj_t *adc = self_in; STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) {
machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (adc->isvdd) { uint32_t value = adc_read(self);
return mp_obj_new_int(system_get_vdd33()); return MP_OBJ_NEW_SMALL_INT(value * 65535 / 1024);
} else {
return mp_obj_new_int(system_adc_read());
}
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_adc_read_obj, pyb_adc_read); STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_u16_obj, machine_adc_read_u16);
STATIC const mp_rom_map_elem_t pyb_adc_locals_dict_table[] = { // Legacy method
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_adc_read_obj) } STATIC mp_obj_t machine_adc_read(mp_obj_t self_in) {
machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(adc_read(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_obj, machine_adc_read);
STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read_u16), MP_ROM_PTR(&machine_adc_read_u16_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_adc_read_obj) }
}; };
STATIC MP_DEFINE_CONST_DICT(pyb_adc_locals_dict, pyb_adc_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(machine_adc_locals_dict, machine_adc_locals_dict_table);
const mp_obj_type_t pyb_adc_type = { const mp_obj_type_t machine_adc_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_ADC, .name = MP_QSTR_ADC,
.make_new = pyb_adc_make_new, .print = machine_adc_print,
.locals_dict = (mp_obj_dict_t*)&pyb_adc_locals_dict, .make_new = machine_adc_make_new,
.locals_dict = (mp_obj_dict_t*)&machine_adc_locals_dict,
}; };

View File

@ -29,11 +29,13 @@
#include <string.h> #include <string.h>
#include "ets_sys.h" #include "ets_sys.h"
#include "user_interface.h"
#include "uart.h" #include "uart.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stream.h" #include "py/stream.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#include "py/mphal.h"
#include "modmachine.h" #include "modmachine.h"
// UartDev is defined and initialized in rom code. // UartDev is defined and initialized in rom code.
@ -63,14 +65,14 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
} }
STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_rxbuf, ARG_timeout, ARG_timeout_char }; enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_tx, ARG_rx, ARG_rxbuf, ARG_timeout, ARG_timeout_char };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_bits, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_stop, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_stop, MP_ARG_INT, {.u_int = 0} },
//{ MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
//{ MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
@ -128,6 +130,22 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
} }
} }
// set tx/rx pins
mp_hal_pin_obj_t tx = 1, rx = 3;
if (args[ARG_tx].u_obj != MP_OBJ_NULL) {
tx = mp_hal_get_pin_obj(args[ARG_tx].u_obj);
}
if (args[ARG_rx].u_obj != MP_OBJ_NULL) {
rx = mp_hal_get_pin_obj(args[ARG_rx].u_obj);
}
if (tx == 1 && rx == 3) {
system_uart_de_swap();
} else if (tx == 15 && rx == 13) {
system_uart_swap();
} else {
mp_raise_ValueError("invalid tx/rx");
}
// set stop bits // set stop bits
switch (args[ARG_stop].u_int) { switch (args[ARG_stop].u_int) {
case 0: case 0:

View File

@ -410,7 +410,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
{ MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) },
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) }, { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
#if MICROPY_PY_MACHINE_I2C #if MICROPY_PY_MACHINE_I2C
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) },

View File

@ -5,7 +5,7 @@
extern const mp_obj_type_t pyb_pin_type; extern const mp_obj_type_t pyb_pin_type;
extern const mp_obj_type_t pyb_pwm_type; extern const mp_obj_type_t pyb_pwm_type;
extern const mp_obj_type_t pyb_adc_type; extern const mp_obj_type_t machine_adc_type;
extern const mp_obj_type_t pyb_rtc_type; extern const mp_obj_type_t pyb_rtc_type;
extern const mp_obj_type_t pyb_uart_type; extern const mp_obj_type_t pyb_uart_type;
extern const mp_obj_type_t pyb_i2c_type; extern const mp_obj_type_t pyb_i2c_type;

View File

@ -46,7 +46,7 @@ int do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
} else { } else {

View File

@ -73,6 +73,7 @@
#define MICROPY_PY_COLLECTIONS (1) #define MICROPY_PY_COLLECTIONS (1)
#define MICROPY_PY_MATH (1) #define MICROPY_PY_MATH (1)
#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1)
#define MICROPY_PY_MATH_ISCLOSE (1)
#define MICROPY_PY_CMATH (1) #define MICROPY_PY_CMATH (1)
#define MICROPY_PY_IO (1) #define MICROPY_PY_IO (1)
#define MICROPY_PY_STRUCT (1) #define MICROPY_PY_STRUCT (1)

View File

@ -16,7 +16,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
} else { } else {

View File

@ -1,8 +1,3 @@
# Nordic files # Nordic files
##################### #####################
drivers/bluetooth/s1*/ drivers/bluetooth/s1*/
# Build files
#####################
build-*/

View File

@ -101,7 +101,7 @@ LDFLAGS += -Wl,--gc-sections
endif endif
CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES))
CFLAGS += $(INC) -Wall -Werror -g -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_MOD) CFLAGS += $(INC) -Wall -Werror -g -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_MOD)
CFLAGS += -fno-strict-aliasing CFLAGS += -fno-strict-aliasing
CFLAGS += -Iboards/$(BOARD) CFLAGS += -Iboards/$(BOARD)
@ -254,7 +254,7 @@ OBJ += $(BUILD)/pins_gen.o
$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
.PHONY: all flash sd binary hex .PHONY: all flash deploy sd binary hex
all: binary hex all: binary hex
@ -276,7 +276,7 @@ FLASHER ?=
ifeq ($(FLASHER),) ifeq ($(FLASHER),)
flash: $(BUILD)/$(OUTPUT_FILENAME).hex deploy: $(BUILD)/$(OUTPUT_FILENAME).hex
nrfjprog --program $< --sectorerase -f $(MCU_VARIANT) nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
nrfjprog --reset -f $(MCU_VARIANT) nrfjprog --reset -f $(MCU_VARIANT)
@ -288,7 +288,7 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).hex
else ifeq ($(FLASHER), pyocd) else ifeq ($(FLASHER), pyocd)
flash: $(BUILD)/$(OUTPUT_FILENAME).hex deploy: $(BUILD)/$(OUTPUT_FILENAME).hex
pyocd-flashtool -t $(MCU_VARIANT) $< pyocd-flashtool -t $(MCU_VARIANT) $<
sd: $(BUILD)/$(OUTPUT_FILENAME).hex sd: $(BUILD)/$(OUTPUT_FILENAME).hex
@ -298,14 +298,47 @@ sd: $(BUILD)/$(OUTPUT_FILENAME).hex
else ifeq ($(FLASHER), idap) else ifeq ($(FLASHER), idap)
flash: $(BUILD)/$(OUTPUT_FILENAME).hex deploy: $(BUILD)/$(OUTPUT_FILENAME).hex
IDAPnRFPRog $< IDAPnRFPRog $<
sd: $(BUILD)/$(OUTPUT_FILENAME).hex sd: $(BUILD)/$(OUTPUT_FILENAME).hex
IDAPnRFPRog $(SOFTDEV_HEX) $< IDAPnRFPRog $(SOFTDEV_HEX) $<
else ifeq ($(FLASHER), bmp)
BMP_PORT ?= /dev/ttyACM0
deploy: $(BUILD)/$(OUTPUT_FILENAME).elf
$(Q)$(GDB) \
-ex 'target extended-remote $(BMP_PORT)' \
-ex 'monitor tpwr enable' \
-ex 'monitor swdp_scan' \
-ex 'attach 1' \
-ex 'set mem inaccessible-by-default off' \
-ex 'load' \
-ex 'kill' \
-ex 'quit' \
$<
sd: $(BUILD)/$(OUTPUT_FILENAME).elf
$(Q)$(GDB) \
-ex 'target extended-remote $(BMP_PORT)' \
-ex 'monitor tpwr enable' \
-ex 'monitor swdp_scan' \
-ex 'attach 1' \
-ex 'set mem inaccessible-by-default off' \
-ex 'monitor erase_mass' \
-ex 'load' \
-ex 'file $(SOFTDEV_HEX)' \
-ex 'load' \
-ex 'kill' \
-ex 'quit' \
$<
endif endif
flash: deploy
$(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ) $(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ)
$(ECHO) "LINK $@" $(ECHO) "LINK $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)

View File

@ -30,7 +30,7 @@ This is a port of MicroPython to the Nordic Semiconductor nRF series of chips.
* PCA10031 (dongle) * PCA10031 (dongle)
* [WT51822-S4AT](http://www.wireless-tag.com/wireless_module/BLE/WT51822-S4AT.html) * [WT51822-S4AT](http://www.wireless-tag.com/wireless_module/BLE/WT51822-S4AT.html)
* nRF52832 * nRF52832
* [PCA10040](http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52%2Fdita%2Fnrf52%2Fdevelopment%2Fnrf52_dev_kit.html) * [PCA10040](http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52%2Fdita%2Fnrf52%2Fdevelopment%2Fnrf52_dev_kit.html)
* [Adafruit Feather nRF52](https://www.adafruit.com/product/3406) * [Adafruit Feather nRF52](https://www.adafruit.com/product/3406)
* [Thingy:52](http://www.nordicsemi.com/eng/Products/Nordic-Thingy-52) * [Thingy:52](http://www.nordicsemi.com/eng/Products/Nordic-Thingy-52)
* [Arduino Primo](http://www.arduino.org/products/boards/arduino-primo) * [Arduino Primo](http://www.arduino.org/products/boards/arduino-primo)
@ -38,6 +38,7 @@ This is a port of MicroPython to the Nordic Semiconductor nRF series of chips.
* [BLUEIO-TAG-EVIM BLYST Nano Sensor board](https://www.crowdsupply.com/i-syst/blyst-nano) * [BLUEIO-TAG-EVIM BLYST Nano Sensor board](https://www.crowdsupply.com/i-syst/blyst-nano)
* nRF52840 * nRF52840
* [PCA10056](http://www.nordicsemi.com/eng/Products/nRF52840-Preview-DK) * [PCA10056](http://www.nordicsemi.com/eng/Products/nRF52840-Preview-DK)
* [Particle Xenon](https://docs.particle.io/xenon/)
## Compile and Flash ## Compile and Flash
@ -71,7 +72,7 @@ the compilation:
GNU ARM Embedded Toolchain 7.2.1/4Q17. It's recommended to use a toolchain after GNU ARM Embedded Toolchain 7.2.1/4Q17. It's recommended to use a toolchain after
this release, for example 7.3.1/2Q18 or 8.2.1/4Q18. The alternative would be to this release, for example 7.3.1/2Q18 or 8.2.1/4Q18. The alternative would be to
build the target using the LTO=0 as described above. build the target using the LTO=0 as described above.
## Compile and Flash with Bluetooth Stack ## Compile and Flash with Bluetooth Stack
First prepare the bluetooth folder by downloading Bluetooth LE stacks and headers: First prepare the bluetooth folder by downloading Bluetooth LE stacks and headers:
@ -126,6 +127,7 @@ ibk_blyst_nano | s132 | Peripheral and Central | [IDAP]
idk_blyst_nano | s132 | Peripheral and Central | [IDAP](#idap-midap-link-targets) idk_blyst_nano | s132 | Peripheral and Central | [IDAP](#idap-midap-link-targets)
blueio_tag_evim | s132 | Peripheral and Central | [IDAP](#idap-midap-link-targets) blueio_tag_evim | s132 | Peripheral and Central | [IDAP](#idap-midap-link-targets)
pca10056 | s140 | Peripheral and Central | [Segger](#segger-targets) pca10056 | s140 | Peripheral and Central | [Segger](#segger-targets)
particle_xenon | s140 | Peripheral and Central | [Black Magic Probe](#black-magic-probe-targets)
## IDAP-M/IDAP-Link Targets ## IDAP-M/IDAP-Link Targets
@ -153,6 +155,14 @@ Install the necessary tools to flash and debug using OpenOCD:
sudo apt-get install openocd sudo apt-get install openocd
sudo pip install pyOCD sudo pip install pyOCD
## Black Magic Probe Targets
This requires no further dependencies other than `arm-none-eabi-gdb`.
`make deploy` will use gdb to load and run new firmware. See
[this guide](https://github.com/blacksphere/blackmagic/wiki/Useful-GDB-commands)
for more tips about using the BMP with GDB.
## Bluetooth LE REPL ## Bluetooth LE REPL
The port also implements a BLE REPL driver. This feature is disabled by default, as it will deactivate the UART REPL when activated. As some of the nRF devices only have one UART, using the BLE REPL free's the UART instance such that it can be used as a general UART peripheral not bound to REPL. The port also implements a BLE REPL driver. This feature is disabled by default, as it will deactivate the UART REPL when activated. As some of the nRF devices only have one UART, using the BLE REPL free's the UART instance such that it can be used as a general UART peripheral not bound to REPL.

View File

@ -16,7 +16,7 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
_etext = .; /* define a global symbol at end of code */ _etext = .; /* define a global symbol at end of code */
} >FLASH_TEXT } >FLASH_TEXT
/* /*
.ARM.extab : .ARM.extab :
{ {
@ -30,10 +30,10 @@ SECTIONS
__exidx_end = .; __exidx_end = .;
} >FLASH } >FLASH
*/ */
/* used by the startup to initialize data */ /* used by the startup to initialize data */
_sidata = LOADADDR(.data); _sidata = LOADADDR(.data);
/* This is the initialized data section /* This is the initialized data section
The program executes knowing that the data is in the RAM The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata). but the loader puts the initial values in the FLASH (inidata).
@ -49,7 +49,7 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */ _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM AT>FLASH_TEXT } >RAM AT>FLASH_TEXT
/* Uninitialized data section */ /* Uninitialized data section */
.bss : .bss :
{ {

View File

@ -93,6 +93,7 @@ class Pin(object):
self.adc_num = 0 self.adc_num = 0
self.adc_channel = 0 self.adc_channel = 0
self.board_pin = False self.board_pin = False
self.board_index = None
def cpu_pin_name(self): def cpu_pin_name(self):
return '{:s}{:d}'.format("P", self.pin) return '{:s}{:d}'.format("P", self.pin)
@ -103,6 +104,9 @@ class Pin(object):
def set_is_board_pin(self): def set_is_board_pin(self):
self.board_pin = True self.board_pin = True
def set_board_index(self, index):
self.board_index = index
def parse_adc(self, adc_str): def parse_adc(self, adc_str):
if (adc_str[:3] != 'ADC'): if (adc_str[:3] != 'ADC'):
return return
@ -233,20 +237,24 @@ class Pins(object):
def print_named(self, label, named_pins): def print_named(self, label, named_pins):
print('STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label)) print('STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
index = 0
for named_pin in named_pins: for named_pin in named_pins:
pin = named_pin.pin() pin = named_pin.pin()
if pin.is_board_pin(): if pin.is_board_pin():
print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&machine_pin_obj[{:d}]) }},'.format(named_pin.name(), index)) print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&machine_board_pin_obj[{:d}]) }},'.format(named_pin.name(), pin.board_index))
index += 1
print('};') print('};')
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label)); print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
def print_const_table(self): def print_const_table(self):
num_board_pins = 0
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if pin.is_board_pin():
pin.set_board_index(num_board_pins)
num_board_pins += 1
print('') print('')
print('const uint8_t machine_pin_num_of_pins = {:d};'.format(len(self.board_pins))) print('const uint8_t machine_pin_num_of_board_pins = {:d};'.format(num_board_pins))
print('') print('')
print('const pin_obj_t machine_pin_obj[{:d}] = {{'.format(len(self.board_pins))) print('const pin_obj_t machine_board_pin_obj[{:d}] = {{'.format(num_board_pins))
for named_pin in self.cpu_pins: for named_pin in self.cpu_pins:
pin = named_pin.pin() pin = named_pin.pin()
if pin.is_board_pin(): if pin.is_board_pin():

View File

@ -256,15 +256,15 @@ static const uint16_t render_timings[] =
// The scale is (approximately) exponential, // The scale is (approximately) exponential,
// each step is approx x1.9 greater than the previous. // each step is approx x1.9 greater than the previous.
{ 0, // Bright, Ticks Duration, Relative power { 0, // Bright, Ticks Duration, Relative power
2, // 1, 2, 32µs, inf 2, // 1, 2, 32us, inf
2, // 2, 4, 64µs, 200% 2, // 2, 4, 64us, 200%
4, // 3, 8, 128µs, 200% 4, // 3, 8, 128us, 200%
7, // 4, 15, 240µs, 187% 7, // 4, 15, 240us, 187%
13, // 5, 28, 448µs, 187% 13, // 5, 28, 448us, 187%
25, // 6, 53, 848µs, 189% 25, // 6, 53, 848us, 189%
49, // 7, 102, 1632µs, 192% 49, // 7, 102, 1632us, 192%
97, // 8, 199, 3184µs, 195% 97, // 8, 199, 3184us, 195%
// Always on 9, 375, 6000µs, 188% // Always on 9, 375, 6000us, 188%
}; };
#define DISPLAY_TICKER_SLOT 1 #define DISPLAY_TICKER_SLOT 1
@ -281,7 +281,7 @@ static int32_t callback(void) {
return -1; return -1;
} }
display->previous_brightness = brightness; display->previous_brightness = brightness;
// Return interval (in 16µs ticks) until next callback // Return interval (in 16us ticks) until next callback
return render_timings[brightness]; return render_timings[brightness];
} }

View File

@ -62,7 +62,7 @@ STATIC void microbit_image_print(const mp_print_t *print, mp_obj_t self_in, mp_p
uint8_t monochromeGetPixelValue(monochrome_5by5_t * p_mono, mp_int_t x, mp_int_t y) { uint8_t monochromeGetPixelValue(monochrome_5by5_t * p_mono, mp_int_t x, mp_int_t y) {
unsigned int index = y*5+x; unsigned int index = y*5+x;
if (index == 24) if (index == 24)
return p_mono->pixel44; return p_mono->pixel44;
return (p_mono->bits24[index>>3] >> (index&7))&1; return (p_mono->bits24[index>>3] >> (index&7))&1;
} }
@ -380,7 +380,7 @@ mp_obj_t microbit_image_set_pixel(mp_uint_t n_args, const mp_obj_t *args) {
mp_raise_ValueError("index cannot be negative"); mp_raise_ValueError("index cannot be negative");
} }
mp_int_t bright = mp_obj_get_int(args[3]); mp_int_t bright = mp_obj_get_int(args[3]);
if (bright < 0 || bright > MAX_BRIGHTNESS) if (bright < 0 || bright > MAX_BRIGHTNESS)
mp_raise_ValueError("brightness out of bounds."); mp_raise_ValueError("brightness out of bounds.");
if (x < imageWidth(self) && y < imageHeight(self)) { if (x < imageWidth(self) && y < imageHeight(self)) {
greyscaleSetPixelValue(&(self->greyscale), x, y, bright); greyscaleSetPixelValue(&(self->greyscale), x, y, bright);
@ -610,7 +610,7 @@ microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_float_t f
#else #else
microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_int_t fval) { microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_int_t fval) {
#endif #endif
if (fval < 0) if (fval < 0)
mp_raise_ValueError("Brightness multiplier must not be negative."); mp_raise_ValueError("Brightness multiplier must not be negative.");
greyscale_t *result = greyscale_new(imageWidth(lhs), imageHeight(lhs)); greyscale_t *result = greyscale_new(imageWidth(lhs), imageHeight(lhs));
for (int x = 0; x < imageWidth(lhs); ++x) { for (int x = 0; x < imageWidth(lhs); ++x) {
@ -639,7 +639,7 @@ microbit_image_obj_t *microbit_image_sum(microbit_image_obj_t *lhs, microbit_ima
int val; int val;
int lval = imageGetPixelValue(lhs, x,y); int lval = imageGetPixelValue(lhs, x,y);
int rval = imageGetPixelValue(rhs, x,y); int rval = imageGetPixelValue(rhs, x,y);
if (add) if (add)
val = min(lval + rval, MAX_BRIGHTNESS); val = min(lval + rval, MAX_BRIGHTNESS);
else else
val = max(0, lval - rval); val = max(0, lval - rval);
@ -647,7 +647,7 @@ microbit_image_obj_t *microbit_image_sum(microbit_image_obj_t *lhs, microbit_ima
} }
} }
return (microbit_image_obj_t *)result; return (microbit_image_obj_t *)result;
} }
STATIC mp_obj_t image_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { STATIC mp_obj_t image_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
if (mp_obj_get_type(lhs_in) != &microbit_image_type) { if (mp_obj_get_type(lhs_in) != &microbit_image_type) {
@ -697,9 +697,9 @@ const mp_obj_type_t microbit_image_type = {
.buffer_p = {NULL}, .buffer_p = {NULL},
.locals_dict = (mp_obj_dict_t*)&microbit_image_locals_dict, .locals_dict = (mp_obj_dict_t*)&microbit_image_locals_dict,
}; };
typedef struct _scrolling_string_t { typedef struct _scrolling_string_t {
mp_obj_base_t base; mp_obj_base_t base;
char const *str; char const *str;
mp_uint_t len; mp_uint_t len;
mp_obj_t ref; mp_obj_t ref;
@ -708,7 +708,7 @@ typedef struct _scrolling_string_t {
} scrolling_string_t; } scrolling_string_t;
typedef struct _scrolling_string_iterator_t { typedef struct _scrolling_string_iterator_t {
mp_obj_base_t base; mp_obj_base_t base;
mp_obj_t ref; mp_obj_t ref;
greyscale_t *img; greyscale_t *img;
char const *next_char; char const *next_char;
@ -962,7 +962,7 @@ const mp_obj_type_t microbit_facade_iterator_type = {
}; };
mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf) { mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf) {
(void)iter_buf; (void)iter_buf;
facade_iterator_t *result = m_new_obj(facade_iterator_t); facade_iterator_t *result = m_new_obj(facade_iterator_t);
string_image_facade_t *iterable = (string_image_facade_t *)iterable_in; string_image_facade_t *iterable = (string_image_facade_t *)iterable_in;
result->base.type = &microbit_facade_iterator_type; result->base.type = &microbit_facade_iterator_type;

View File

@ -2,15 +2,15 @@
#define __MICROPY_INCLUDED_MICROBIT_IMAGE_H__ #define __MICROPY_INCLUDED_MICROBIT_IMAGE_H__
#include "py/runtime.h" #include "py/runtime.h"
#define MAX_BRIGHTNESS 9 #define MAX_BRIGHTNESS 9
/** Monochrome images are immutable, which means that /** Monochrome images are immutable, which means that
* we only need one bit per pixel which saves quite a lot * we only need one bit per pixel which saves quite a lot
* of memory */ * of memory */
/* we reserve a couple of bits, so we won't need to modify the /* we reserve a couple of bits, so we won't need to modify the
* layout if we need to add more functionality or subtypes. */ * layout if we need to add more functionality or subtypes. */
#define TYPE_AND_FLAGS \ #define TYPE_AND_FLAGS \
mp_obj_base_t base; \ mp_obj_base_t base; \
uint8_t five:1; \ uint8_t five:1; \

View File

@ -0,0 +1,70 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Jim Mussared
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define MICROPY_HW_BOARD_NAME "XENON"
#define MICROPY_HW_MCU_NAME "NRF52840"
#define MICROPY_PY_SYS_PLATFORM "PARTICLE-XENON"
#define MICROPY_PY_MACHINE_UART (1)
#define MICROPY_PY_MACHINE_HW_PWM (1)
#define MICROPY_PY_MACHINE_HW_SPI (1)
#define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_PY_MACHINE_RTCOUNTER (1)
#define MICROPY_PY_MACHINE_I2C (1)
#define MICROPY_PY_MACHINE_ADC (1)
#define MICROPY_PY_MACHINE_TEMP (1)
#define MICROPY_PY_RANDOM_HW_RNG (1)
#define MICROPY_HW_HAS_LED (1)
#define MICROPY_HW_LED_TRICOLOR (1)
#define MICROPY_HW_LED_PULLUP (1)
#define MICROPY_HW_LED_RED (13) // LED1
#define MICROPY_HW_LED_GREEN (14) // LED2
#define MICROPY_HW_LED_BLUE (15) // LED3
// UART config
#define MICROPY_HW_UART1_RX (8)
#define MICROPY_HW_UART1_TX (6)
#define MICROPY_HW_UART1_CTS (32+2)
#define MICROPY_HW_UART1_RTS (32+1)
#define MICROPY_HW_UART1_HWFC (0)
// SPI0 config
#define MICROPY_HW_SPI0_NAME "SPI0"
#define MICROPY_HW_SPI0_SCK (32+15)
#define MICROPY_HW_SPI0_MOSI (32+13)
#define MICROPY_HW_SPI0_MISO (32+14)
#define MICROPY_HW_PWM0_NAME "PWM0"
#define MICROPY_HW_PWM1_NAME "PWM1"
#define MICROPY_HW_PWM2_NAME "PWM2"
#if 0
#define MICROPY_HW_PWM3_NAME "PWM3"
#endif
#define HELP_TEXT_BOARD_LED "1,2,3"

View File

@ -0,0 +1,7 @@
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52840
SOFTDEV_VERSION = 6.1.1
LD_FILES += boards/nrf52840_1M_256k.ld
NRF_DEFINES += -DNRF52840_XXAA

View File

@ -0,0 +1,38 @@
LED1,P13
LED2,P14
LED3,P15
A0,P3,ADC0_IN1
A1,P4,ADC0_IN2
A2,P28,ADC0_IN4
A3,P29,ADC0_IN5
A4,P30,ADC0_IN6
A5,P31,ADC0_IN7
SPI_SS,P31
SPI_SCK,P47
SPI_MOSI,P45
SPI_MISO,P46
SPI1_SCK,P33
SPI1_MOSI,P34
SPI1_MISO,P40
UART1_RX,P8
UART1_TX,P6
UART2_RX,P42
UART2_TX,P40
SDA,P26
SCL,P27
SDA1,P33
SCL1,P34
D0,P26
D1,P27
D2,P33
D3,P34
D4,P40
D5,P42
D6,P43
D7,P44
D8,P35
D9,P6
D10,P8
D11,P46
D12,P45
D13,P47
1 LED1,P13
2 LED2,P14
3 LED3,P15
4 A0,P3,ADC0_IN1
5 A1,P4,ADC0_IN2
6 A2,P28,ADC0_IN4
7 A3,P29,ADC0_IN5
8 A4,P30,ADC0_IN6
9 A5,P31,ADC0_IN7
10 SPI_SS,P31
11 SPI_SCK,P47
12 SPI_MOSI,P45
13 SPI_MISO,P46
14 SPI1_SCK,P33
15 SPI1_MOSI,P34
16 SPI1_MISO,P40
17 UART1_RX,P8
18 UART1_TX,P6
19 UART2_RX,P42
20 UART2_TX,P40
21 SDA,P26
22 SCL,P27
23 SDA1,P33
24 SCL1,P34
25 D0,P26
26 D1,P27
27 D2,P33
28 D3,P34
29 D4,P40
30 D5,P42
31 D6,P43
32 D7,P44
33 D8,P35
34 D9,P6
35 D10,P8
36 D11,P46
37 D12,P45
38 D13,P47

View File

@ -48,8 +48,8 @@ void Reset_Handler(void) {
// RAM on in on-mode // RAM on in on-mode
*ram_on_addr = 3; // block 0 and 1 *ram_on_addr = 3; // block 0 and 1
*ram_on_b_addr = 3; // block 2 and 3 *ram_on_b_addr = 3; // block 2 and 3
#if 0 #if 0
// RAM on in off-mode // RAM on in off-mode
ram_on_addr = 1 << 16; ram_on_addr = 1 << 16;
ram_on_b_addr = 1 << 17; ram_on_b_addr = 1 << 17;
#endif #endif

View File

@ -418,7 +418,7 @@ bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
p_adv_params->p_device_name, p_adv_params->p_device_name,
p_adv_params->device_name_len) != 0) { p_adv_params->device_name_len) != 0) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
"Can not apply device name in the stack.")); "Can not apply device name in the stack."));
} }
BLE_DRIVER_LOG("Device name applied\n"); BLE_DRIVER_LOG("Device name applied\n");

View File

@ -190,7 +190,7 @@ void ble_uart_init0(void) {
ble_uart_char_tx.service_handle = ble_uart_service.handle; ble_uart_char_tx.service_handle = ble_uart_service.handle;
bool retval = ble_drv_characteristic_add(&ble_uart_char_tx); bool retval = ble_drv_characteristic_add(&ble_uart_char_tx);
if (retval) { if (retval) {
ble_uart_char_tx.p_service = &ble_uart_service; ble_uart_char_tx.p_service = &ble_uart_service;
} }
mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_tx)); mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_tx));
@ -198,7 +198,7 @@ void ble_uart_init0(void) {
ble_uart_char_rx.service_handle = ble_uart_service.handle; ble_uart_char_rx.service_handle = ble_uart_service.handle;
retval = ble_drv_characteristic_add(&ble_uart_char_rx); retval = ble_drv_characteristic_add(&ble_uart_char_rx);
if (retval) { if (retval) {
ble_uart_char_rx.p_service = &ble_uart_service; ble_uart_char_rx.p_service = &ble_uart_service;
} }
mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_rx)); mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_rx));

View File

@ -35,7 +35,7 @@
#define __MICROPY_INCLUDED_LIB_TICKER_H__ #define __MICROPY_INCLUDED_LIB_TICKER_H__
/************************************* /*************************************
* 62.5kHz (16µs cycle time) ticker. * 62.5kHz (16us cycle time) ticker.
************************************/ ************************************/
#include "nrf.h" #include "nrf.h"

View File

@ -28,6 +28,6 @@
#include "lib/oofatfs/ff.h" #include "lib/oofatfs/ff.h"
DWORD get_fattime(void) { DWORD get_fattime(void) {
// TODO: Implement this function. For now, fake it. // TODO: Implement this function. For now, fake it.
return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2);
} }

View File

@ -81,7 +81,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
if (nlr_push(&nlr) == 0) { if (nlr_push(&nlr) == 0) {
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t pn = mp_parse(lex, input_kind); mp_parse_tree_t pn = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&pn, source_name, MP_EMIT_OPT_NONE, true); mp_obj_t module_fun = mp_compile(&pn, source_name, true);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
} else { } else {
@ -94,7 +94,7 @@ extern uint32_t _heap_start;
extern uint32_t _heap_end; extern uint32_t _heap_end;
int main(int argc, char **argv) { int main(int argc, char **argv) {
soft_reset: soft_reset:
mp_stack_set_top(&_ram_end); mp_stack_set_top(&_ram_end);
@ -185,8 +185,8 @@ pin_init0();
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
// use SD card as current directory // use SD card as current directory
f_chdrive("/sd"); f_chdrive("/sd");
} }
no_mem_for_sd:; no_mem_for_sd:;
} }
@ -293,18 +293,17 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
void HardFault_Handler(void) void HardFault_Handler(void)
{ {
#if defined(NRF52_SERIES) #if defined(NRF52_SERIES)
static volatile uint32_t reg; static volatile uint32_t reg;
static volatile uint32_t reg2; static volatile uint32_t reg2;
static volatile uint32_t bfar; static volatile uint32_t bfar;
reg = SCB->HFSR; reg = SCB->HFSR;
reg2 = SCB->CFSR; reg2 = SCB->CFSR;
bfar = SCB->BFAR; bfar = SCB->BFAR;
for (int i = 0; i < 0; i++) for (int i = 0; i < 0; i++) {
{ (void)reg;
(void)reg; (void)reg2;
(void)reg2; (void)bfar;
(void)bfar; }
}
#endif #endif
} }

View File

@ -39,7 +39,7 @@
" ble.enabled() -- check whether bluetooth stack is enabled\n" \ " ble.enabled() -- check whether bluetooth stack is enabled\n" \
" ble.address() -- return device address as text string\n" \ " ble.address() -- return device address as text string\n" \
"\n" "\n"
#else #else
#define HELP_TEXT_SD #define HELP_TEXT_SD
#endif // MICROPY_PY_BLE #endif // MICROPY_PY_BLE

View File

@ -91,10 +91,19 @@ void adc_init0(void) {
} }
STATIC int adc_find(mp_obj_t id) { STATIC int adc_find(mp_obj_t id) {
// given an integer id int adc_idx;
int adc_id = mp_obj_get_int(id); if (mp_obj_is_int(id)) {
// Given an integer id
int adc_idx = adc_id; adc_idx = mp_obj_get_int(id);
} else {
// Assume it's a pin-compatible object and convert it to an ADC channel number
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(id);
if (pin->adc_num & PIN_ADC1) {
adc_idx = pin->adc_channel;
} else {
mp_raise_ValueError("invalid Pin for ADC");
}
}
if (adc_idx >= 0 && adc_idx < MP_ARRAY_SIZE(machine_adc_obj) if (adc_idx >= 0 && adc_idx < MP_ARRAY_SIZE(machine_adc_obj)
&& machine_adc_obj[adc_idx].id != (uint8_t)-1) { && machine_adc_obj[adc_idx].id != (uint8_t)-1) {
@ -137,7 +146,7 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
.acq_time = NRF_SAADC_ACQTIME_3US, .acq_time = NRF_SAADC_ACQTIME_3US,
.mode = NRF_SAADC_MODE_SINGLE_ENDED, .mode = NRF_SAADC_MODE_SINGLE_ENDED,
.burst = NRF_SAADC_BURST_DISABLED, .burst = NRF_SAADC_BURST_DISABLED,
.pin_p = self->id, // 0 - 7 .pin_p = 1 + self->id, // pin_p=0 is AIN0, pin_p=8 is AIN7
.pin_n = NRF_SAADC_INPUT_DISABLED .pin_n = NRF_SAADC_INPUT_DISABLED
}; };
@ -169,6 +178,20 @@ int16_t machine_adc_value_read(machine_adc_obj_t * adc_obj) {
return value; return value;
} }
// read_u16()
STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) {
machine_adc_obj_t *self = self_in;
int16_t raw = machine_adc_value_read(self);
#if defined(NRF52_SERIES)
// raw is signed but the channel is in single-ended mode and this method cannot return negative values
if (raw < 0) {
raw = 0;
}
#endif
// raw is an 8-bit value
return MP_OBJ_NEW_SMALL_INT(raw << 8 | raw);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_adc_read_u16_obj, machine_adc_read_u16);
/// \method value() /// \method value()
/// Read adc level. /// Read adc level.
@ -263,6 +286,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_machine_adc_battery_level_obj, machine_adc_b
STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = {
// instance methods // instance methods
{ MP_ROM_QSTR(MP_QSTR_read_u16), MP_ROM_PTR(&mp_machine_adc_read_u16_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&mp_machine_adc_value_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&mp_machine_adc_value_obj) },
// class methods // class methods

View File

@ -37,8 +37,8 @@
#include "nrf_gpio.h" #include "nrf_gpio.h"
#include "nrfx_gpiote.h" #include "nrfx_gpiote.h"
extern const pin_obj_t machine_pin_obj[]; extern const pin_obj_t machine_board_pin_obj[];
extern const uint8_t machine_pin_num_of_pins; extern const uint8_t machine_pin_num_of_board_pins;
/// \moduleref machine /// \moduleref machine
/// \class Pin - control I/O pins /// \class Pin - control I/O pins
@ -127,12 +127,12 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
const pin_obj_t *pin_obj; const pin_obj_t *pin_obj;
// If pin is SMALL_INT // If pin is SMALL_INT
if (mp_obj_is_small_int(user_obj)) { if (mp_obj_is_small_int(user_obj)) {
uint8_t value = MP_OBJ_SMALL_INT_VALUE(user_obj); uint8_t value = MP_OBJ_SMALL_INT_VALUE(user_obj);
for (uint8_t i = 0; i < machine_pin_num_of_pins; i++) { for (uint8_t i = 0; i < machine_pin_num_of_board_pins; i++) {
if (machine_pin_obj[i].pin == value) { if (machine_board_pin_obj[i].pin == value) {
return &machine_pin_obj[i]; return &machine_board_pin_obj[i];
} }
} }
} }
// If a pin was provided, then use it // If a pin was provided, then use it
@ -364,8 +364,8 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, con
nrf_gpio_pin_dir_t mode = (nrf_gpio_pin_dir_t)args[0].u_int; nrf_gpio_pin_dir_t mode = (nrf_gpio_pin_dir_t)args[0].u_int;
// Connect input or not // Connect input or not
nrf_gpio_pin_input_t input = (mode == NRF_GPIO_PIN_DIR_INPUT) ? NRF_GPIO_PIN_INPUT_CONNECT nrf_gpio_pin_input_t input = (mode == NRF_GPIO_PIN_DIR_INPUT) ? NRF_GPIO_PIN_INPUT_CONNECT
: NRF_GPIO_PIN_INPUT_DISCONNECT; : NRF_GPIO_PIN_INPUT_DISCONNECT;
if (mode == NRF_GPIO_PIN_DIR_OUTPUT || mode == NRF_GPIO_PIN_DIR_INPUT) { if (mode == NRF_GPIO_PIN_DIR_OUTPUT || mode == NRF_GPIO_PIN_DIR_INPUT) {
nrf_gpio_cfg(self->pin, nrf_gpio_cfg(self->pin,
@ -496,7 +496,7 @@ STATIC void pin_common_irq_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t
} }
STATIC mp_obj_t pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum {ARG_handler, ARG_trigger, ARG_wake}; enum {ARG_handler, ARG_trigger, ARG_wake};
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_handler, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = mp_const_none} }, { MP_QSTR_handler, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = mp_const_none} },
{ MP_QSTR_trigger, MP_ARG_INT, {.u_int = NRF_GPIOTE_POLARITY_LOTOHI | NRF_GPIOTE_POLARITY_HITOLO} }, { MP_QSTR_trigger, MP_ARG_INT, {.u_int = NRF_GPIOTE_POLARITY_LOTOHI | NRF_GPIOTE_POLARITY_HITOLO} },

View File

@ -269,7 +269,7 @@ STATIC mp_obj_t machine_hard_pwm_make_new(mp_arg_val_t *args) {
} else { } else {
self->p_config->mode = MODE_HIGH_LOW; self->p_config->mode = MODE_HIGH_LOW;
} }
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }

View File

@ -154,9 +154,9 @@ STATIC int spi_find(mp_obj_t id) {
void spi_transfer(const machine_hard_spi_obj_t * self, size_t len, const void * src, void * dest) { void spi_transfer(const machine_hard_spi_obj_t * self, size_t len, const void * src, void * dest) {
nrfx_spi_xfer_desc_t xfer_desc = { nrfx_spi_xfer_desc_t xfer_desc = {
.p_tx_buffer = src, .p_tx_buffer = src,
.tx_length = len, .tx_length = len,
.p_rx_buffer = dest, .p_rx_buffer = dest,
.rx_length = len .rx_length = len
}; };
nrfx_spi_xfer(self->p_spi, &xfer_desc, 0); nrfx_spi_xfer(self->p_spi, &xfer_desc, 0);
@ -340,7 +340,7 @@ STATIC void machine_hard_spi_init(mp_obj_t self_in, mp_arg_val_t *args) {
// Active high // Active high
if (args[ARG_INIT_polarity].u_int == 0) { if (args[ARG_INIT_polarity].u_int == 0) {
if (args[ARG_INIT_phase].u_int == 0) { if (args[ARG_INIT_phase].u_int == 0) {
// First clock edge // First clock edge
self->p_config->mode = NRF_SPI_MODE_0; self->p_config->mode = NRF_SPI_MODE_0;
} else { } else {
@ -349,7 +349,7 @@ STATIC void machine_hard_spi_init(mp_obj_t self_in, mp_arg_val_t *args) {
} }
// Active low // Active low
} else { } else {
if (args[ARG_INIT_phase].u_int == 0) { if (args[ARG_INIT_phase].u_int == 0) {
// First clock edge // First clock edge
self->p_config->mode = NRF_SPI_MODE_2; self->p_config->mode = NRF_SPI_MODE_2;
} else { } else {

View File

@ -67,9 +67,9 @@ STATIC mp_obj_t machine_temp_make_new(const mp_obj_type_t *type, size_t n_args,
// parse args // parse args
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
machine_temp_obj_t *self = m_new_obj(machine_temp_obj_t); machine_temp_obj_t *self = m_new_obj(machine_temp_obj_t);
self->base.type = &machine_temp_type; self->base.type = &machine_temp_type;
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);

View File

@ -72,7 +72,7 @@ uint32_t machine_rng_generate_random_word(void) {
status = sd_rand_application_vector_get((uint8_t *)&retval, 4); // Extract 4 bytes status = sd_rand_application_vector_get((uint8_t *)&retval, 4); // Extract 4 bytes
} while (status != 0); } while (status != 0);
return retval; return retval;
} }
#endif #endif

View File

@ -72,7 +72,7 @@ STATIC const mp_rom_map_elem_t ubluepy_delegate_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_handleConnection), MP_ROM_PTR(&ubluepy_delegate_handle_conn_obj) }, { MP_ROM_QSTR(MP_QSTR_handleConnection), MP_ROM_PTR(&ubluepy_delegate_handle_conn_obj) },
{ MP_ROM_QSTR(MP_QSTR_handleNotification), MP_ROM_PTR(&ubluepy_delegate_handle_notif_obj) }, { MP_ROM_QSTR(MP_QSTR_handleNotification), MP_ROM_PTR(&ubluepy_delegate_handle_notif_obj) },
#if 0 #if 0
{ MP_ROM_QSTR(MP_QSTR_handleDiscovery), MP_ROM_PTR(&ubluepy_delegate_handle_disc_obj) }, { MP_ROM_QSTR(MP_QSTR_handleDiscovery), MP_ROM_PTR(&ubluepy_delegate_handle_disc_obj) },
#endif #endif
}; };

View File

@ -481,7 +481,7 @@ STATIC const mp_rom_map_elem_t ubluepy_peripheral_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) }, { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) },
#endif #endif
#if MICROPY_PY_UBLUEPY_OBSERVER #if MICROPY_PY_UBLUEPY_OBSERVER
// Nothing yet. // Nothing yet.
#endif #endif
}; };

View File

@ -162,7 +162,7 @@ STATIC const mp_rom_map_elem_t ubluepy_service_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_service_add_char_obj) }, { MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_service_add_char_obj) },
{ MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_service_get_chars_obj) }, { MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_service_get_chars_obj) },
#if 0 #if 0
// Properties // Properties
{ MP_ROM_QSTR(MP_QSTR_peripheral), MP_ROM_PTR(&ubluepy_service_get_peripheral_obj) }, { MP_ROM_QSTR(MP_QSTR_peripheral), MP_ROM_PTR(&ubluepy_service_get_peripheral_obj) },
#endif #endif
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&ubluepy_service_get_uuid_obj) }, { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&ubluepy_service_get_uuid_obj) },

View File

@ -42,7 +42,7 @@ typedef enum
} HAL_StatusTypeDef; } HAL_StatusTypeDef;
static inline uint32_t hal_tick_fake(void) { static inline uint32_t hal_tick_fake(void) {
return 0; return 0;
} }
#define mp_hal_ticks_ms hal_tick_fake // TODO: implement. Right now, return 0 always #define mp_hal_ticks_ms hal_tick_fake // TODO: implement. Right now, return 0 always

View File

@ -1,9 +1,9 @@
P0,P0 P0,P0
P1,P1 P1,P1
P2,P2 P2,P2,ADC1_CH0
P3,P3 P3,P3,ADC1_CH1
P4,P4 P4,P4,ADC1_CH2
P5,P5 P5,P5,ADC1_CH3
P6,P6 P6,P6
P7,P7 P7,P7
P8,P8 P8,P8
@ -26,10 +26,10 @@ P24,P24
P25,P25 P25,P25
P26,P26 P26,P26
P27,P27 P27,P27
P28,P28 P28,P28,ADC1_CH4
P29,P29 P29,P29,ADC1_CH5
P30,P30 P30,P30,ADC1_CH6
P31,P31 P31,P31,ADC1_CH7
P32,P32 P32,P32
P33,P33 P33,P33
P34,P34 P34,P34

1 P0 P0,P0 P0
2 P1 P1,P1 P1
3 P2 P2,P2,ADC1_CH0 P2
4 P3 P3,P3,ADC1_CH1 P3
5 P4 P4,P4,ADC1_CH2 P4
6 P5 P5,P5,ADC1_CH3 P5
7 P6 P6,P6 P6
8 P7 P7,P7 P7
9 P8 P8,P8 P8
26 P25 P25,P25 P25
27 P26 P26,P26 P26
28 P27 P27,P27 P27
29 P28 P28,P28,ADC1_CH4 P28
30 P29 P29,P29,ADC1_CH5 P29
31 P30 P30,P30,ADC1_CH6 P30
32 P31 P31,P31,ADC1_CH7 P31
33 P32 P32,P32 P32
34 P33 P33,P33 P33
35 P34 P34,P34 P34

View File

@ -53,9 +53,12 @@ enum {
}; };
#define PIN_DEFS_PORT_AF_UNION \ #define PIN_DEFS_PORT_AF_UNION \
NRF_UART_Type *UART; NRF_UART_Type *UART;
// NRF_SPI_Type *SPIM; // NRF_SPI_Type *SPIM;
// NRF_SPIS_Type *SPIS; // NRF_SPIS_Type *SPIS;
enum {
PIN_ADC1 = (1 << 0),
};
typedef NRF_GPIO_Type pin_gpio_t; typedef NRF_GPIO_Type pin_gpio_t;

View File

@ -114,6 +114,14 @@ OBJ = $(OBJ_COMMON) $(OBJ_RUN) $(OBJ_TEST)
# List of sources for qstr extraction # List of sources for qstr extraction
SRC_QSTR += $(SRC_COMMON_C) $(SRC_RUN_C) $(LIB_SRC_C) SRC_QSTR += $(SRC_COMMON_C) $(SRC_RUN_C) $(LIB_SRC_C)
ifneq ($(FROZEN_MPY_DIR),)
# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and
# then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch).
CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
MPY_CROSS_FLAGS += -march=armv7m
endif
all: run all: run
run: $(BUILD)/firmware.elf run: $(BUILD)/firmware.elf

View File

@ -1,5 +1,7 @@
LIB_SRC_C = lib/upytesthelper/upytesthelper.c LIB_SRC_C = lib/upytesthelper/upytesthelper.c
FROZEN_MPY_DIR ?= test-frzmpy
include Makefile include Makefile
CFLAGS += -DTEST CFLAGS += -DTEST
@ -8,7 +10,7 @@ CFLAGS += -DTEST
$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h $(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h
$(BUILD)/genhdr/tests.h: $(BUILD)/genhdr/tests.h:
(cd $(TOP)/tests; ./run-tests --write-exp) (cd $(TOP)/tests; ./run-tests --target=qemu-arm --write-exp)
$(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@ $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@
$(BUILD)/tinytest.o: $(BUILD)/tinytest.o:
@ -18,7 +20,8 @@ $(BUILD)/firmware-test.elf: $(OBJ_COMMON) $(OBJ_TEST)
$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
$(Q)$(SIZE) $@ $(Q)$(SIZE) $@
# Note: Using timeout(1) to handle cases where qemu hangs (e.g. this can happen with alignment errors).
test: $(BUILD)/firmware-test.elf test: $(BUILD)/firmware-test.elf
qemu-system-arm -machine $(BOARD) $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out timeout --foreground -k 5s 30s qemu-system-arm -machine $(BOARD) $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out
$(Q)tail -n2 $(BUILD)/console.out $(Q)tail -n2 $(BUILD)/console.out
$(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" $(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0"

View File

@ -18,7 +18,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name; qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true);
mp_call_function_0(module_fun); mp_call_function_0(module_fun);
nlr_pop(); nlr_pop();
} else { } else {

View File

@ -0,0 +1,13 @@
import micropython
@micropython.native
def native_x(x):
print(x + 1)
@micropython.native
def native_y(x):
print(x + 1)
@micropython.native
def native_z(x):
print(x + 1)

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