pull/10620/head
peterhinch 2023-01-29 18:10:48 +00:00
commit 9ac577f0d0
131 zmienionych plików z 2473 dodań i 1052 usunięć

Wyświetl plik

@ -28,7 +28,7 @@ jobs:
- name: Build
run: source tools/ci.sh && ci_code_size_build
- name: Compute code size difference
run: tools/metrics.py diff ~/size0 ~/size1 | tee > diff
run: tools/metrics.py diff ~/size0 ~/size1 | tee diff
- name: Save PR number
if: github.event_name == 'pull_request'
env:

Wyświetl plik

@ -20,6 +20,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build
run: make -C examples/embedding
run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding
- name: Run
run: test "$(./examples/embedding/hello-embed)" = "Hello world of easy embedding!"
run: ./examples/embedding/embed | grep "hello world"

Wyświetl plik

@ -65,16 +65,52 @@ changes to the correct style. Without arguments this tool will reformat all
source code (and may take some time to run). Otherwise pass as arguments to
the tool the files that changed and it will only reformat those.
**Important**: Use only [uncrustify](https://github.com/uncrustify/uncrustify)
v0.71 or v0.72 for MicroPython. Different uncrustify versions produce slightly
different formatting, and the configuration file formats are often incompatible.
uncrustify
==========
Only [uncrustify](https://github.com/uncrustify/uncrustify) v0.71 or v0.72 can
be used for MicroPython. Different uncrustify versions produce slightly
different formatting, and the configuration file formats are often
incompatible. v0.73 or newer *will not work*.
Depending on your operating system version, it may be possible to install a pre-compiled
uncrustify version:
Ubuntu, Debian
--------------
Ubuntu versions 21.10 or 22.04LTS, and Debian versions bullseye or bookworm all
include v0.72 so can be installed directly:
```
$ apt install uncrustify
```
Arch Linux
----------
The current Arch uncrustify version is too new. There is an [old Arch package
for v0.72](https://archive.archlinux.org/packages/u/uncrustify/) that can be
installed from the Arch Linux archive ([more
information](https://wiki.archlinux.org/title/Downgrading_packages#Arch_Linux_Archive)). Use
the [IgnorePkg feature](https://wiki.archlinux.org/title/Pacman#Skip_package_from_being_upgraded)
to prevent it re-updating.
Brew
----
This command may work, please raise a new Issue if it doesn't:
```
brew install https://github.com/Homebrew/homebrew-core/raw/2b07d8192623365078a8b855a164ebcdf81494a6/Formula/uncrustify.rb
```
Automatic Pre-Commit Hooks
==========================
To have code formatting and commit message conventions automatically checked,
a configuration file is provided for the [pre-commit]
(https://pre-commit.com/) tool.
a configuration file is provided for the [pre-commit](https://pre-commit.com/)
tool.
First install `pre-commit`, either from your system package manager or via
`pip`. When installing `pre-commit` via pip, it is recommended to use a
@ -82,13 +118,17 @@ virtual environment. Other sources, such as Brew are also available, see
[the docs](https://pre-commit.com/index.html#install) for details.
```
$ apt install pre-commit # Ubuntu
$ apt install pre-commit # Ubuntu, Debian
$ pacman -Sy python-precommit # Arch Linux
$ brew install pre-commit # Brew
$ pip install pre-commit # PyPI
```
Then inside the MicroPython repository, register the git hooks for pre-commit
Next, install [uncrustify (see above)](#uncrustify). Other dependencies are managed by
pre-commit automatically, but uncrustify needs to be installed and available on
the PATH.
Then, inside the MicroPython repository, register the git hooks for pre-commit
by running:
```
@ -115,7 +155,6 @@ Tips:
* To ignore the pre-commit message format check temporarily, start the commit
message subject line with "WIP" (for "Work In Progress").
Python code conventions
=======================

Wyświetl plik

@ -68,6 +68,9 @@ by reading the temperature sensor immediately after waking up from sleep.
Networking
----------
WLAN
^^^^
The :mod:`network` module::
import network
@ -110,6 +113,67 @@ calling ``wlan.config(reconnects=n)``, where n are the number of desired reconne
attempts (0 means it won't retry, -1 will restore the default behaviour of trying
to reconnect forever).
LAN
^^^
To use the wired interfaces one has to specify the pins and mode ::
import network
lan = network.LAN(mdc=PIN_MDC, ...) # Set the pin and mode configuration
lan.active(True) # activate the interface
lan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
The keyword arguments for the constructor defining the PHY type and interface are:
- mdc=pin-object # set the mdc and mdio pins.
- mdio=pin-object
- power=pin-object # set the pin which switches the power of the PHY device.
- phy_type=<type> # Select the PHY device type. Supported devices are PHY_LAN8710,
PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041
- phy_addr=number # The address number of the PHY device.
- ref_clk_mode=mode # Defines, whether the ref_clk at the ESP32 is an input
or output. Suitable values are Pin.IN and Pin.OUT.
- ref_clk=pin-object # defines the Pin used for ref_clk.
The options ref_clk_mode and ref_clk require at least esp-idf version 4.4. For
earlier esp-idf versions, these parameters must be defined by kconfig board options.
These are working configurations for LAN interfaces of popular boards::
# Olimex ESP32-GATEWAY: power controlled by Pin(5)
# Olimex ESP32 PoE and ESP32-PoE ISO: power controlled by Pin(12)
lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5),
phy_type=network.PHY_LAN8720, phy_addr=0)
# or with dynamic ref_clk pin configuration
lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5),
phy_type=network.PHY_LAN8720, phy_addr=0,
ref_clk=machine.Pin(17), ref_clk_mode=machine.Pin.OUT)
# Wireless-Tag's WT32-ETH01
lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18),
phy_type=network.PHY_LAN8720, phy_addr=1, power=None)
# Espressif ESP32-Ethernet-Kit_A_V1.2
lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5),
phy_type=network.PHY_IP101, phy_addr=1)
A suitable definition of the PHY interface in a sdkconfig.board file is::
CONFIG_ETH_PHY_INTERFACE_RMII=y
CONFIG_ETH_RMII_CLK_OUTPUT=y
CONFIG_ETH_RMII_CLK_OUT_GPIO=17
CONFIG_LWIP_LOCAL_HOSTNAME="ESP32_POE"
The value assigned to CONFIG_ETH_RMII_CLK_OUT_GPIO may vary depending on the
board's wiring.
Delay and timing
----------------

Wyświetl plik

@ -38,13 +38,16 @@ Constructors
Methods
-------
.. method:: Timer.init(*, mode=Timer.PERIODIC, period=-1, callback=None)
.. method:: Timer.init(*, mode=Timer.PERIODIC, freq=-1, period=-1, callback=None)
Initialise the timer. Example::
def mycallback(t):
pass
# periodic at 1kHz
tim.init(mode=Timer.PERIODIC, freq=1000, callback=mycallback)
# periodic with 100ms period
tim.init(period=100, callback=mycallback)
@ -60,6 +63,11 @@ Methods
- ``Timer.PERIODIC`` - The timer runs periodically at the configured
frequency of the channel.
- ``freq`` - The timer frequency, in units of Hz. The upper bound of
the frequency is dependent on the port. When both the ``freq`` and
``period`` arguments are given, ``freq`` has a higher priority and
``period`` is ignored.
- ``period`` - The timer period, in milliseconds.
- ``callback`` - The callable to call upon expiration of the timer period.

Wyświetl plik

@ -99,13 +99,17 @@ Methods
.. method:: StateMachine.put(value, shift=0)
Push a word onto the state machine's TX FIFO.
Push words onto the state machine's TX FIFO.
If the FIFO is full, it blocks until there is space (i.e. the state machine
pulls a word).
*value* can be an integer, an array of type ``B``, ``H`` or ``I``, or a
`bytearray`.
The value is first shifted left by *shift* bits, i.e. the state machine
receives ``value << shift``.
This method will block until all words have been written to the FIFO. If
the FIFO is, or becomes, full, the method will block until the state machine
pulls enough words to complete the write.
Each word is first shifted left by *shift* bits, i.e. the state machine
receives ``word << shift``.
.. method:: StateMachine.rx_fifo()

Wyświetl plik

@ -29,7 +29,7 @@ returned by `getaddrinfo` function, which must be used to resolve textual addres
# You must use getaddrinfo() even for numeric addresses
sockaddr = socket.getaddrinfo('127.0.0.1', 80)[0][-1]
# Now you can use that address
sock.connect(addr)
sock.connect(sockaddr)
Using `getaddrinfo` is the most efficient (both in terms of memory and processing
power) and portable way to work with addresses.

Wyświetl plik

@ -392,6 +392,8 @@ Symbol Meaning
F float
B byte code
M module
S string or bytes
A bytearray
====== =================
Each letter represents a single block of memory, a block being 16 bytes. So each

Wyświetl plik

@ -76,9 +76,10 @@ and state machines. Below is the code for reference.
nop() [29]
jmp(x_dec, "delay_high")
# Cycles: 1 + 7 + 32 * (30 + 1) = 1000
# Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
nop()
set(pins, 0)
set(x, 31) [6]
set(x, 31) [5]
label("delay_low")
nop() [29]
jmp(x_dec, "delay_low")
@ -113,6 +114,8 @@ the following:
X starts with the value 31 this jump will happen 31 times, so the ``nop() [29]``
runs 32 times in total (note there is also one instruction cycle taken by the
``jmp`` for each of these 32 loops).
- The single ``nop()`` correlates with the cycle used for IRQ raise, and ensures
the same number of cycles are used for LED on and LED off.
- ``set(pins, 0)`` will turn the LED off by setting pin 25 low.
- Another 32 loops of ``nop() [29]`` and ``jmp(...)`` will execute.
- Because ``wrap_target()`` and ``wrap()`` are not specified, their default will

Wyświetl plik

@ -151,7 +151,7 @@ Use the :ref:`zsensor.Sensor <zsensor.Sensor>` class to access sensor data::
accel.measure() # obtain a measurement reading from the accelerometer
# each of these prints the value taken by measure()
accel.float(zsensor.ACCEL_X) # print measurement value for accelerometer X-axis sensor channel as float
accel.millis(zsensor.ACCEL_Y) # print measurement value for accelerometer Y-axis sensor channel in millionths
accel.micro(zsensor.ACCEL_Z) # print measurement value for accelerometer Z-axis sensor channel in thousandths
accel.int(zsensor.ACCEL_X) # print measurement integer value only for accelerometer X-axis sensor channel
accel.get_float(zsensor.ACCEL_X) # print measurement value for accelerometer X-axis sensor channel as float
accel.get_millis(zsensor.ACCEL_Y) # print measurement value for accelerometer Y-axis sensor channel in millionths
accel.get_micro(zsensor.ACCEL_Z) # print measurement value for accelerometer Z-axis sensor channel in thousandths
accel.get_int(zsensor.ACCEL_X) # print measurement integer value only for accelerometer X-axis sensor channel

Wyświetl plik

@ -0,0 +1,92 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
*
* 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 <stdio.h>
#include <string.h>
#include "py/runtime.h"
#include "py/mphal.h"
#if defined(MICROPY_PY_NETWORK_NINAW10) && defined(MICROPY_HW_PIN_EXT_COUNT)
#include "modmachine.h"
#include "machine_pin.h"
#include "nina_wifi_drv.h"
#define NINA_GPIO_INPUT (0x00)
#define NINA_GPIO_OUTPUT (0x01)
#define NINA_GPIO_INPUT_PULLUP (0x02)
#define NINA_GPIO_MODE (0x50)
#define NINA_GPIO_READ (0x53)
#define NINA_GPIO_WRITE (0x51)
static uint8_t pin_map[MICROPY_HW_PIN_EXT_COUNT] = {
27, // LEDR
25, // LEDG
26, // LEDB
36, // A6
35, // A7
};
void machine_pin_ext_init(void) {
nina_init();
}
void machine_pin_ext_set(machine_pin_obj_t *self, bool value) {
if (self->id >= 0 && self->id < MICROPY_HW_PIN_EXT_COUNT) {
uint8_t buf[] = {pin_map[self->id], value};
nina_ioctl(NINA_GPIO_WRITE, sizeof(buf), buf, 0);
}
}
bool machine_pin_ext_get(machine_pin_obj_t *self) {
bool value = false;
if (self->id >= 0 && self->id < MICROPY_HW_PIN_EXT_COUNT) {
uint8_t buf[] = {pin_map[self->id]};
nina_ioctl(NINA_GPIO_READ, sizeof(buf), buf, 0);
}
return value;
}
void machine_pin_ext_config(machine_pin_obj_t *self, int mode, int value) {
if (mode == MACHINE_PIN_MODE_IN) {
mode = NINA_GPIO_INPUT;
self->is_output = false;
} else if (mode == MACHINE_PIN_MODE_OUT) {
mode = NINA_GPIO_OUTPUT;
self->is_output = true;
machine_pin_ext_set(self, value);
} else {
mp_raise_ValueError("only Pin.OUT and Pin.IN are supported for this pin");
}
if (self->id >= 0 && self->id < MICROPY_HW_PIN_EXT_COUNT) {
uint8_t buf[] = {pin_map[self->id], mode};
nina_ioctl(NINA_GPIO_MODE, sizeof(buf), buf, 0);
}
}
#endif // defined(MICROPY_PY_NETWORK_NINAW10) && defined(MICROPY_HW_PIN_EXT_COUNT)

Wyświetl plik

@ -1,8 +1,25 @@
MPTOP = ../..
CFLAGS += -std=c99 -I. -I$(MPTOP) -DNO_QSTR
LDFLAGS += -L./build
# This file is part of the MicroPython project, http://micropython.org/
# The MIT License (MIT)
# Copyright (c) 2022-2023 Damien P. George
#
# This is a very simple makefile that demonstrates how to build the embed port.
# All it needs to do is build all *.c files in the micropython_embed directory.
# This makefile would be replaced with your custom build system.
hello-embed: hello-embed.o -lmicropython
EMBED_DIR = micropython_embed
PROG = embed
-lmicropython:
$(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP)
CFLAGS += -I.
CFLAGS += -I$(EMBED_DIR)
CFLAGS += -I$(EMBED_DIR)/port
CFLAGS += -Wall -Og
SRC += main.c
SRC += $(wildcard $(EMBED_DIR)/*/*.c) $(wildcard $(EMBED_DIR)/*/*/*.c)
OBJ += $(SRC:.c=.o)
$(PROG): $(OBJ)
$(CC) -o $@ $^
clean:
/bin/rm -f $(OBJ) $(PROG)

Wyświetl plik

@ -1,184 +0,0 @@
MPTOP = ../..
-include mpconfigport.mk
include $(MPTOP)/py/mkenv.mk
all: lib
# OS name, for simple autoconfig
UNAME_S := $(shell uname -s)
# include py core make definitions
include $(MPTOP)/py/py.mk
include $(MPTOP)/extmod/extmod.mk
INC += -I.
INC += -I..
INC += -I$(MPTOP)
INC += -I$(MPTOP)/ports/unix
INC += -I$(BUILD)
# compiler settings
CWARN = -Wall -Werror
CWARN += -Wpointer-arith -Wuninitialized
CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
# Some systems (eg MacOS) need -fno-common so that mp_state_ctx is placed in the BSS.
CFLAGS += -fno-common
# Debugging/Optimization
ifdef DEBUG
CFLAGS += -g
COPT = -O0
else
COPT = -Os #-DNDEBUG
# _FORTIFY_SOURCE is a feature in gcc/glibc which is intended to provide extra
# security for detecting buffer overflows. Some distros (Ubuntu at the very least)
# have it enabled by default.
#
# gcc already optimizes some printf calls to call puts and/or putchar. When
# _FORTIFY_SOURCE is enabled and compiling with -O1 or greater, then some
# printf calls will also be optimized to call __printf_chk (in glibc). Any
# printfs which get redirected to __printf_chk are then no longer synchronized
# with printfs that go through mp_printf.
#
# In MicroPython, we don't want to use the runtime library's printf but rather
# go through mp_printf, so that stdout is properly tied into streams, etc.
# This means that we either need to turn off _FORTIFY_SOURCE or provide our
# own implementation of __printf_chk. We've chosen to turn off _FORTIFY_SOURCE.
# It should also be noted that the use of printf in MicroPython is typically
# quite limited anyways (primarily for debug and some error reporting, etc
# in the unix version).
#
# Information about _FORTIFY_SOURCE seems to be rather scarce. The best I could
# find was this: https://securityblog.redhat.com/2014/03/26/fortify-and-you/
# Original patchset was introduced by
# https://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html .
#
# Turning off _FORTIFY_SOURCE is only required when compiling with -O1 or greater
CFLAGS += -U _FORTIFY_SOURCE
endif
# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed.
# The unix port of MicroPython on OSX must be compiled with clang,
# while cross-compile ports require gcc, so we test here for OSX and
# if necessary override the value of 'CC' set in py/mkenv.mk
ifeq ($(UNAME_S),Darwin)
CC = clang
# Use clang syntax for map file
LDFLAGS_ARCH = -Wl,-map,$@.map
else
# Use gcc syntax for map file
LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref
endif
LDFLAGS += $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA)
ifeq ($(MICROPY_FORCE_32BIT),1)
# Note: you may need to install i386 versions of dependency packages,
# starting with linux-libc-dev:i386
ifeq ($(MICROPY_PY_FFI),1)
ifeq ($(UNAME_S),Linux)
CFLAGS_MOD += -I/usr/include/i686-linux-gnu
endif
endif
endif
ifeq ($(MICROPY_USE_READLINE),1)
INC += -I$(MPTOP)/shared/readline
CFLAGS_MOD += -DMICROPY_USE_READLINE=1
SHARED_SRC_C_EXTRA += readline/readline.c
endif
ifeq ($(MICROPY_USE_READLINE),2)
CFLAGS_MOD += -DMICROPY_USE_READLINE=2
LDFLAGS_MOD += -lreadline
# the following is needed for BSD
#LDFLAGS_MOD += -ltermcap
endif
ifeq ($(MICROPY_PY_TIME),1)
CFLAGS_MOD += -DMICROPY_PY_TIME=1
SRC_MOD += modtime.c
endif
ifeq ($(MICROPY_PY_TERMIOS),1)
CFLAGS_MOD += -DMICROPY_PY_TERMIOS=1
SRC_MOD += modtermios.c
endif
ifeq ($(MICROPY_PY_SOCKET),1)
CFLAGS_MOD += -DMICROPY_PY_SOCKET=1
SRC_MOD += modsocket.c
endif
ifeq ($(MICROPY_PY_FFI),1)
ifeq ($(MICROPY_STANDALONE),1)
LIBFFI_CFLAGS_MOD := -I$(shell ls -1d $(MPTOP)/lib/libffi/build_dir/out/lib/libffi-*/include)
ifeq ($(MICROPY_FORCE_32BIT),1)
LIBFFI_LDFLAGS_MOD = $(MPTOP)/lib/libffi/build_dir/out/lib32/libffi.a
else
LIBFFI_LDFLAGS_MOD = $(MPTOP)/lib/libffi/build_dir/out/lib/libffi.a
endif
else
LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi)
LIBFFI_LDFLAGS_MOD := $(shell pkg-config --libs libffi)
endif
ifeq ($(UNAME_S),Linux)
LIBFFI_LDFLAGS_MOD += -ldl
endif
CFLAGS_MOD += $(LIBFFI_CFLAGS_MOD) -DMICROPY_PY_FFI=1
LDFLAGS_MOD += $(LIBFFI_LDFLAGS_MOD)
SRC_MOD += modffi.c
endif
MAIN_C = main.c
# source files
SRC_C = $(addprefix ports/unix/,\
$(MAIN_C) \
gccollect.c \
unix_mphal.c \
input.c \
modmachine.c \
moduselect.c \
alloc.c \
coverage.c \
fatfs_port.c \
$(SRC_MOD) \
)
SHARED_SRC_C = $(addprefix shared/,\
libc/printf.c \
runtime/gchelper_generic.c \
timeutils/timeutils.c \
$(SHARED_SRC_C_EXTRA) \
)
OBJ = $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o))
# List of sources for qstr extraction
SRC_QSTR += $(SRC_C) $(SHARED_SRC_C)
# Append any auto-generated sources that are needed by sources listed in
# SRC_QSTR
SRC_QSTR_AUTO_DEPS +=
include $(MPTOP)/py/mkrules.mk
# Value of configure's --host= option (required for cross-compilation).
# Deduce it from CROSS_COMPILE by default, but can be overridden.
ifneq ($(CROSS_COMPILE),)
CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE))
else
CROSS_COMPILE_HOST =
endif
deplibs: libffi
# install-exec-recursive & install-data-am targets are used to avoid building
# docs and depending on makeinfo
libffi:
cd $(MPTOP)/lib/libffi; git clean -d -x -f
cd $(MPTOP)/lib/libffi; ./autogen.sh
mkdir -p $(MPTOP)/lib/libffi/build_dir; cd $(MPTOP)/lib/libffi/build_dir; \
../configure $(CROSS_COMPILE_HOST) --prefix=$$PWD/out CC="$(CC)" CXX="$(CXX)" LD="$(LD)"; \
make install-exec-recursive; make -C include install-data-am

Wyświetl plik

@ -1,67 +1,37 @@
Example of embedding MicroPython in a standalone C application
==============================================================
This directory contains a (very simple!) example of how to embed a MicroPython
in an existing C application.
A C application is represented by the file `hello-embed.c`. It executes a simple
Python statement which prints to the standard output.
This directory contains a simple example of how to embed MicroPython in an
existing C application.
A C application is represented here by the file `main.c`. It executes two
simple Python scripts which print things to the standard output.
Building the example
--------------------
Building the example is as simple as running:
First build the embed port using:
make
$ make -f micropython_embed.mk
It's worth to trace what's happening behind the scenes though:
This will generate the `micropython_embed` directory which is a self-contained
copy of MicroPython suitable for embedding. The .c files in this directory need
to be compiled into your project, in whatever way your project can do that. The
example here uses make and a provided `Makefile`.
1. As a first step, a MicroPython library is built. This is handled by a
separate makefile, `Makefile.upylib`. It is more or less complex, but the
good news is that you won't need to change anything in it, just use it
as is, the main `Makefile` shows how. What may require editing though is
a MicroPython configuration file. MicroPython is highly configurable, so
you would need to build a library suiting your application well, while
not bloating its size. Check the options in the file `mpconfigport.h`.
Included is a copy of the "minimal" Unix port, which should be a good start
for minimal embedding. For the list of all available options, see
`py/mpconfig.h`.
To build the example project, based on `main.c`, use:
2. Once the MicroPython library is built, your application is compiled
and linked it. The main Makefile is very simple and shows that the changes
you would need to do to your application's `Makefile` (or other build
configuration) are also simple:
$ make
a) You would need to use C99 standard (you're using this 15+ years old
standard already, not a 25+ years old one, right?).
b) You need to provide a path to MicroPython's top-level dir, for includes.
c) You need to include `-DNO_QSTR` compile-time flag.
d) Otherwise, just link with the MicroPython library produced in step 1.
That will create an exacutable called `embed` which you can run:
$ ./embed
Out of tree build
-----------------
This example is set up to work out of the box, being part of the MicroPython
tree. Your application of course will be outside of its tree, but the
only thing you need to do is to pass `MPTOP` variable pointing to
MicroPython directory to both Makefiles (in this example, the main Makefile
automatically passes it to `Makefile.upylib`; in your own Makefile, don't forget
to use a suitable value).
A practical way to embed MicroPython in your application is to include it
as a git submodule. Suppose you included it as `libs/micropython`. Then in
your main Makefile you would have something like:
~~~
MPTOP = libs/micropython
my_app: $(MY_OBJS) -lmicropython
-lmicropython:
$(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP)
~~~
tree. Your application will be outside of this tree, but the only thing you
need to do for that is to change `MICROPYTHON_TOP` (found in `micropython_embed.mk`)
to point to the location of the MicroPython repository. The MicroPython
repository may, for example, be a git submodule in your project.

Wyświetl plik

@ -1,76 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
*
* 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 <stdio.h>
#include <stdlib.h>
#include "py/builtin.h"
#include "py/compile.h"
#include "py/runtime.h"
#include "py/gc.h"
#include "py/stackctrl.h"
static char heap[16384];
mp_obj_t execute_from_str(const char *str) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
qstr src_name = 1/*MP_QSTR_*/;
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_obj_t module_fun = mp_compile(&pt, src_name, false);
mp_call_function_0(module_fun);
nlr_pop();
return 0;
} else {
// uncaught exception
return (mp_obj_t)nlr.ret_val;
}
}
int main() {
// Initialized stack limit
mp_stack_set_limit(40000 * (sizeof(void *) / 4));
// Initialize heap
gc_init(heap, heap + sizeof(heap));
// Initialize interpreter
mp_init();
const char str[] = "print('Hello world of easy embedding!')";
if (execute_from_str(str)) {
printf("Error\n");
}
}
uint mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught NLR %p\n", val);
exit(1);
}

Wyświetl plik

@ -0,0 +1,44 @@
/* This file is part of the MicroPython project, http://micropython.org/
* The MIT License (MIT)
* Copyright (c) 2022-2023 Damien P. George
*/
#include "port/micropython_embed.h"
// This is example 1 script, which will be compiled and executed.
static const char *example_1 =
"print('hello world!', list(x + 1 for x in range(10)), end='eol\\n')";
// This is example 2 script, which will be compiled and executed.
static const char *example_2 =
"for i in range(10):\n"
" print('iter {:08}'.format(i))\n"
"\n"
"try:\n"
" 1//0\n"
"except Exception as er:\n"
" print('caught exception', repr(er))\n"
"\n"
"import gc\n"
"print('run GC collect')\n"
"gc.collect()\n"
"\n"
"print('finish')\n"
;
// This array is the MicroPython GC heap.
static char heap[8 * 1024];
int main() {
// Initialise MicroPython.
mp_embed_init(&heap[0], sizeof(heap));
// Run the example scripts (they will be compiled first).
mp_embed_exec_str(example_1);
mp_embed_exec_str(example_2);
// Deinitialise MicroPython.
mp_embed_deinit();
return 0;
}

Wyświetl plik

@ -0,0 +1,9 @@
# This file is part of the MicroPython project, http://micropython.org/
# The MIT License (MIT)
# Copyright (c) 2022-2023 Damien P. George
# Set the location of the top of the MicroPython repository.
MICROPYTHON_TOP = ../..
# Include the main makefile fragment to build the MicroPython component.
include $(MICROPYTHON_TOP)/ports/embed/embed.mk

Wyświetl plik

@ -1 +1,15 @@
#include "mpconfigport_minimal.h"
/* This file is part of the MicroPython project, http://micropython.org/
* The MIT License (MIT)
* Copyright (c) 2022-2023 Damien P. George
*/
// Include common MicroPython embed configuration.
#include <port/mpconfigport_common.h>
// Use the minimal starting configuration (disables all optional features).
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM)
// MicroPython configuration.
#define MICROPY_ENABLE_COMPILER (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_PY_GC (1)

Wyświetl plik

@ -1,122 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2015 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.
*/
// options to control how MicroPython is built
#define MICROPY_ALLOC_PATH_MAX (PATH_MAX)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_FINALISER (0)
#define MICROPY_STACK_CHECK (0)
#define MICROPY_COMP_CONST (0)
#define MICROPY_MEM_STATS (0)
#define MICROPY_DEBUG_PRINTERS (0)
#define MICROPY_READER_POSIX (1)
#define MICROPY_KBD_EXCEPTION (1)
#define MICROPY_HELPER_REPL (1)
#define MICROPY_HELPER_LEXER_UNIX (1)
#define MICROPY_ENABLE_SOURCE_LINE (0)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
#define MICROPY_WARNINGS (0)
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
#define MICROPY_STREAMS_NON_BLOCK (0)
#define MICROPY_OPT_COMPUTED_GOTO (0)
#define MICROPY_CAN_OVERRIDE_BUILTINS (0)
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
#define MICROPY_CPYTHON_COMPAT (0)
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
#define MICROPY_PY_BUILTINS_COMPILE (0)
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
#define MICROPY_PY_BUILTINS_FILTER (0)
#define MICROPY_PY_BUILTINS_FROZENSET (0)
#define MICROPY_PY_BUILTINS_REVERSED (0)
#define MICROPY_PY_BUILTINS_SET (0)
#define MICROPY_PY_BUILTINS_SLICE (0)
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
#define MICROPY_PY_BUILTINS_PROPERTY (0)
#define MICROPY_PY_BUILTINS_MIN_MAX (0)
#define MICROPY_PY___FILE__ (0)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
#define MICROPY_PY_GC (0)
#define MICROPY_PY_GC_COLLECT_RETVAL (0)
#define MICROPY_PY_ARRAY (0)
#define MICROPY_PY_COLLECTIONS (0)
#define MICROPY_PY_MATH (0)
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_IO (0)
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_SYS (1)
#define MICROPY_PY_SYS_EXIT (0)
#define MICROPY_PY_SYS_PLATFORM "linux"
#define MICROPY_PY_SYS_MAXSIZE (0)
#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen"
#define MICROPY_PY_SYS_STDFILES (0)
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_UCTYPES (0)
#define MICROPY_PY_UZLIB (0)
#define MICROPY_PY_UJSON (0)
#define MICROPY_PY_UOS (1)
#define MICROPY_PY_URE (0)
#define MICROPY_PY_UHEAPQ (0)
#define MICROPY_PY_UHASHLIB (0)
#define MICROPY_PY_UBINASCII (0)
//////////////////////////////////////////
// Do not change anything beyond this line
//////////////////////////////////////////
#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__))
// Fall back to setjmp() implementation for discovery of GC pointers in registers.
#define MICROPY_GCREGS_SETJMP (1)
#endif
// type definitions for the specific machine
#ifdef __LP64__
typedef long mp_int_t; // must be pointer size
typedef unsigned long mp_uint_t; // must be pointer size
#else
// These are definitions for machines where sizeof(int) == sizeof(void*),
// regardless for actual size.
typedef int mp_int_t; // must be pointer size
typedef unsigned int mp_uint_t; // must be pointer size
#endif
// Cannot include <sys/types.h>, as it may lead to symbol name clashes
#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__)
typedef long long mp_off_t;
#else
typedef long mp_off_t;
#endif
// We need to provide a declaration/definition of alloca()
#ifdef __FreeBSD__
#include <stdlib.h>
#else
#include <alloca.h>
#endif

Wyświetl plik

@ -16,9 +16,10 @@ def blink_1hz():
nop() [29]
jmp(x_dec, "delay_high")
# Cycles: 1 + 7 + 32 * (30 + 1) = 1000
# Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
nop()
set(pins, 0)
set(x, 31) [6]
set(x, 31) [5]
label("delay_low")
nop() [29]
jmp(x_dec, "delay_low")

Wyświetl plik

@ -26,7 +26,11 @@
#ifndef AXTLS_OS_PORT_H
#define AXTLS_OS_PORT_H
#ifndef __ets__
#include <arpa/inet.h>
#endif
#include <errno.h>
#include <sys/time.h>
#include "py/stream.h"
#include "lib/crypto-algorithms/sha256.h"

Wyświetl plik

@ -6,7 +6,15 @@ int _re1_5_classmatch(const char *pc, const char *sp)
int is_positive = (pc[-1] == Class);
int cnt = *pc++;
while (cnt--) {
if (*sp >= *pc && *sp <= pc[1]) return is_positive;
if (*pc == RE15_CLASS_NAMED_CLASS_INDICATOR) {
if (_re1_5_namedclassmatch(pc + 1, sp)) {
return is_positive;
}
} else {
if (*sp >= *pc && *sp <= pc[1]) {
return is_positive;
}
}
pc += 2;
}
return !is_positive;

Wyświetl plik

@ -4,6 +4,9 @@
#include "re1.5.h"
// Matches: DSWdsw
#define MATCH_NAMED_CLASS_CHAR(c) (((c) | 0x20) == 'd' || ((c) | 0x24) == 'w')
#define INSERT_CODE(at, num, pc) \
((code ? memmove(code + at + num, code + at, pc - at) : 0), pc += num)
#define REL(at, to) (to - at - 2)
@ -31,7 +34,7 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
case '\\':
re++;
if (!*re) return NULL; // Trailing backslash
if ((*re | 0x20) == 'd' || (*re | 0x20) == 's' || (*re | 0x20) == 'w') {
if (MATCH_NAMED_CLASS_CHAR(*re)) {
term = PC;
EMIT(PC++, NamedClass);
EMIT(PC++, *re);
@ -63,14 +66,21 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
PC++; // Skip # of pair byte
prog->len++;
for (cnt = 0; *re != ']'; re++, cnt++) {
if (*re == '\\') {
char c = *re;
if (c == '\\') {
++re;
c = *re;
if (MATCH_NAMED_CLASS_CHAR(c)) {
c = RE15_CLASS_NAMED_CLASS_INDICATOR;
goto emit_char_pair;
}
}
if (!*re) return NULL;
EMIT(PC++, *re);
if (!c) return NULL;
if (re[1] == '-' && re[2] != ']') {
re += 2;
}
emit_char_pair:
EMIT(PC++, c);
EMIT(PC++, *re);
}
EMIT_CHECKED(term + 1, cnt);

Wyświetl plik

@ -138,6 +138,7 @@ struct Subject {
#define NON_ANCHORED_PREFIX 5
#define HANDLE_ANCHORED(bytecode, is_anchored) ((is_anchored) ? (bytecode) + NON_ANCHORED_PREFIX : (bytecode))
#define RE15_CLASS_NAMED_CLASS_INDICATOR 0
int re1_5_backtrack(ByteProg*, Subject*, const char**, int, int);
int re1_5_pikevm(ByteProg*, Subject*, const char**, int, int);

Wyświetl plik

@ -162,7 +162,7 @@ APP_STM_SRC_C = $(addprefix ports/stm32/,\
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(APP_FATFS_SRC_C:.c=.o) $(APP_RTOS_SRC_C:.c=.o) $(APP_FTP_SRC_C:.c=.o) $(APP_HAL_SRC_C:.c=.o) $(APP_MISC_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(APP_MODS_SRC_C:.c=.o) $(APP_CC3100_SRC_C:.c=.o) $(APP_SL_SRC_C:.c=.o) $(APP_TELNET_SRC_C:.c=.o) $(APP_UTIL_SRC_C:.c=.o) $(APP_UTIL_SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(APP_MAIN_SRC_C:.c=.o) $(APP_SHARED_SRC_C:.c=.o) $(APP_LIB_SRC_C:.c=.o) $(APP_STM_SRC_C:.c=.o))
OBJ += $(BUILD)/shared/runtime/gchelper_m3.o
OBJ += $(BUILD)/shared/runtime/gchelper_thumb2.o
OBJ += $(BUILD)/pins.o
# List of sources for qstr extraction

Wyświetl plik

@ -0,0 +1,18 @@
MicroPython embed port
======================
This is a port of MicroPython that outputs a set of .c and .h files for embedding
into a wider project. This port essentially targets the C language, instead of a
particular hardware architecture or platform.
To use this port in a project there are three main steps:
1. Provide configuration for the project via an `mpconfigport.h` file.
2. Build this embed port against that configuration, using the provided `embed.mk`.
The output is a set of self-contained source files for building MicroPython.
These files can be placed outside this repository.
3. Build the project. This requires compiling all .c files from the above step.
See `examples/embedding` for an example.

Wyświetl plik

@ -0,0 +1,65 @@
# This file is part of the MicroPython project, http://micropython.org/
# The MIT License (MIT)
# Copyright (c) 2022-2023 Damien P. George
#
# This file is intended to be included by a Makefile in a custom project.
# Set the build output directory for the generated files.
BUILD = build-embed
# Include the core environment definitions; this will set $(TOP).
include $(MICROPYTHON_TOP)/py/mkenv.mk
# Include py core make definitions.
include $(TOP)/py/py.mk
# Set the location of the MicroPython embed port.
MICROPYTHON_EMBED_PORT = $(MICROPYTHON_TOP)/ports/embed
# Set default makefile-level MicroPython feature configurations.
MICROPY_ROM_TEXT_COMPRESSION ?= 0
# Set CFLAGS for the MicroPython build.
CFLAGS += -I. -I$(TOP) -I$(BUILD) -I$(MICROPYTHON_EMBED_PORT)
CFLAGS += -Wall -Werror -std=c99
# Define the required generated header files.
GENHDR_OUTPUT = $(addprefix $(BUILD)/genhdr/, \
moduledefs.h \
mpversion.h \
qstrdefs.generated.h \
root_pointers.h \
)
# Define the top-level target, the generated output files.
.PHONY: all
all: micropython-embed-package
clean: clean-micropython-embed-package
.PHONY: clean-micropython-embed-package
clean-micropython-embed-package:
$(RM) -rf $(PACKAGE_DIR)
PACKAGE_DIR ?= micropython_embed
PACKAGE_DIR_LIST = $(addprefix $(PACKAGE_DIR)/,py extmod shared/runtime genhdr port)
.PHONY: micropython-embed-package
micropython-embed-package: $(GENHDR_OUTPUT)
$(ECHO) "Generate micropython_embed output:"
$(Q)$(RM) -rf $(PACKAGE_DIR_LIST)
$(Q)$(MKDIR) -p $(PACKAGE_DIR_LIST)
$(ECHO) "- py"
$(Q)$(CP) $(TOP)/py/*.[ch] $(PACKAGE_DIR)/py
$(ECHO) "- extmod"
$(Q)$(CP) $(TOP)/extmod/moduplatform.h $(PACKAGE_DIR)/extmod
$(ECHO) "- shared"
$(Q)$(CP) $(TOP)/shared/runtime/gchelper.h $(PACKAGE_DIR)/shared/runtime
$(Q)$(CP) $(TOP)/shared/runtime/gchelper_generic.c $(PACKAGE_DIR)/shared/runtime
$(ECHO) "- genhdr"
$(Q)$(CP) $(GENHDR_OUTPUT) $(PACKAGE_DIR)/genhdr
$(ECHO) "- port"
$(Q)$(CP) $(MICROPYTHON_EMBED_PORT)/port/*.[ch] $(PACKAGE_DIR)/port
# Include remaining core make rules.
include $(TOP)/py/mkrules.mk

Wyświetl plik

@ -0,0 +1,106 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 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/compile.h"
#include "py/gc.h"
#include "py/persistentcode.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "shared/runtime/gchelper.h"
#include "port/micropython_embed.h"
// Initialise the runtime.
void mp_embed_init(void *gc_heap, size_t gc_heap_size) {
mp_stack_ctrl_init();
gc_init(gc_heap, (uint8_t *)gc_heap + gc_heap_size);
mp_init();
}
#if MICROPY_ENABLE_COMPILER
// Compile and execute the given source script (Python text).
void mp_embed_exec_str(const char *src) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// Compile, parse and execute the given string.
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;
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true);
mp_call_function_0(module_fun);
nlr_pop();
} else {
// Uncaught exception: print it out.
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
#endif
#if MICROPY_PERSISTENT_CODE_LOAD
void mp_embed_exec_mpy(const uint8_t *mpy, size_t len) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// Execute the given .mpy data.
mp_module_context_t *ctx = m_new_obj(mp_module_context_t);
ctx->module.globals = mp_globals_get();
mp_compiled_module_t cm = mp_raw_code_load_mem(mpy, len, ctx);
mp_obj_t f = mp_make_function_from_raw_code(cm.rc, ctx, MP_OBJ_NULL);
mp_call_function_0(f);
nlr_pop();
} else {
// Uncaught exception: print it out.
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
#endif
// Deinitialise the runtime.
void mp_embed_deinit(void) {
mp_deinit();
}
#if MICROPY_ENABLE_GC
// Run a garbage collection cycle.
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
gc_collect_end();
}
#endif
// Called if an exception is raised outside all C exception-catching handlers.
void nlr_jump_fail(void *val) {
for (;;) {
}
}
#ifndef NDEBUG
// Used when debugging is enabled.
void __assert_func(const char *file, int line, const char *func, const char *expr) {
for (;;) {
}
}
#endif

Wyświetl plik

@ -0,0 +1,41 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 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.
*/
#ifndef MICROPY_INCLUDED_MICROPYTHON_EMBED_H
#define MICROPY_INCLUDED_MICROPYTHON_EMBED_H
#include <stddef.h>
#include <stdint.h>
void mp_embed_init(void *gc_heap, size_t gc_heap_size);
void mp_embed_deinit(void);
// Only available if MICROPY_ENABLE_COMPILER is enabled.
void mp_embed_exec_str(const char *src);
// Only available if MICROPY_PERSISTENT_CODE_LOAD is enabled.
void mp_embed_exec_mpy(const uint8_t *mpy, size_t len);
#endif // MICROPY_INCLUDED_MICROPYTHON_EMBED_H

Wyświetl plik

@ -0,0 +1,38 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 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 <stdint.h>
// Type definitions for the specific machine
typedef intptr_t mp_int_t; // must be pointer size
typedef uintptr_t mp_uint_t; // must be pointer size
typedef long mp_off_t;
// Need to provide a declaration/definition of alloca()
#include <alloca.h>
#define MICROPY_MPHALPORT_H "port/mphalport.h"

Wyświetl plik

@ -0,0 +1,33 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 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 <stdio.h>
#include "py/mphal.h"
// Send string of given length to stdout, converting \n to \r\n.
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
printf("%.*s", (int)len, str);
}

Wyświetl plik

@ -0,0 +1,2 @@
// Define so there's no dependency on extmod/virtpin.h
#define mp_hal_pin_obj_t

Wyświetl plik

@ -0,0 +1,19 @@
{
"deploy": [
"../deploy.md"
],
"docs": "",
"features": [
"BLE",
"WiFi"
],
"id": "esp32-unicore",
"images": [
"generic_unicore.jpg"
],
"mcu": "esp32",
"product": "ESP32 Unicore",
"thumbnail": "",
"url": "https://www.espressif.com/en/products/modules",
"vendor": "Espressif"
}

Wyświetl plik

@ -0,0 +1 @@
The following files are daily firmware for single-core ESP32-based boards without external SPIRAM.

Wyświetl plik

@ -0,0 +1,5 @@
set(SDKCONFIG_DEFAULTS
boards/sdkconfig.base
boards/sdkconfig.ble
boards/GENERIC_UNICORE/sdkconfig.board
)

Wyświetl plik

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

Wyświetl plik

@ -0,0 +1 @@
CONFIG_FREERTOS_UNICORE=y

Wyświetl plik

@ -0,0 +1,23 @@
{
"deploy": [
"../deploy.md"
],
"docs": "",
"features": [
"BLE",
"WiFi",
"MicroSD",
"Battery Charging",
"Ethernet",
"PoE",
"Breadboard friendly"
],
"images": [
"ESP32-POE-ISO-1.jpg"
],
"mcu": "esp32",
"product": "Olimex ESP32 POE",
"thumbnail": "",
"url": "https://www.olimex.com/",
"vendor": "OLIMEX"
}

Wyświetl plik

@ -0,0 +1,4 @@
The following files are daily firmware for Olimex ESP32 boards with Ethernet.
They match the boards ESP32 ETH-PoE, ESP32 ETH-PoE-ISO and ESP32 Gateway.
This firmware is compiled using ESP-IDF v4.x.

Wyświetl plik

@ -0,0 +1,5 @@
set(SDKCONFIG_DEFAULTS
boards/sdkconfig.base
boards/sdkconfig.ble
boards/OLIMEX_ESP32_POE/sdkconfig.board
)

Wyświetl plik

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

Wyświetl plik

@ -0,0 +1,4 @@
CONFIG_ETH_PHY_INTERFACE_RMII=y
CONFIG_ETH_RMII_CLK_OUTPUT=y
CONFIG_ETH_RMII_CLK_OUT_GPIO=17
CONFIG_LWIP_LOCAL_HOSTNAME="ESP32_POE"

Wyświetl plik

@ -533,6 +533,14 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
return MP_OBJ_FROM_PTR(self);
}
spi_host_device_t machine_hw_spi_get_host(mp_obj_t in) {
if (mp_obj_get_type(in) != &machine_spi_type) {
mp_raise_ValueError(MP_ERROR_TEXT("expecting a SPI object"));
}
machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t *)in;
return self->host;
}
STATIC const mp_machine_spi_p_t machine_hw_spi_p = {
.init = machine_hw_spi_init,
.deinit = machine_hw_spi_deinit,

Wyświetl plik

@ -211,7 +211,7 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
.gpio_cs = GPIO_NUM_34,
.gpio_cd = SDSPI_SLOT_NO_CD,
.gpio_wp = SDSPI_SLOT_NO_WP,
.dma_channel = 2
.dma_channel = SPI_DMA_CH_AUTO
},
SDSPI_SLOT_CONFIG_DEFAULT()
};

Wyświetl plik

@ -229,7 +229,7 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&get_wlan_obj) },
#endif
#if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32)
#if MICROPY_PY_NETWORK_LAN
{ MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&get_lan_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_PPP), MP_ROM_PTR(&ppp_make_new_obj) },
@ -260,7 +260,8 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_AUTH_MAX), MP_ROM_INT(WIFI_AUTH_MAX) },
#endif
#if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32)
#if MICROPY_PY_NETWORK_LAN
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8710), MP_ROM_INT(PHY_LAN8710) },
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) },
{ MP_ROM_QSTR(MP_QSTR_PHY_IP101), MP_ROM_INT(PHY_IP101) },
{ MP_ROM_QSTR(MP_QSTR_PHY_RTL8201), MP_ROM_INT(PHY_RTL8201) },
@ -269,6 +270,20 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
// PHY_KSZ8041 is new in ESP-IDF v4.3
{ MP_ROM_QSTR(MP_QSTR_PHY_KSZ8041), MP_ROM_INT(PHY_KSZ8041) },
#endif
#if ESP_IDF_VERSION_MINOR >= 4
// PHY_KSZ8081 is new in ESP-IDF v4.4
{ MP_ROM_QSTR(MP_QSTR_PHY_KSZ8081), MP_ROM_INT(PHY_KSZ8081) },
#endif
#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
{ MP_ROM_QSTR(MP_QSTR_PHY_KSZ8851SNL), MP_ROM_INT(PHY_KSZ8851SNL) },
#endif
#if CONFIG_ETH_SPI_ETHERNET_DM9051
{ MP_ROM_QSTR(MP_QSTR_PHY_DM9051), MP_ROM_INT(PHY_DM9051) },
#endif
#if CONFIG_ETH_SPI_ETHERNET_W5500
{ MP_ROM_QSTR(MP_QSTR_PHY_W5500), MP_ROM_INT(PHY_W5500) },
#endif
{ MP_ROM_QSTR(MP_QSTR_ETH_INITIALIZED), MP_ROM_INT(ETH_INITIALIZED)},
{ MP_ROM_QSTR(MP_QSTR_ETH_STARTED), MP_ROM_INT(ETH_STARTED)},

Wyświetl plik

@ -28,7 +28,8 @@
#include "esp_event.h"
enum { PHY_LAN8720, PHY_IP101, PHY_RTL8201, PHY_DP83848, PHY_KSZ8041 };
enum { PHY_LAN8710, PHY_LAN8720, PHY_IP101, PHY_RTL8201, PHY_DP83848, PHY_KSZ8041, PHY_KSZ8081, PHY_KSZ8851SNL = 100, PHY_DM9051, PHY_W5500 };
#define IS_SPI_PHY(NUM) (NUM >= 100)
enum { ETH_INITIALIZED, ETH_STARTED, ETH_STOPPED, ETH_CONNECTED, ETH_DISCONNECTED, ETH_GOT_IP };
// Cases similar to ESP8266 user_interface.h

Wyświetl plik

@ -217,3 +217,21 @@ typedef long mp_off_t;
#endif
void boardctrl_startup(void);
#ifndef MICROPY_PY_NETWORK_LAN
#if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32 || (CONFIG_ETH_USE_SPI_ETHERNET && (CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL || CONFIG_ETH_SPI_ETHERNET_DM9051 || CONFIG_ETH_SPI_ETHERNET_W5500)))
#define MICROPY_PY_NETWORK_LAN (1)
#else
#define MICROPY_PY_NETWORK_LAN (0)
#endif
#endif
#if MICROPY_PY_NETWORK_LAN && CONFIG_ETH_USE_SPI_ETHERNET
#ifndef MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
#define MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ (12)
#else
#define MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ (36)
#endif
#endif
#endif

Wyświetl plik

@ -35,6 +35,8 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#define MICROPY_PLATFORM_VERSION "IDF" IDF_VER
// The core that the MicroPython task(s) are pinned to.
@ -42,7 +44,9 @@
// and avoid the Wifi/BLE timing problems on the same core.
// Best effort here to remain backwards compatible in rare version edge cases...
// See https://github.com/micropython/micropython/issues/5489 for history
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
#if CONFIG_FREERTOS_UNICORE
#define MP_TASK_COREID (0)
#elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
#define MP_TASK_COREID (1)
#else
#define MP_TASK_COREID (0)
@ -111,4 +115,6 @@ static inline void mp_hal_pin_write(mp_hal_pin_obj_t pin, int v) {
gpio_set_level(pin, v);
}
spi_host_device_t machine_hw_spi_get_host(mp_obj_t in);
#endif // INCLUDED_MPHALPORT_H

Wyświetl plik

@ -33,13 +33,16 @@
#include "esp_idf_version.h"
// LAN only for ESP32 (not ESP32S2) and only for ESP-IDF v4.1 and higher
#if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32)
#if MICROPY_PY_NETWORK_LAN
#include "esp_eth.h"
#include "esp_eth_mac.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif
#include "modnetwork.h"
@ -48,9 +51,11 @@ typedef struct _lan_if_obj_t {
int if_id; // MUST BE FIRST to match wlan_if_obj_t
bool initialized;
bool active;
uint8_t mdc_pin;
uint8_t mdio_pin;
int8_t mdc_pin;
int8_t mdio_pin;
int8_t phy_power_pin;
int8_t phy_cs_pin;
int8_t phy_int_pin;
uint8_t phy_addr;
uint8_t phy_type;
esp_eth_phy_t *phy;
@ -97,14 +102,23 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
return MP_OBJ_FROM_PTR(&lan_obj);
}
enum { ARG_id, ARG_mdc, ARG_mdio, ARG_power, ARG_phy_addr, ARG_phy_type };
enum { ARG_id, ARG_mdc, ARG_mdio, ARG_power, ARG_phy_addr, ARG_phy_type,
ARG_spi, ARG_cs, ARG_int, ARG_ref_clk_mode, ARG_ref_clk };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_mdc, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_mdio, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_mdc, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_mdio, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_power, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_spi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_int, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
#if ESP_IDF_VERSION_MINOR >= 4
// Dynamic ref_clk configuration available at v4.4
{ MP_QSTR_ref_clk_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_ref_clk, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
#endif
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -116,36 +130,99 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
}
}
self->mdc_pin = machine_pin_get_id(args[ARG_mdc].u_obj);
self->mdio_pin = machine_pin_get_id(args[ARG_mdio].u_obj);
self->phy_power_pin = args[ARG_power].u_obj == mp_const_none ? -1 : machine_pin_get_id(args[ARG_power].u_obj);
#define GET_PIN(XXX) args[XXX].u_obj == mp_const_none ? -1 : machine_pin_get_id(args[XXX].u_obj);
self->mdc_pin = GET_PIN(ARG_mdc);
self->mdio_pin = GET_PIN(ARG_mdio);
self->phy_power_pin = GET_PIN(ARG_power);
self->phy_cs_pin = GET_PIN(ARG_cs);
self->phy_int_pin = GET_PIN(ARG_int);
if (args[ARG_phy_addr].u_int < 0x00 || args[ARG_phy_addr].u_int > 0x1f) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid phy address"));
}
self->phy_addr = args[ARG_phy_addr].u_int;
if (args[ARG_phy_type].u_int != PHY_LAN8720 &&
if (args[ARG_phy_type].u_int != PHY_LAN8710 &&
args[ARG_phy_type].u_int != PHY_LAN8720 &&
args[ARG_phy_type].u_int != PHY_IP101 &&
args[ARG_phy_type].u_int != PHY_RTL8201 &&
#if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
args[ARG_phy_type].u_int != PHY_KSZ8041 &&
#endif
#if ESP_IDF_VERSION_MINOR >= 4 // KSZ8081 is new in ESP-IDF v4.4
args[ARG_phy_type].u_int != PHY_KSZ8081 &&
#endif
#if CONFIG_ETH_USE_SPI_ETHERNET
#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
args[ARG_phy_type].u_int != PHY_KSZ8851SNL &&
#endif
#if CONFIG_ETH_SPI_ETHERNET_DM9051
args[ARG_phy_type].u_int != PHY_DM9051 &&
#endif
#if CONFIG_ETH_SPI_ETHERNET_W5500
args[ARG_phy_type].u_int != PHY_W5500 &&
#endif
#endif
args[ARG_phy_type].u_int != PHY_DP83848) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid phy type"));
}
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
mac_config.smi_mdc_gpio_num = self->mdc_pin;
mac_config.smi_mdio_gpio_num = self->mdio_pin;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
esp_eth_mac_t *mac = NULL;
// Dynamic ref_clk configuration available at v4.4
#if ESP_IDF_VERSION_MINOR >= 4
if (args[ARG_ref_clk_mode].u_int != -1) {
// Map the GPIO_MODE constants to EMAC_CLK constants.
mac_config.clock_config.rmii.clock_mode =
args[ARG_ref_clk_mode].u_int == GPIO_MODE_INPUT ? EMAC_CLK_EXT_IN : EMAC_CLK_OUT;
}
if (args[ARG_ref_clk].u_obj != mp_const_none) {
mac_config.clock_config.rmii.clock_gpio = machine_pin_get_id(args[ARG_ref_clk].u_obj);
}
#endif
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = self->phy_addr;
phy_config.reset_gpio_num = self->phy_power_pin;
self->phy = NULL;
#if CONFIG_ETH_USE_SPI_ETHERNET
spi_device_handle_t spi_handle = NULL;
if (IS_SPI_PHY(args[ARG_phy_type].u_int)) {
spi_device_interface_config_t devcfg = {
.mode = 0,
.clock_speed_hz = MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ * 1000 * 1000,
.queue_size = 20,
.spics_io_num = self->phy_cs_pin,
};
switch (args[ARG_phy_type].u_int) {
#if CONFIG_ETH_SPI_ETHERNET_DM9051
case PHY_DM9051: {
devcfg.command_bits = 1;
devcfg.address_bits = 7;
break;
}
#endif
#if CONFIG_ETH_SPI_ETHERNET_W5500
case PHY_W5500: {
devcfg.command_bits = 16;
devcfg.address_bits = 8;
break;
}
#endif
}
spi_host_device_t host = machine_hw_spi_get_host(args[ARG_spi].u_obj);
if (spi_bus_add_device(host, &devcfg, &spi_handle) != ESP_OK) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("spi_bus_add_device failed"));
}
}
#endif
switch (args[ARG_phy_type].u_int) {
#if CONFIG_IDF_TARGET_ESP32
case PHY_LAN8710:
case PHY_LAN8720:
self->phy = esp_eth_phy_new_lan8720(&phy_config);
break;
@ -158,15 +235,59 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
case PHY_DP83848:
self->phy = esp_eth_phy_new_dp83848(&phy_config);
break;
#if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
case PHY_KSZ8041:
#if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
self->phy = esp_eth_phy_new_ksz8041(&phy_config);
break;
#endif
default:
mp_raise_ValueError(MP_ERROR_TEXT("unknown phy"));
#endif
#if ESP_IDF_VERSION_MINOR >= 4 // KSZ8081 is new in ESP-IDF v4.4
case PHY_KSZ8081:
self->phy = esp_eth_phy_new_ksz8081(&phy_config);
break;
#endif
#endif
#if CONFIG_ETH_USE_SPI_ETHERNET
#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
case PHY_KSZ8851SNL: {
eth_ksz8851snl_config_t chip_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_handle);
chip_config.int_gpio_num = self->phy_int_pin;
mac = esp_eth_mac_new_ksz8851snl(&chip_config, &mac_config);
self->phy = esp_eth_phy_new_ksz8851snl(&phy_config);
break;
}
#endif
#if CONFIG_ETH_SPI_ETHERNET_DM9051
case PHY_DM9051: {
eth_dm9051_config_t chip_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
chip_config.int_gpio_num = self->phy_int_pin;
mac = esp_eth_mac_new_dm9051(&chip_config, &mac_config);
self->phy = esp_eth_phy_new_dm9051(&phy_config);
break;
}
#endif
#if CONFIG_ETH_SPI_ETHERNET_W5500
case PHY_W5500: {
eth_w5500_config_t chip_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
chip_config.int_gpio_num = self->phy_int_pin;
mac = esp_eth_mac_new_w5500(&chip_config, &mac_config);
self->phy = esp_eth_phy_new_w5500(&phy_config);
break;
}
#endif
#endif
}
#if CONFIG_IDF_TARGET_ESP32
if (!IS_SPI_PHY(args[ARG_phy_type].u_int)) {
if (self->mdc_pin == -1 || self->mdio_pin == -1) {
mp_raise_ValueError(MP_ERROR_TEXT("mdc and mdio must be specified"));
}
mac_config.smi_mdc_gpio_num = self->mdc_pin;
mac_config.smi_mdio_gpio_num = self->mdio_pin;
mac = esp_eth_mac_new_esp32(&mac_config);
}
#endif
if (esp_netif_init() != ESP_OK) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("esp_netif_init failed"));
}
@ -261,7 +382,12 @@ STATIC mp_obj_t lan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
if (bufinfo.len != 6) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid buffer length"));
}
esp_eth_ioctl(self->eth_handle, ETH_CMD_S_MAC_ADDR, bufinfo.buf);
if (
(esp_eth_ioctl(self->eth_handle, ETH_CMD_S_MAC_ADDR, bufinfo.buf) != ESP_OK) ||
(esp_netif_set_mac(self->eth_netif, bufinfo.buf) != ESP_OK)
) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed setting MAC address"));
}
break;
}
default:

Wyświetl plik

@ -35,6 +35,7 @@
#include "py/objlist.h"
#include "py/runtime.h"
#include "py/mphal.h"
#include "modnetwork.h"
#include "esp_wifi.h"
@ -210,6 +211,12 @@ STATIC mp_obj_t network_wlan_active(size_t n_args, const mp_obj_t *args) {
wifi_started = true;
}
}
// This delay is a band-aid patch for issues #8289, #8792 and #9236,
// allowing the esp data structures to settle. It looks like some
// kind of race condition, which is not yet found. But at least
// this small delay seems not hurt much, since wlan.active() is
// usually not called in a time critical part of the code.
mp_hal_delay_ms(1);
}
return (mode & bit) ? mp_const_true : mp_const_false;

Wyświetl plik

@ -1,10 +1,9 @@
MicroPython port to ESP8266
===========================
This is an experimental port of MicroPython for the WiFi modules based
on Espressif ESP8266 chip.
WARNING: The port is experimental and many APIs are subject to change.
This is a port of MicroPython to the Espressif ESP8266 WiFi microcontroller.
MicroPython runs on this chip without any underlying operating system, using
the ESP8266 NONOS SDK.
Supported features include:
- REPL (Python prompt) over UART0.

Wyświetl plik

@ -410,6 +410,11 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
wifi_set_phy_mode(mp_obj_get_int(kwargs->table[i].value));
break;
}
case MP_QSTR_txpower: {
int8_t power = mp_obj_get_float(kwargs->table[i].value) * 4;
system_phy_set_max_tpw(power);
break;
}
default:
goto unknown;
}

Wyświetl plik

@ -262,7 +262,7 @@ SRC_SS = \
$(MCU_DIR)/gcc/startup_$(MCU_SERIES)$(MCU_CORE).S \
hal/resethandler_MIMXRT10xx.S
SRC_S += shared/runtime/gchelper_m3.s \
SRC_S += shared/runtime/gchelper_thumb2.s \
# =============================================================================
# QSTR Sources

Wyświetl plik

@ -37,7 +37,11 @@ uint32_t trng_random_u32(void);
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES)
// Memory allocation policies
#if MICROPY_HW_SDRAM_AVAIL
#define MICROPY_GC_STACK_ENTRY_TYPE uint32_t
#else
#define MICROPY_GC_STACK_ENTRY_TYPE uint16_t
#endif
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (32)
#define MICROPY_ALLOC_PATH_MAX (256)

Wyświetl plik

@ -277,6 +277,11 @@ typedef int mp_int_t; // must be pointer size
typedef unsigned int mp_uint_t; // must be pointer size
typedef long mp_off_t;
#if MICROPY_HW_ENABLE_RNG
#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (rng_generate_random_word())
long unsigned int rng_generate_random_word(void);
#endif
#if BOARD_SPECIFIC_MODULES
#include "boardmodules.h"
#endif // BOARD_SPECIFIC_MODULES

Wyświetl plik

@ -17,7 +17,7 @@ ifeq ($(BOARD),netduino2)
CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft
CFLAGS += -DQEMU_SOC_STM32
LDSCRIPT = stm32.ld
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_m3.o
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o
MPY_CROSS_FLAGS += -march=armv7m
endif
@ -26,7 +26,7 @@ CFLAGS += -mthumb -mcpu=cortex-m0 -mfloat-abi=soft
CFLAGS += -DQEMU_SOC_NRF51
LDSCRIPT = nrf51.ld
QEMU_EXTRA = -global nrf51-soc.flash-size=1048576 -global nrf51-soc.sram-size=262144
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_m0.o
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb1.o
MPY_CROSS_FLAGS += -march=armv7m
endif
@ -34,7 +34,7 @@ ifeq ($(BOARD),mps2-an385)
CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft
CFLAGS += -DQEMU_SOC_MPS2
LDSCRIPT = mps2.ld
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_m3.o
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o
MPY_CROSS_FLAGS += -march=armv7m
endif

Wyświetl plik

@ -335,7 +335,7 @@ SRC_O += \
$(SYSTEM_FILE)
SRC_O += \
shared/runtime/gchelper_m3.o
shared/runtime/gchelper_thumb2.o
HAL_SRC_C += $(addprefix $(HAL_DIR)/ra/board/$(BOARD_LOW)/,\
board_init.c \

Wyświetl plik

@ -87,7 +87,7 @@ set(MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/netutils/netutils.c
${MICROPY_DIR}/shared/netutils/trace.c
${MICROPY_DIR}/shared/readline/readline.c
${MICROPY_DIR}/shared/runtime/gchelper_m0.s
${MICROPY_DIR}/shared/runtime/gchelper_thumb1.s
${MICROPY_DIR}/shared/runtime/gchelper_native.c
${MICROPY_DIR}/shared/runtime/interrupt_char.c
${MICROPY_DIR}/shared/runtime/mpirq.c
@ -131,6 +131,7 @@ set(MICROPY_SOURCE_PORT
usbd.c
msc_disk.c
mbedtls/mbedtls_port.c
${CMAKE_BINARY_DIR}/pins_${MICROPY_BOARD}.c
)
set(MICROPY_SOURCE_QSTR
@ -153,6 +154,7 @@ set(MICROPY_SOURCE_QSTR
${PROJECT_SOURCE_DIR}/modutime.c
${PROJECT_SOURCE_DIR}/rp2_flash.c
${PROJECT_SOURCE_DIR}/rp2_pio.c
${CMAKE_BINARY_DIR}/pins_${MICROPY_BOARD}.c
)
set(PICO_SDK_COMPONENTS
@ -257,6 +259,10 @@ if (MICROPY_PY_NETWORK_CYW43)
)
endif()
list(APPEND MICROPY_SOURCE_PORT
machine_pin_cyw43.c
)
list(APPEND MICROPY_SOURCE_EXTMOD
${MICROPY_DIR}/extmod/network_cyw43.c
)
@ -281,6 +287,7 @@ if (MICROPY_PY_NETWORK_NINAW10)
${MICROPY_DIR}/drivers/ninaw10/nina_bt_hci.c
${MICROPY_DIR}/drivers/ninaw10/nina_wifi_drv.c
${MICROPY_DIR}/drivers/ninaw10/nina_wifi_bsp.c
${MICROPY_DIR}/drivers/ninaw10/machine_pin_nina.c
)
list(APPEND MICROPY_SOURCE_EXTMOD
@ -435,3 +442,37 @@ endforeach()
# Include the main MicroPython cmake rules.
include(${MICROPY_DIR}/py/mkrules.cmake)
set(MICROPY_BOARDS_DIR "${MICROPY_PORT_DIR}/boards")
set(GEN_PINS_AF_CSV "${MICROPY_BOARDS_DIR}/rp2_af.csv")
set(GEN_PINS_PREFIX "${MICROPY_BOARDS_DIR}/rp2_prefix.c")
set(GEN_PINS_MKPINS "${MICROPY_BOARDS_DIR}/make-pins.py")
set(GEN_PINS_SRC "${CMAKE_BINARY_DIR}/pins_${MICROPY_BOARD}.c")
set(GEN_PINS_HDR "${MICROPY_GENHDR_DIR}/pins.h")
set(GEN_PINS_QSTR "${CMAKE_BINARY_DIR}/pins_qstr.h")
set(GEN_PINS_AF_CONST "${MICROPY_GENHDR_DIR}/pins_af_const.h")
set(GEN_PINS_AF_PY "${CMAKE_BINARY_DIR}/pins_af.py")
if(EXISTS "${MICROPY_BOARDS_DIR}/${MICROPY_BOARD}/pins.csv")
set(GEN_PINS_BOARD_CSV "${MICROPY_BOARDS_DIR}/${MICROPY_BOARD}/pins.csv")
set(GEN_PINS_CSV_ARG --board "${GEN_PINS_BOARD_CSV}")
endif()
target_sources(${MICROPY_TARGET} PRIVATE
${GEN_PINS_HDR}
)
# Generate pins
add_custom_command(
OUTPUT ${GEN_PINS_HDR} ${GEN_PINS_SRC} ${GEN_PINS_QSTR}
COMMAND ${Python3_EXECUTABLE} ${GEN_PINS_MKPINS} ${GEN_PINS_CSV_ARG} --af ${GEN_PINS_AF_CSV} --prefix ${GEN_PINS_PREFIX}
--hdr ${GEN_PINS_HDR} --qstr ${GEN_PINS_QSTR} --af-const ${GEN_PINS_AF_CONST} --af-py ${GEN_PINS_AF_PY} > ${GEN_PINS_SRC}
DEPENDS
${GEN_PINS_AF_CSV}
${GEN_PINS_BOARD_CSV}
${GEN_PINS_MKPINS}
${GEN_PINS_PREFIX}
${MICROPY_MPVERSION}
VERBATIM
COMMAND_EXPAND_LISTS
)

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO13
1 LED GPIO13

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO11
1 LED GPIO11

Wyświetl plik

@ -13,6 +13,9 @@
// Disable internal error numbers.
#define MICROPY_USE_INTERNAL_ERRNO (0)
// Enable externally controlled pins.
#define MICROPY_HW_PIN_EXT_COUNT (5)
// Enable USB Mass Storage with FatFS filesystem.
#define MICROPY_HW_USB_MSC (1)
#define MICROPY_HW_USB_VID (0x2341)

Wyświetl plik

@ -0,0 +1,26 @@
TX,GPIO0
RX,GPIO1
D2,GPIO25
D3,GPIO15
D4,GPIO16
D5,GPIO17
D6,GPIO18
D7,GPIO19
D8,GPIO20
D9,GPIO21
D10,GPIO5
D11,GPIO7
D12,GPIO4
D13,GPIO6
LED,GPIO6
A0,GPIO26
A1,GPIO27
A2,GPIO28
A3,GPIO29
A4,GPIO12
A5,GPIO13
LEDR,EXT_GPIO0
LEDG,EXT_GPIO1
LEDB,EXT_GPIO2
A6,EXT_GPIO3
A7,EXT_GPIO4
1 TX GPIO0
2 RX GPIO1
3 D2 GPIO25
4 D3 GPIO15
5 D4 GPIO16
6 D5 GPIO17
7 D6 GPIO18
8 D7 GPIO19
9 D8 GPIO20
10 D9 GPIO21
11 D10 GPIO5
12 D11 GPIO7
13 D12 GPIO4
14 D13 GPIO6
15 LED GPIO6
16 A0 GPIO26
17 A1 GPIO27
18 A2 GPIO28
19 A3 GPIO29
20 A4 GPIO12
21 A5 GPIO13
22 LEDR EXT_GPIO0
23 LEDG EXT_GPIO1
24 LEDB EXT_GPIO2
25 A6 EXT_GPIO3
26 A7 EXT_GPIO4

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO23
1 LED GPIO23

Wyświetl plik

@ -0,0 +1,17 @@
# nullbits Bit-C PRO
The nullbits Bit-C PRO Board is based on the Raspberry Pi RP2040, and comes in the Arduino Pro Micro footprint.
## Board-specific modules
The `board` module contains definitions for the onboard RGB LED.
Example:
```python
>>> import board
>>> board.led_red.on()
>>> board.led_green.on()
>>> board.led_blue.on()
```

Wyświetl plik

@ -0,0 +1,20 @@
{
"deploy": [
"../deploy.md"
],
"docs": "",
"features": [
"Breadboard Friendly",
"RGB LED",
"USB-C",
"SPI Flash"
],
"images": [
"nullbits_bit_c_pro.jpg"
],
"mcu": "rp2040",
"product": "Bit-C PRO",
"thumbnail": "",
"url": "https://nullbits.co/bit-c-pro",
"vendor": "nullbits"
}

Wyświetl plik

@ -0,0 +1,7 @@
from machine import Pin, Signal
led_red = Signal("LED_RED", Pin.OUT, invert=True, value=0)
led_green = Signal("LED_GREEN", Pin.OUT, invert=True, value=0)
led_blue = Signal("LED_BLUE", Pin.OUT, invert=True, value=0)
del Pin

Wyświetl plik

@ -0,0 +1,2 @@
include("$(PORT_DIR)/boards/manifest.py")
module("board.py")

Wyświetl plik

@ -0,0 +1,10 @@
# cmake file for nullbits Bit-C PRO
# The Bit-C PRO is not yet in upstream pico-sdk, so define it here
# See also: https://github.com/raspberrypi/pico-sdk/tree/master/src/boards/include/boards
list(APPEND PICO_BOARD_HEADER_DIRS ${MICROPY_BOARD_DIR})
set(PICO_BOARD "nullbits_bit_c_pro")
# Freeze board.py
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)

Wyświetl plik

@ -0,0 +1,9 @@
// https://nullbits.co/bit-c-pro
#define MICROPY_HW_BOARD_NAME "nullbits Bit-C PRO"
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (1 * 512 * 1024)) // 512K reserved
// RGB LED, active low
// Red LED 16
// Green LED 17
// Blue LED 18

Wyświetl plik

@ -0,0 +1,96 @@
// Board definition for the nullbits Bit-C PRO
#ifndef _BOARDS_NULLBITS_BIT_C_PRO_H
#define _BOARDS_NULLBITS_BIT_C_PRO_H
// For board detection
#define NULLBITS_BIT_C_PRO
// On some samples, the xosc can take longer to stabilize than is usual
#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
#endif
// --- BOARD SPECIFIC ---
#define BIT_C_PRO_LED_R_PIN 16
#define BIT_C_PRO_LED_G_PIN 17
#define BIT_C_PRO_LED_B_PIN 18
// ------------- UART -------------//
#ifndef PICO_DEFAULT_UART
#define PICO_DEFAULT_UART 0
#endif
#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 0
#endif
#ifndef PICO_DEFAULT_UART_RX_PIN
#define PICO_DEFAULT_UART_RX_PIN 1
#endif
// --- LED ---
// Set the default LED to the Bit-C PRO's B led
#ifndef PICO_DEFAULT_LED_PIN
#define PICO_DEFAULT_LED_PIN BIT_C_PRO_LED_B_PIN
#endif
#ifndef PICO_DEFAULT_LED_PIN_INVERTED
#define PICO_DEFAULT_LED_PIN_INVERTED 1
#endif
// no PICO_DEFAULT_WS2812_PIN
// ------------- I2C -------------//
#ifndef PICO_DEFAULT_I2C
#define PICO_DEFAULT_I2C 0
#endif
#ifndef PICO_DEFAULT_I2C_SDA_PIN
#define PICO_DEFAULT_I2C_SDA_PIN 2
#endif
#ifndef PICO_DEFAULT_I2C_SCL_PIN
#define PICO_DEFAULT_I2C_SCL_PIN 3
#endif
// ------------- SPI -------------//
#ifndef PICO_DEFAULT_SPI
#define PICO_DEFAULT_SPI 0
#endif
#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN 23
#endif
#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN 20
#endif
#ifndef PICO_DEFAULT_SPI_SCK_PIN
#define PICO_DEFAULT_SPI_SCK_PIN 22
#endif
#ifndef PICO_DEFAULT_SPI_CSN_PIN
#define PICO_DEFAULT_SPI_CSN_PIN 21
#endif
// ------------- FLASH -------------//
// Best performance/compatibility with selected flash
#define PICO_BOOT_STAGE2_CHOOSE_W25X10CL 1
#ifndef PICO_FLASH_SPI_CLKDIV
#define PICO_FLASH_SPI_CLKDIV 2
#endif
// Bit-C PRO has 4MB SPI flash
#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024)
#endif
// All boards have B1+ RP2040
#ifndef PICO_RP2040_B0_SUPPORTED
#define PICO_RP2040_B0_SUPPORTED 0
#endif
#endif

Wyświetl plik

@ -0,0 +1,4 @@
LED,GPIO16
LED_RED,GPIO16
LED_GREEN,GPIO17
LED_BLUE,GPIO18
1 LED GPIO16
2 LED_RED GPIO16
3 LED_GREEN GPIO17
4 LED_BLUE GPIO18

Wyświetl plik

@ -0,0 +1,28 @@
GP0,GPIO0
GP1,GPIO1
GP2,GPIO2
GP3,GPIO3
GP4,GPIO4
GP5,GPIO5
GP6,GPIO6
GP7,GPIO7
GP8,GPIO8
GP9,GPIO9
GP10,GPIO10
GP11,GPIO11
GP12,GPIO12
GP13,GPIO13
GP14,GPIO14
GP15,GPIO15
GP16,GPIO16
GP17,GPIO17
GP18,GPIO18
GP19,GPIO19
GP20,GPIO20
GP21,GPIO21
GP22,GPIO22
GP25,GPIO25
GP26,GPIO26
GP27,GPIO27
GP28,GPIO28
LED,GPIO25
1 GP0 GPIO0
2 GP1 GPIO1
3 GP2 GPIO2
4 GP3 GPIO3
5 GP4 GPIO4
6 GP5 GPIO5
7 GP6 GPIO6
8 GP7 GPIO7
9 GP8 GPIO8
10 GP9 GPIO9
11 GP10 GPIO10
12 GP11 GPIO11
13 GP12 GPIO12
14 GP13 GPIO13
15 GP14 GPIO14
16 GP15 GPIO15
17 GP16 GPIO16
18 GP17 GPIO17
19 GP18 GPIO18
20 GP19 GPIO19
21 GP20 GPIO20
22 GP21 GPIO21
23 GP22 GPIO22
24 GP25 GPIO25
25 GP26 GPIO26
26 GP27 GPIO27
27 GP28 GPIO28
28 LED GPIO25

Wyświetl plik

@ -17,9 +17,6 @@
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 1
#define MICROPY_HW_PIN_CYW43_COUNT CYW43_WL_GPIO_COUNT
#ifdef CYW43_WL_GPIO_LED_PIN
#define MICROPY_HW_PIN_CYW43_LED_PIN_NUM CYW43_WL_GPIO_LED_PIN
#endif
#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT
#define MICROPY_HW_PIN_RESERVED(i) ((i) == CYW43_PIN_WL_HOST_WAKE || (i) == CYW43_PIN_WL_REG_ON)

Wyświetl plik

@ -0,0 +1,30 @@
GP0,GPIO0
GP1,GPIO1
GP2,GPIO2
GP3,GPIO3
GP4,GPIO4
GP5,GPIO5
GP6,GPIO6
GP7,GPIO7
GP8,GPIO8
GP9,GPIO9
GP10,GPIO10
GP11,GPIO11
GP12,GPIO12
GP13,GPIO13
GP14,GPIO14
GP15,GPIO15
GP16,GPIO16
GP17,GPIO17
GP18,GPIO18
GP19,GPIO19
GP20,GPIO20
GP21,GPIO21
GP22,GPIO22
GP26,GPIO26
GP27,GPIO27
GP28,GPIO28
WL_GPIO0,EXT_GPIO0
WL_GPIO1,EXT_GPIO1
WL_GPIO2,EXT_GPIO2
LED,EXT_GPIO0
1 GP0 GPIO0
2 GP1 GPIO1
3 GP2 GPIO2
4 GP3 GPIO3
5 GP4 GPIO4
6 GP5 GPIO5
7 GP6 GPIO6
8 GP7 GPIO7
9 GP8 GPIO8
10 GP9 GPIO9
11 GP10 GPIO10
12 GP11 GPIO11
13 GP12 GPIO12
14 GP13 GPIO13
15 GP14 GPIO14
16 GP15 GPIO15
17 GP16 GPIO16
18 GP17 GPIO17
19 GP18 GPIO18
20 GP19 GPIO19
21 GP20 GPIO20
22 GP21 GPIO21
23 GP22 GPIO22
24 GP26 GPIO26
25 GP27 GPIO27
26 GP28 GPIO28
27 WL_GPIO0 EXT_GPIO0
28 WL_GPIO1 EXT_GPIO1
29 WL_GPIO2 EXT_GPIO2
30 LED EXT_GPIO0

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO25
1 LED GPIO25

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO25
1 LED GPIO25

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO19
1 LED GPIO19

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO25
1 LED GPIO25

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO25
1 LED GPIO25

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO25
1 LED GPIO25

Wyświetl plik

@ -0,0 +1 @@
LED,GPIO25
1 LED GPIO25

Wyświetl plik

@ -0,0 +1,428 @@
#!/usr/bin/env python
"""Creates the pin file for the RP2."""
from __future__ import print_function
import argparse
import sys
import csv
import re
SUPPORTED_FN = {
"SPI": ["TX", "RX", "SCK", "CS"],
"UART": ["TX", "RX", "CTS", "RTS"],
"I2C": ["SCL", "SDA"],
"PWM": ["A", "B"],
"SIO": [""],
"PIO0": [""],
"PIO1": [""],
"GPCK": ["GPIN0", "GPOUT0", "GPIN1", "GPOUT1", "GPOUT2", "GPOUT3"],
"USB": ["OVCUR_DET", "VBUS_DET", "VBUS_EN"],
}
def parse_pin(name_str):
"""Parses a string and returns a pin number."""
if len(name_str) < 2:
raise ValueError("Expecting pin name to be at least 2 charcters.")
if not name_str.startswith("GPIO") and not name_str.startswith("EXT_GPIO"):
raise ValueError("Expecting pin name to start with EXT_/GPIO")
return int(re.findall(r"\d+$", name_str)[0])
def split_name_num(name_num):
num = None
for num_idx in range(len(name_num) - 1, -1, -1):
if not name_num[num_idx].isdigit():
name = name_num[0 : num_idx + 1]
num_str = name_num[num_idx + 1 :]
if len(num_str) > 0:
num = int(num_str)
break
if name == "PIO":
name += str(num)
return name, num
class AlternateFunction(object):
"""Holds the information associated with a pins alternate function."""
def __init__(self, idx, af_str):
self.idx = idx
self.af_str = af_str
self.func = ""
self.fn_num = None
self.pin_type = ""
self.supported = False
af_words = af_str.split("_", 1)
self.func, self.fn_num = split_name_num(af_words[0])
if len(af_words) > 1:
self.pin_type = af_words[1]
if self.func in SUPPORTED_FN:
pin_types = SUPPORTED_FN[self.func]
if self.pin_type in pin_types:
self.supported = True
def is_supported(self):
return self.supported
def ptr(self):
"""Returns the numbered function (i.e. USART6) for this AF."""
if self.fn_num is None:
return self.func
return "{:s}{:d}".format(self.func, self.fn_num)
def mux_name(self):
return "AF{:d}_{:s}".format(self.idx, self.ptr())
def print(self):
"""Prints the C representation of this AF."""
if self.supported:
print(" AF", end="")
else:
print(" //", end="")
fn_num = self.fn_num
if fn_num is None:
fn_num = 0
print("({:d}, {:4s}, {:d}), // {:s}".format(self.idx, self.func, fn_num, self.af_str))
def qstr_list(self):
return [self.mux_name()]
class Pin(object):
"""Holds the information associated with a pin."""
def __init__(self, pin, is_ext=False):
self.pin = pin
self.alt_fn = []
self.alt_fn_count = 0
self.is_board = False
self.is_ext = is_ext
def cpu_pin_name(self):
return "{:s}GPIO{:d}".format("EXT_" if self.is_ext else "", self.pin)
def is_board_pin(self):
return self.is_board
def set_is_board_pin(self):
self.is_board = True
def parse_af(self, af_idx, af_strs_in):
if len(af_strs_in) == 0:
return
# If there is a slash, then the slash separates 2 aliases for the
# same alternate function.
af_strs = af_strs_in.split("/")
for af_str in af_strs:
alt_fn = AlternateFunction(af_idx, af_str)
self.alt_fn.append(alt_fn)
if alt_fn.is_supported():
self.alt_fn_count += 1
def alt_fn_name(self, null_if_0=False):
if null_if_0 and self.alt_fn_count == 0:
return "NULL"
return "pin_{:s}_af".format(self.cpu_pin_name())
def print(self):
if self.is_ext:
print("#if (MICROPY_HW_PIN_EXT_COUNT > {:d})".format(self.pin))
if self.alt_fn_count == 0:
print("// ", end="")
print("const machine_pin_af_obj_t {:s}[] = {{".format(self.alt_fn_name()))
for alt_fn in self.alt_fn:
alt_fn.print()
if self.alt_fn_count == 0:
print("// ", end="")
print("};")
print("")
print(
"{:s}machine_pin_obj_t pin_{:s} = PIN({:d}, {:s}, {:d}, {:d}, {:s});".format(
"" if self.is_ext else "const ",
self.cpu_pin_name(),
self.pin,
self.cpu_pin_name(),
self.is_ext,
self.alt_fn_count,
self.alt_fn_name(null_if_0=True),
)
)
if self.is_ext:
print("#endif")
print("")
def print_header(self, hdr_file):
n = self.cpu_pin_name()
hdr_file.write(
"extern{:s}machine_pin_obj_t pin_{:s};\n".format(" " if self.is_ext else " const ", n)
)
if self.alt_fn_count > 0:
hdr_file.write("extern const machine_pin_af_obj_t pin_{:s}_af[];\n".format(n))
def qstr_list(self):
result = []
for alt_fn in self.alt_fn:
if alt_fn.is_supported():
result += alt_fn.qstr_list()
return result
class NamedPin(object):
def __init__(self, name, pin):
self._name = name
self._pin = pin
def pin(self):
return self._pin
def name(self):
return self._name
class Pins(object):
def __init__(self):
self.cpu_pins = [] # list of NamedPin objects
self.board_pins = [] # list of NamedPin objects
self.ext_pins = [] # list of NamedPin objects
for i in range(0, 10):
self.ext_pins.append(NamedPin("EXT_GPIO{:d}".format(i), Pin(i, True)))
def find_pin(self, pin_name):
for pin in self.cpu_pins:
if pin.name() == pin_name:
return pin.pin()
for pin in self.ext_pins:
if pin.name() == pin_name:
return pin.pin()
def parse_af_file(self, filename, pinname_col, af_col):
with open(filename, "r") as csvfile:
rows = csv.reader(csvfile)
for row in rows:
try:
pin_num = parse_pin(row[pinname_col])
except Exception as e:
# import traceback; traceback.print_exc()
continue
pin = Pin(pin_num)
for af_idx in range(af_col, len(row)):
if af_idx >= af_col:
pin.parse_af(af_idx, row[af_idx])
self.cpu_pins.append(NamedPin(pin.cpu_pin_name(), pin))
def parse_board_file(self, filename):
with open(filename, "r") as csvfile:
rows = csv.reader(csvfile)
for row in rows:
if len(row) == 0 or row[0].startswith("#"):
# Skip empty lines, and lines starting with "#"
continue
if len(row) != 2:
raise ValueError("Expecting two entries in a row")
cpu_pin_name = row[1]
try:
pin_num = parse_pin(cpu_pin_name)
except:
# import traceback; traceback.print_exc()
continue
pin = self.find_pin(cpu_pin_name)
if pin:
pin.set_is_board_pin()
if row[0]: # Only add board pins that have a name
self.board_pins.append(NamedPin(row[0], pin))
def print_table(self, label, named_pins):
print("")
print("const machine_pin_obj_t *machine_pin_{:s}_pins[] = {{".format(label))
for pin in named_pins:
if not pin.pin().is_ext:
print(" &pin_{},".format(pin.name()))
print("};")
print("")
def print_named(self, label, named_pins):
print("")
print(
"STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{".format(label)
)
for named_pin in named_pins:
pin = named_pin.pin()
if pin.is_ext:
print(" #if (MICROPY_HW_PIN_EXT_COUNT > {:d})".format(pin.pin))
print(
" {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},".format(
named_pin.name(), pin.cpu_pin_name()
)
)
if pin.is_ext:
print(" #endif")
print("};")
print(
"MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);".format(
label, label
)
)
print("")
def print(self):
for pin in self.cpu_pins:
pin.pin().print()
for pin in self.ext_pins:
if pin.pin().is_ext:
pin.pin().print()
self.print_table("cpu", self.cpu_pins)
self.print_named("cpu", self.cpu_pins + self.ext_pins)
self.print_named("board", self.board_pins)
def print_header(self, hdr_filename, obj_decls):
with open(hdr_filename, "wt") as hdr_file:
if obj_decls:
for named_pin in self.cpu_pins:
pin = named_pin.pin()
pin.print_header(hdr_file)
for named_pin in self.board_pins:
pin = named_pin.pin()
if pin.is_ext:
pin.print_header(hdr_file)
# provide #define's mapping board to cpu name
for named_pin in self.board_pins:
if named_pin.pin().is_board_pin():
hdr_file.write(
"#define pin_{:s} pin_{:s}\n".format(
named_pin.name(), named_pin.pin().cpu_pin_name()
)
)
def print_qstr(self, qstr_filename):
with open(qstr_filename, "wt") as qstr_file:
qstr_set = set([])
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if pin.is_board_pin():
qstr_set |= set(pin.qstr_list())
qstr_set |= set([named_pin.name()])
for named_pin in self.board_pins:
qstr_set |= set([named_pin.name()])
for qstr in sorted(qstr_set):
print("Q({})".format(qstr), file=qstr_file)
def print_af_hdr(self, af_const_filename):
with open(af_const_filename, "wt") as af_const_file:
af_hdr_set = set([])
mux_name_width = 0
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if pin.is_board_pin():
for af in pin.alt_fn:
if af.is_supported():
mux_name = af.mux_name()
af_hdr_set |= set([mux_name])
if len(mux_name) > mux_name_width:
mux_name_width = len(mux_name)
for mux_name in sorted(af_hdr_set):
key = "MP_OBJ_NEW_QSTR(MP_QSTR_{}),".format(mux_name)
val = "MP_OBJ_NEW_SMALL_INT(GPIO_{})".format(mux_name)
print(" { %-*s %s }," % (mux_name_width + 26, key, val), file=af_const_file)
def print_af_py(self, af_py_filename):
with open(af_py_filename, "wt") as af_py_file:
print("PINS_AF = (", file=af_py_file)
for named_pin in self.board_pins:
print(" ('%s', " % named_pin.name(), end="", file=af_py_file)
for af in named_pin.pin().alt_fn:
if af.is_supported():
print("(%d, '%s'), " % (af.idx, af.af_str), end="", file=af_py_file)
print("),", file=af_py_file)
print(")", file=af_py_file)
def main():
parser = argparse.ArgumentParser(
prog="make-pins.py",
usage="%(prog)s [options] [command]",
description="Generate board specific pin file",
)
parser.add_argument(
"-a",
"--af",
dest="af_filename",
help="Specifies the alternate function file for the chip",
default="rp2_af.csv",
)
parser.add_argument(
"--af-const",
dest="af_const_filename",
help="Specifies header file for alternate function constants.",
default="build/pins_af_const.h",
)
parser.add_argument(
"--af-py",
dest="af_py_filename",
help="Specifies the filename for the python alternate function mappings.",
default="build/pins_af.py",
)
parser.add_argument(
"-b",
"--board",
dest="board_filename",
help="Specifies the board file",
)
parser.add_argument(
"-p",
"--prefix",
dest="prefix_filename",
help="Specifies beginning portion of generated pins file",
default="rp2_prefix.c",
)
parser.add_argument(
"-q",
"--qstr",
dest="qstr_filename",
help="Specifies name of generated qstr header file",
default="build/pins_qstr.h",
)
parser.add_argument(
"-r",
"--hdr",
dest="hdr_filename",
help="Specifies name of generated pin header file",
default="build/pins.h",
)
args = parser.parse_args(sys.argv[1:])
pins = Pins()
print("// This file was automatically generated by make-pins.py")
print("//")
if args.af_filename:
print("// --af {:s}".format(args.af_filename))
pins.parse_af_file(args.af_filename, 0, 1)
if args.board_filename:
print("// --board {:s}".format(args.board_filename))
pins.parse_board_file(args.board_filename)
if args.prefix_filename:
print("// --prefix {:s}".format(args.prefix_filename))
print("")
with open(args.prefix_filename, "r") as prefix_file:
print(prefix_file.read())
pins.print()
pins.print_header(args.hdr_filename, True)
pins.print_qstr(args.qstr_filename)
pins.print_af_hdr(args.af_const_filename)
pins.print_af_py(args.af_py_filename)
if __name__ == "__main__":
main()

Wyświetl plik

@ -0,0 +1,31 @@
Pin,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9
GPIO0,SPI0_RX,UART0_TX,I2C0_SDA,PWM0_A,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO1,SPI0_CS,UART0_RX,I2C0_SCL,PWM0_B,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO2,SPI0_SCK,UART0_CTS,I2C1_SDA,PWM1_A,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO3,SPI0_TX,UART0_RTS,I2C1_SCL,PWM1_B,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO4,SPI0_RX,UART1_TX,I2C0_SDA,PWM2_A,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO5,SPI0_CS,UART1_RX,I2C0_SCL,PWM2_B,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO6,SPI0_SCK,UART1_CTS,I2C1_SDA,PWM3_A,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO7,SPI0_TX,UART1_RTS,I2C1_SCL,PWM3_B,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO8,SPI1_RX,UART1_TX,I2C0_SDA,PWM4_A,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO9,SPI1_CS,UART1_RX,I2C0_SCL,PWM4_B,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO10,SPI1_SCK,UART1_CTS,I2C1_SDA,PWM5_A,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO11,SPI1_TX,UART1_RTS,I2C1_SCL,PWM5_B,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO12,SPI1_RX,UART0_TX,I2C0_SDA,PWM6_A,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO13,SPI1_CS,UART0_RX,I2C0_SCL,PWM6_B,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO14,SPI1_SCK,UART0_CTS,I2C1_SDA,PWM7_A,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO15,SPI1_TX,UART0_RTS,I2C1_SCL,PWM7_B,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO16,SPI0_RX,UART0_TX,I2C0_SDA,PWM0_A,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO17,SPI0_CS,UART0_RX,I2C0_SCL,PWM0_B,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO18,SPI0_SCK,UART0_CTS,I2C1_SDA,PWM1_A,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO19,SPI0_TX,UART0_RTS,I2C1_SCL,PWM1_B,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO20,SPI0_RX,UART1_TX,I2C0_SDA,PWM2_A,SIO,PIO0,PIO1,GPCK_GPIN0,USB_VBUS_EN
GPIO21,SPI0_CS,UART1_RX,I2C0_SCL,PWM2_B,SIO,PIO0,PIO1,GPCK_GPOUT0,USB_OVCUR_DET
GPIO22,SPI0_SCK,UART1_CTS,I2C1_SDA,PWM3_A,SIO,PIO0,PIO1,GPCK_GPIN1,USB_VBUS_DET
GPIO23,SPI0_TX,UART1_RTS,I2C1_SCL,PWM3_B,SIO,PIO0,PIO1,GPCK_GPOUT1,USB_VBUS_EN
GPIO24,SPI1_RX,UART1_TX,I2C0_SDA,PWM4_A,SIO,PIO0,PIO1,GPCK_GPOUT2,USB_OVCUR_DET
GPIO25,SPI1_CS,UART1_RX,I2C0_SCL,PWM4_B,SIO,PIO0,PIO1,GPCK_GPOUT3,USB_VBUS_DET
GPIO26,SPI1_SCK,UART1_CTS,I2C1_SDA,PWM5_A,SIO,PIO0,PIO1,,USB_VBUS_EN
GPIO27,SPI1_TX,UART1_RTS,I2C1_SCL,PWM5_B,SIO,PIO0,PIO1,,USB_OVCUR_DET
GPIO28,SPI1_RX,UART0_TX,I2C0_SDA,PWM6_A,SIO,PIO0,PIO1,,USB_VBUS_DET
GPIO29,SPI1_CS,UART0_RX,I2C0_SCL,PWM6_B,SIO,PIO0,PIO1,,USB_VBUS_EN
1 Pin AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AF9
2 GPIO0 SPI0_RX UART0_TX I2C0_SDA PWM0_A SIO PIO0 PIO1 USB_OVCUR_DET
3 GPIO1 SPI0_CS UART0_RX I2C0_SCL PWM0_B SIO PIO0 PIO1 USB_VBUS_DET
4 GPIO2 SPI0_SCK UART0_CTS I2C1_SDA PWM1_A SIO PIO0 PIO1 USB_VBUS_EN
5 GPIO3 SPI0_TX UART0_RTS I2C1_SCL PWM1_B SIO PIO0 PIO1 USB_OVCUR_DET
6 GPIO4 SPI0_RX UART1_TX I2C0_SDA PWM2_A SIO PIO0 PIO1 USB_VBUS_DET
7 GPIO5 SPI0_CS UART1_RX I2C0_SCL PWM2_B SIO PIO0 PIO1 USB_VBUS_EN
8 GPIO6 SPI0_SCK UART1_CTS I2C1_SDA PWM3_A SIO PIO0 PIO1 USB_OVCUR_DET
9 GPIO7 SPI0_TX UART1_RTS I2C1_SCL PWM3_B SIO PIO0 PIO1 USB_VBUS_DET
10 GPIO8 SPI1_RX UART1_TX I2C0_SDA PWM4_A SIO PIO0 PIO1 USB_VBUS_EN
11 GPIO9 SPI1_CS UART1_RX I2C0_SCL PWM4_B SIO PIO0 PIO1 USB_OVCUR_DET
12 GPIO10 SPI1_SCK UART1_CTS I2C1_SDA PWM5_A SIO PIO0 PIO1 USB_VBUS_DET
13 GPIO11 SPI1_TX UART1_RTS I2C1_SCL PWM5_B SIO PIO0 PIO1 USB_VBUS_EN
14 GPIO12 SPI1_RX UART0_TX I2C0_SDA PWM6_A SIO PIO0 PIO1 USB_OVCUR_DET
15 GPIO13 SPI1_CS UART0_RX I2C0_SCL PWM6_B SIO PIO0 PIO1 USB_VBUS_DET
16 GPIO14 SPI1_SCK UART0_CTS I2C1_SDA PWM7_A SIO PIO0 PIO1 USB_VBUS_EN
17 GPIO15 SPI1_TX UART0_RTS I2C1_SCL PWM7_B SIO PIO0 PIO1 USB_OVCUR_DET
18 GPIO16 SPI0_RX UART0_TX I2C0_SDA PWM0_A SIO PIO0 PIO1 USB_VBUS_DET
19 GPIO17 SPI0_CS UART0_RX I2C0_SCL PWM0_B SIO PIO0 PIO1 USB_VBUS_EN
20 GPIO18 SPI0_SCK UART0_CTS I2C1_SDA PWM1_A SIO PIO0 PIO1 USB_OVCUR_DET
21 GPIO19 SPI0_TX UART0_RTS I2C1_SCL PWM1_B SIO PIO0 PIO1 USB_VBUS_DET
22 GPIO20 SPI0_RX UART1_TX I2C0_SDA PWM2_A SIO PIO0 PIO1 GPCK_GPIN0 USB_VBUS_EN
23 GPIO21 SPI0_CS UART1_RX I2C0_SCL PWM2_B SIO PIO0 PIO1 GPCK_GPOUT0 USB_OVCUR_DET
24 GPIO22 SPI0_SCK UART1_CTS I2C1_SDA PWM3_A SIO PIO0 PIO1 GPCK_GPIN1 USB_VBUS_DET
25 GPIO23 SPI0_TX UART1_RTS I2C1_SCL PWM3_B SIO PIO0 PIO1 GPCK_GPOUT1 USB_VBUS_EN
26 GPIO24 SPI1_RX UART1_TX I2C0_SDA PWM4_A SIO PIO0 PIO1 GPCK_GPOUT2 USB_OVCUR_DET
27 GPIO25 SPI1_CS UART1_RX I2C0_SCL PWM4_B SIO PIO0 PIO1 GPCK_GPOUT3 USB_VBUS_DET
28 GPIO26 SPI1_SCK UART1_CTS I2C1_SDA PWM5_A SIO PIO0 PIO1 USB_VBUS_EN
29 GPIO27 SPI1_TX UART1_RTS I2C1_SCL PWM5_B SIO PIO0 PIO1 USB_OVCUR_DET
30 GPIO28 SPI1_RX UART0_TX I2C0_SDA PWM6_A SIO PIO0 PIO1 USB_VBUS_DET
31 GPIO29 SPI1_CS UART0_RX I2C0_SCL PWM6_B SIO PIO0 PIO1 USB_VBUS_EN

Wyświetl plik

@ -0,0 +1,36 @@
#include <stdint.h>
#include "py/obj.h"
#include "py/mphal.h"
#include "machine_pin.h"
#define AF(af_idx, af_fn, af_unit) \
{ \
.base = { &machine_pin_af_type }, \
.name = MP_QSTR_##af_fn, \
.idx = (af_idx), \
.fn = GPIO_FUNC_##af_fn, \
.unit = (af_unit), \
}
#if MICROPY_HW_PIN_EXT_COUNT
#define PIN(_id, _name, _is_ext, _af_num, _af_list) \
{ \
.base = { &machine_pin_type }, \
.name = MP_QSTR_##_name, \
.id = (uint8_t)(_id), \
.is_ext = (_is_ext), \
.is_output = false, \
.last_output_value = 0, \
.af_num = (_af_num), \
.af = (_af_list), \
}
#else
#define PIN(_id, _name, _is_ext, _af_num, _af_list) \
{ \
.base = { &machine_pin_type }, \
.name = MP_QSTR_##_name, \
.id = (uint8_t)(_id), \
.af_num = (_af_num), \
.af = (_af_list), \
}
#endif

Wyświetl plik

@ -31,6 +31,7 @@
#include "py/mphal.h"
#include "shared/runtime/mpirq.h"
#include "modmachine.h"
#include "machine_pin.h"
#include "extmod/virtpin.h"
#include "hardware/irq.h"
@ -38,11 +39,6 @@
#include "hardware/structs/iobank0.h"
#include "hardware/structs/padsbank0.h"
#define GPIO_MODE_IN (0)
#define GPIO_MODE_OUT (1)
#define GPIO_MODE_OPEN_DRAIN (2)
#define GPIO_MODE_ALT (3)
// These can be or'd together.
#define GPIO_PULL_UP (1)
#define GPIO_PULL_DOWN (2)
@ -62,15 +58,25 @@
#define MICROPY_HW_PIN_RESERVED(i) (0)
#endif
typedef struct _machine_pin_obj_t {
mp_obj_base_t base;
uint8_t id;
#if MICROPY_HW_PIN_CYW43_COUNT
bool is_cyw43;
bool is_output;
bool last_output_value;
#endif
} machine_pin_obj_t;
MP_DEFINE_CONST_OBJ_TYPE(
machine_pin_af_type,
MP_QSTR_PinAF,
MP_TYPE_FLAG_NONE
);
MP_DEFINE_CONST_OBJ_TYPE(
pin_cpu_pins_obj_type,
MP_QSTR_cpu,
MP_TYPE_FLAG_NONE,
locals_dict, &pin_cpu_pins_locals_dict
);
MP_DEFINE_CONST_OBJ_TYPE(
pin_board_pins_obj_type,
MP_QSTR_board,
MP_TYPE_FLAG_NONE,
locals_dict, &pin_board_pins_locals_dict
);
typedef struct _machine_pin_irq_obj_t {
mp_irq_obj_t base;
@ -79,92 +85,17 @@ typedef struct _machine_pin_irq_obj_t {
} machine_pin_irq_obj_t;
STATIC const mp_irq_methods_t machine_pin_irq_methods;
STATIC const machine_pin_obj_t machine_pin_obj[NUM_BANK0_GPIOS] = {
{{&machine_pin_type}, 0},
{{&machine_pin_type}, 1},
{{&machine_pin_type}, 2},
{{&machine_pin_type}, 3},
{{&machine_pin_type}, 4},
{{&machine_pin_type}, 5},
{{&machine_pin_type}, 6},
{{&machine_pin_type}, 7},
{{&machine_pin_type}, 8},
{{&machine_pin_type}, 9},
{{&machine_pin_type}, 10},
{{&machine_pin_type}, 11},
{{&machine_pin_type}, 12},
{{&machine_pin_type}, 13},
{{&machine_pin_type}, 14},
{{&machine_pin_type}, 15},
{{&machine_pin_type}, 16},
{{&machine_pin_type}, 17},
{{&machine_pin_type}, 18},
{{&machine_pin_type}, 19},
{{&machine_pin_type}, 20},
{{&machine_pin_type}, 21},
{{&machine_pin_type}, 22},
{{&machine_pin_type}, 23},
{{&machine_pin_type}, 24},
{{&machine_pin_type}, 25},
{{&machine_pin_type}, 26},
{{&machine_pin_type}, 27},
{{&machine_pin_type}, 28},
{{&machine_pin_type}, 29},
};
#if MICROPY_HW_PIN_CYW43_COUNT
#include "lib/cyw43-driver/src/cyw43.h"
#define CYW43_PIN_NAME_PREFIX "WL_GPIO"
STATIC machine_pin_obj_t cyw43_pin_obj[MICROPY_HW_PIN_CYW43_COUNT];
#endif
#define LED_PIN_NAME "LED"
#ifndef MICROPY_HW_PIN_ENABLE_LED_PIN
#if defined(MICROPY_HW_PIN_CYW43_LED_PIN_NUM) || defined(PICO_DEFAULT_LED_PIN)
#define MICROPY_HW_PIN_ENABLE_LED_PIN 1
#endif
#endif
#ifdef MICROPY_HW_PIN_ENABLE_LED_PIN
#ifdef MICROPY_HW_PIN_CYW43_LED_PIN_NUM
STATIC machine_pin_obj_t *led_pin_obj = &cyw43_pin_obj[MICROPY_HW_PIN_CYW43_LED_PIN_NUM];
#elif defined(MICROPY_HW_PIN_LED_PIN_NUM)
STATIC machine_pin_obj_t *led_pin_obj = &machine_pin_obj[MICROPY_HW_PIN_LED_PIN_NUM];
#elif defined(PICO_DEFAULT_LED_PIN)
STATIC const machine_pin_obj_t *led_pin_obj = &machine_pin_obj[PICO_DEFAULT_LED_PIN];
#else
#error MICROPY_HW_PIN_ENABLE_LED_PIN defined but there is no LED pin
#endif
#endif
extern const machine_pin_obj_t *machine_pin_cpu_pins[NUM_BANK0_GPIOS];
// Mask with "1" indicating that the corresponding pin is in simulated open-drain mode.
uint32_t machine_pin_open_drain_mask;
#if MICROPY_HW_PIN_CYW43_COUNT
STATIC inline bool is_cyw43_pin(__unused const machine_pin_obj_t *self) {
return self->is_cyw43;
#if MICROPY_HW_PIN_EXT_COUNT
STATIC inline bool is_ext_pin(__unused const machine_pin_obj_t *self) {
return self->is_ext;
}
#else
#define is_cyw43_pin(x) false
#endif
#if MICROPY_HW_PIN_CYW43_COUNT
STATIC inline void update_cyw43_value(__unused machine_pin_obj_t *self, bool value) {
if (value != self->last_output_value || !self->is_output) {
cyw43_gpio_set(&cyw43_state, self->id, value);
}
self->last_output_value = value;
}
#endif
#if MICROPY_HW_PIN_CYW43_COUNT
STATIC inline bool get_cyw43_value(__unused machine_pin_obj_t *self) {
bool value = false;
cyw43_gpio_get(&cyw43_state, self->id, &value);
return value;
}
#define is_ext_pin(x) false
#endif
STATIC void gpio_irq(void) {
@ -191,12 +122,8 @@ void machine_pin_init(void) {
memset(MP_STATE_PORT(machine_pin_irq_obj), 0, sizeof(MP_STATE_PORT(machine_pin_irq_obj)));
irq_add_shared_handler(IO_IRQ_BANK0, gpio_irq, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
irq_set_enabled(IO_IRQ_BANK0, true);
#if MICROPY_HW_PIN_CYW43_COUNT
for (uint i = 0; i < count_of(cyw43_pin_obj); i++) {
cyw43_pin_obj[i].id = i;
cyw43_pin_obj[i].base.type = &machine_pin_type;
cyw43_pin_obj[i].is_cyw43 = true;
}
#if MICROPY_HW_PIN_EXT_COUNT
machine_pin_ext_init();
#endif
}
@ -210,11 +137,40 @@ void machine_pin_deinit(void) {
irq_remove_handler(IO_IRQ_BANK0, gpio_irq);
}
const machine_pin_obj_t *machine_pin_find_named(const mp_obj_dict_t *named_pins, mp_obj_t name) {
const mp_map_t *named_map = &named_pins->map;
mp_map_elem_t *named_elem = mp_map_lookup((mp_map_t *)named_map, name, MP_MAP_LOOKUP);
if (named_elem != NULL && named_elem->value != NULL) {
return MP_OBJ_TO_PTR(named_elem->value);
}
return NULL;
}
const machine_pin_af_obj_t *machine_pin_find_alt(const machine_pin_obj_t *pin, uint8_t fn) {
const machine_pin_af_obj_t *af = pin->af;
for (mp_uint_t i = 0; i < pin->af_num; i++, af++) {
if (af->fn == fn) {
return af;
}
}
return NULL;
}
const machine_pin_af_obj_t *machine_pin_find_alt_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx) {
const machine_pin_af_obj_t *af = pin->af;
for (mp_uint_t i = 0; i < pin->af_num; i++, af++) {
if (af->idx == af_idx) {
return af;
}
}
return NULL;
}
STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_pin_obj_t *self = self_in;
uint funcsel = GPIO_GET_FUNCSEL(self->id);
qstr mode_qst;
if (!is_cyw43_pin(self)) {
if (!is_ext_pin(self)) {
if (funcsel == GPIO_FUNC_SIO) {
if (GPIO_IS_OPEN_DRAIN(self->id)) {
mode_qst = MP_QSTR_OPEN_DRAIN;
@ -226,7 +182,7 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
} else {
mode_qst = MP_QSTR_ALT;
}
mp_printf(print, "Pin(%u, mode=%q", self->id, mode_qst);
mp_printf(print, "Pin(%q, mode=%q", self->name, mode_qst);
bool pull_up = false;
if (GPIO_IS_PULL_UP(self->id)) {
mp_printf(print, ", pull=%q", MP_QSTR_PULL_UP);
@ -240,12 +196,17 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
}
}
if (funcsel != GPIO_FUNC_SIO) {
mp_printf(print, ", alt=%u", funcsel);
const machine_pin_af_obj_t *af = machine_pin_find_alt_by_index(self, funcsel);
if (af == NULL) {
mp_printf(print, ", alt=%u", funcsel);
} else {
mp_printf(print, ", alt=%q", af->name);
}
}
} else {
#if MICROPY_HW_PIN_CYW43_COUNT
mode_qst = self->is_output ? MP_QSTR_OUT : MP_QSTR_IN;
mp_printf(print, "Pin(%s%u, mode=%q", CYW43_PIN_NAME_PREFIX, self->id, mode_qst);
#if MICROPY_HW_PIN_EXT_COUNT
mode_qst = (self->is_output) ? MP_QSTR_OUT : MP_QSTR_IN;
mp_printf(print, "Pin(%q, mode=%q", self->name, mode_qst);
#endif
}
mp_printf(print, ")");
@ -261,155 +222,102 @@ static const mp_arg_t allowed_args[] = {
{MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = GPIO_FUNC_SIO}},
};
#if MICROPY_HW_PIN_CYW43_COUNT
// pin.init(mode, pull=None, *, value=None, alt=FUNC_SIO)
STATIC mp_obj_t machine_pin_cyw43_obj_init_helper(machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
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);
if (args[ARG_pull].u_obj != mp_const_none) {
int pull = mp_obj_get_int(args[ARG_pull].u_obj);
if (pull) {
mp_raise_ValueError("Pulls are not supported for this pin");
}
}
if (args[ARG_alt].u_int != GPIO_FUNC_SIO) {
mp_raise_ValueError("Alternate functions are not supported for this pin");
}
int value = -1;
if (args[ARG_value].u_obj != mp_const_none) {
value = mp_obj_is_true(args[ARG_value].u_obj);
}
if (args[ARG_mode].u_obj != mp_const_none) {
mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj);
if (mode == GPIO_MODE_IN) {
if (self->is_output) {
// todo need to disable output
}
self->is_output = false;
} else if (mode == GPIO_MODE_OUT) {
if (!self->is_output) {
// todo need to enable output
// for now we just set the value
if (value == -1) {
value = self->last_output_value;
}
self->last_output_value = !self->last_output_value; // defeat shortcircuit
update_cyw43_value(self, value);
self->is_output = true;
}
} else {
mp_raise_ValueError("only Pin.OUT and Pin.IN are supported for this pin");
}
}
if (value != -1) {
if (self->is_output) {
update_cyw43_value(self, value);
} else {
// figure if you pass a value to IN it should still remember it (this is what regular GPIO does)
self->last_output_value = value;
}
}
return mp_const_none;
}
#endif
STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
// parse args
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);
// set initial value (do this before configuring mode/pull)
if (is_ext_pin(self) && args[ARG_pull].u_obj != mp_const_none) {
mp_raise_ValueError("pulls are not supported for external pins");
}
if (is_ext_pin(self) && args[ARG_alt].u_int != GPIO_FUNC_SIO) {
mp_raise_ValueError("alternate functions are not supported for external pins");
}
// get initial value of pin (only valid for OUT and OPEN_DRAIN modes)
int value = -1;
if (args[ARG_value].u_obj != mp_const_none) {
gpio_put(self->id, mp_obj_is_true(args[ARG_value].u_obj));
value = mp_obj_is_true(args[ARG_value].u_obj);
}
// configure mode
if (args[ARG_mode].u_obj != mp_const_none) {
mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj);
if (mode == GPIO_MODE_IN) {
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
// The regular Pins are const, but the external pins are mutable.
machine_pin_obj_t *mutable_self = (machine_pin_obj_t *)self;
machine_pin_ext_config(mutable_self, mode, value);
#endif
} else if (mode == MACHINE_PIN_MODE_IN) {
mp_hal_pin_input(self->id);
} else if (mode == GPIO_MODE_OUT) {
} else if (mode == MACHINE_PIN_MODE_OUT) {
if (value != -1) {
// set initial output value before configuring mode
gpio_put(self->id, value);
}
mp_hal_pin_output(self->id);
} else if (mode == GPIO_MODE_OPEN_DRAIN) {
mp_hal_pin_open_drain(self->id);
} else if (mode == MACHINE_PIN_MODE_OPEN_DRAIN) {
mp_hal_pin_open_drain_with_value(self->id, value == -1 ? 1 : value);
} else {
// Alternate function.
gpio_set_function(self->id, args[ARG_alt].u_int);
// Configure alternate function.
mp_uint_t af = args[ARG_alt].u_int;
if (machine_pin_find_alt(self, af) == NULL) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin af: %d"), af);
}
gpio_set_function(self->id, af);
machine_pin_open_drain_mask &= ~(1 << self->id);
}
}
// configure pull (unconditionally because None means no-pull)
uint32_t pull = 0;
if (args[ARG_pull].u_obj != mp_const_none) {
pull = mp_obj_get_int(args[ARG_pull].u_obj);
if (!is_ext_pin(self)) {
// Configure pull (unconditionally because None means no-pull).
uint32_t pull = 0;
if (args[ARG_pull].u_obj != mp_const_none) {
pull = mp_obj_get_int(args[ARG_pull].u_obj);
}
gpio_set_pulls(self->id, pull & GPIO_PULL_UP, pull & GPIO_PULL_DOWN);
}
gpio_set_pulls(self->id, pull & GPIO_PULL_UP, pull & GPIO_PULL_DOWN);
return mp_const_none;
}
// constructor(id, ...)
mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
const machine_pin_obj_t *self = NULL;
if (mp_obj_is_str(args[0])) {
const char *name = mp_obj_str_get_str(args[0]);
#if MICROPY_HW_PIN_ENABLE_LED_PIN
if (!strcmp(name, LED_PIN_NAME)) {
self = led_pin_obj;
}
#endif
#if MICROPY_HW_PIN_CYW43_COUNT
static_assert(MICROPY_HW_PIN_CYW43_COUNT < 10, ""); // makes parsing name easy!
if (!self && !strncmp(name, CYW43_PIN_NAME_PREFIX, strlen(CYW43_PIN_NAME_PREFIX)) && strlen(name) == strlen(CYW43_PIN_NAME_PREFIX) + 1) {
int num = name[strlen(CYW43_PIN_NAME_PREFIX)] - '0';
if (num < MICROPY_HW_PIN_CYW43_COUNT) {
self = &cyw43_pin_obj[num];
}
}
#endif
// Try to find the pin in the board pins first.
self = machine_pin_find_named(&pin_board_pins_locals_dict, args[0]);
if (!self) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Unknown named pin \"%s\""), name);
// If not found, try to find the pin in the cpu pins which include
// CPU and and externally controlled pins (if any).
self = machine_pin_find_named(&pin_cpu_pins_locals_dict, args[0]);
}
if (!self) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("unknown named pin \"%s\""), name);
}
} else if (mp_obj_is_int(args[0])) {
// get the wanted pin object
int wanted_pin = mp_obj_get_int(args[0]);
if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_cpu_pins)) {
self = machine_pin_cpu_pins[wanted_pin];
}
}
if (!self) {
// get the wanted pin object
int wanted_pin = mp_obj_get_int(args[0]);
if (!(0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_obj))) {
mp_raise_ValueError("invalid pin");
}
self = &machine_pin_obj[wanted_pin];
mp_raise_ValueError("invalid pin");
}
// note we have different init args based on the type of pin. so Pin("LED", Pin.OUT) may not always make sense
if (!is_cyw43_pin(self)) {
if (n_args > 1 || n_kw > 0) {
// pin mode given, so configure this GPIO
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
machine_pin_obj_init_helper(self, n_args - 1, args + 1, &kw_args);
}
return MP_OBJ_FROM_PTR(self);
}
#if MICROPY_HW_PIN_CYW43_COUNT
if (n_args > 1 || n_kw > 0) {
// pin mode given, so configure this GPIO
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
// The regular Pins are const, but the CYW43 pins are mutable.
machine_pin_obj_t *mutable_self = (machine_pin_obj_t *)self;
machine_pin_cyw43_obj_init_helper(mutable_self, n_args - 1, args + 1, &kw_args);
machine_pin_obj_init_helper(self, n_args - 1, args + 1, &kw_args);
}
return MP_OBJ_FROM_PTR(self);
#endif
}
// fast method for getting/setting pin value
@ -418,39 +326,33 @@ STATIC mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c
machine_pin_obj_t *self = self_in;
if (n_args == 0) {
// get pin
if (!is_cyw43_pin(self)) {
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
return MP_OBJ_NEW_SMALL_INT(machine_pin_ext_get(self));
#endif
} else {
return MP_OBJ_NEW_SMALL_INT(gpio_get(self->id));
}
#if MICROPY_HW_PIN_CYW43_COUNT
return MP_OBJ_NEW_SMALL_INT(get_cyw43_value(self));
#endif
} else {
// set pin
bool value = mp_obj_is_true(args[0]);
if (!is_cyw43_pin(self)) {
if (GPIO_IS_OPEN_DRAIN(self->id)) {
MP_STATIC_ASSERT(GPIO_IN == 0 && GPIO_OUT == 1);
gpio_set_dir(self->id, 1 - value);
} else {
gpio_put(self->id, value);
}
return mp_const_none;
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
machine_pin_ext_set(self, value);
#endif
} else if (GPIO_IS_OPEN_DRAIN(self->id)) {
MP_STATIC_ASSERT(GPIO_IN == 0 && GPIO_OUT == 1);
gpio_set_dir(self->id, 1 - value);
} else {
gpio_put(self->id, value);
}
#if MICROPY_HW_PIN_CYW43_COUNT
update_cyw43_value(self, value);
#endif
}
return mp_const_none;
}
// pin.init(mode, pull)
STATIC mp_obj_t machine_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
if (!is_cyw43_pin(args[0])) {
return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
#if MICROPY_HW_PIN_CYW43_COUNT
return machine_pin_cyw43_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
#endif
return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_obj_init);
@ -463,36 +365,32 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_
// pin.low()
STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!is_cyw43_pin(self)) {
if (GPIO_IS_OPEN_DRAIN(self->id)) {
gpio_set_dir(self->id, GPIO_OUT);
} else {
gpio_clr_mask(1u << self->id);
}
return mp_const_none;
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
machine_pin_ext_set(self, 0);
#endif
} else if (GPIO_IS_OPEN_DRAIN(self->id)) {
gpio_set_dir(self->id, GPIO_OUT);
} else {
gpio_clr_mask(1u << self->id);
}
#if MICROPY_HW_PIN_CYW43_COUNT
update_cyw43_value(self, 0);
return mp_const_none;
#endif
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low);
// pin.high()
STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!is_cyw43_pin(self)) {
if (GPIO_IS_OPEN_DRAIN(self->id)) {
gpio_set_dir(self->id, GPIO_IN);
} else {
gpio_set_mask(1u << self->id);
}
return mp_const_none;
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
machine_pin_ext_set(self, 1);
#endif
} else if (GPIO_IS_OPEN_DRAIN(self->id)) {
gpio_set_dir(self->id, GPIO_IN);
} else {
gpio_set_mask(1u << self->id);
}
#if MICROPY_HW_PIN_CYW43_COUNT
update_cyw43_value(self, 1);
return mp_const_none;
#endif
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high);
@ -500,22 +398,20 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high);
// pin.toggle()
STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!is_cyw43_pin(self)) {
if (GPIO_IS_OPEN_DRAIN(self->id)) {
if (GPIO_IS_OUT(self->id)) {
gpio_set_dir(self->id, GPIO_IN);
} else {
gpio_set_dir(self->id, GPIO_OUT);
}
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
machine_pin_ext_set(self, self->last_output_value ^ 1);
#endif
} else if (GPIO_IS_OPEN_DRAIN(self->id)) {
if (GPIO_IS_OUT(self->id)) {
gpio_set_dir(self->id, GPIO_IN);
} else {
gpio_xor_mask(1u << self->id);
gpio_set_dir(self->id, GPIO_OUT);
}
return mp_const_none;
} else {
gpio_xor_mask(1u << self->id);
}
#if MICROPY_HW_PIN_CYW43_COUNT
update_cyw43_value(self, self->last_output_value ^ 1);
return mp_const_none;
#endif
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle);
@ -528,7 +424,7 @@ STATIC machine_pin_irq_obj_t *machine_pin_get_irq(mp_hal_pin_obj_t pin) {
irq = m_new_obj(machine_pin_irq_obj_t);
irq->base.base.type = &mp_irq_type;
irq->base.methods = (mp_irq_methods_t *)&machine_pin_irq_methods;
irq->base.parent = MP_OBJ_FROM_PTR(&machine_pin_obj[pin]);
irq->base.parent = MP_OBJ_FROM_PTR(machine_pin_cpu_pins[pin]);
irq->base.handler = mp_const_none;
irq->base.ishard = false;
MP_STATE_PORT(machine_pin_irq_obj[pin]) = irq;
@ -563,7 +459,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
{ MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} },
};
machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
if (is_cyw43_pin(self)) {
if (is_ext_pin(self)) {
mp_raise_ValueError(MP_ERROR_TEXT("expecting a regular GPIO Pin"));
}
@ -594,15 +490,30 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) },
{ MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) },
// class attributes
{ MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&pin_board_pins_obj_type) },
{ MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&pin_cpu_pins_obj_type) },
// class constants
{ MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_IN) },
{ MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUT) },
{ MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_OPEN_DRAIN) },
{ MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(GPIO_MODE_ALT) },
{ MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(MACHINE_PIN_MODE_IN) },
{ MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(MACHINE_PIN_MODE_OUT) },
{ MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(MACHINE_PIN_MODE_OPEN_DRAIN) },
{ MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(MACHINE_PIN_MODE_ALT) },
{ MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULL_UP) },
{ MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) },
{ MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_IRQ_EDGE_RISE) },
{ MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_IRQ_EDGE_FALL) },
// Pins alternate functions
{ MP_ROM_QSTR(MP_QSTR_ALT_SPI), MP_ROM_INT(GPIO_FUNC_SPI) },
{ MP_ROM_QSTR(MP_QSTR_ALT_UART), MP_ROM_INT(GPIO_FUNC_UART) },
{ MP_ROM_QSTR(MP_QSTR_ALT_I2C), MP_ROM_INT(GPIO_FUNC_I2C) },
{ MP_ROM_QSTR(MP_QSTR_ALT_PWM), MP_ROM_INT(GPIO_FUNC_PWM) },
{ MP_ROM_QSTR(MP_QSTR_ALT_SIO), MP_ROM_INT(GPIO_FUNC_SIO) },
{ MP_ROM_QSTR(MP_QSTR_ALT_PIO0), MP_ROM_INT(GPIO_FUNC_PIO0) },
{ MP_ROM_QSTR(MP_QSTR_ALT_PIO1), MP_ROM_INT(GPIO_FUNC_PIO1) },
{ MP_ROM_QSTR(MP_QSTR_ALT_GPCK), MP_ROM_INT(GPIO_FUNC_GPCK) },
{ MP_ROM_QSTR(MP_QSTR_ALT_USB), MP_ROM_INT(GPIO_FUNC_USB) },
};
STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table);
@ -610,31 +521,28 @@ STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, i
(void)errcode;
machine_pin_obj_t *self = self_in;
if (!is_cyw43_pin(self)) {
switch (request) {
case MP_PIN_READ: {
return gpio_get(self->id);
}
case MP_PIN_WRITE: {
gpio_put(self->id, arg);
return 0;
}
}
return -1;
}
#if MICROPY_HW_PIN_CYW43_COUNT
switch (request) {
case MP_PIN_READ: {
return get_cyw43_value(self);
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
return machine_pin_ext_get(self);
#endif
} else {
return gpio_get(self->id);
}
}
case MP_PIN_WRITE: {
update_cyw43_value(self, arg);
if (is_ext_pin(self)) {
#if MICROPY_HW_PIN_EXT_COUNT
machine_pin_ext_set(self, arg);
#endif
} else {
gpio_put(self->id, arg);
}
return 0;
}
}
return -1;
#endif
}
STATIC const mp_pin_p_t pin_pin_p = {
@ -683,7 +591,7 @@ mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) {
mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin"));
}
machine_pin_obj_t *pin = MP_OBJ_TO_PTR(obj);
if (is_cyw43_pin(pin)) {
if (is_ext_pin(pin)) {
mp_raise_ValueError(MP_ERROR_TEXT("expecting a regular GPIO Pin"));
}
return pin->id;

Wyświetl plik

@ -0,0 +1,82 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
*
* 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.
*/
#ifndef MICROPY_INCLUDED_RP2_MACHINE_PIN_H
#define MICROPY_INCLUDED_RP2_MACHINE_PIN_H
#include <stdint.h>
#include "py/obj.h"
#include "py/mphal.h"
enum {
MACHINE_PIN_MODE_IN = 0,
MACHINE_PIN_MODE_OUT = 1,
MACHINE_PIN_MODE_OPEN_DRAIN = 2,
MACHINE_PIN_MODE_ALT = 3
};
typedef struct _machine_pin_af_obj_t {
mp_obj_base_t base;
qstr name;
uint8_t idx : 4;
uint8_t fn : 4;
uint8_t unit : 8;
} machine_pin_af_obj_t;
typedef struct _machine_pin_obj_t {
mp_obj_base_t base;
qstr name;
uint8_t id : 5;
#if MICROPY_HW_PIN_EXT_COUNT
uint8_t is_ext : 1;
uint8_t is_output : 1;
uint8_t last_output_value : 1;
#endif
uint8_t af_num : 4;
const machine_pin_af_obj_t *af;
} machine_pin_obj_t;
extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t machine_pin_af_type;
// Include all of the individual pin objects
#include "genhdr/pins.h"
extern const mp_obj_type_t pin_cpu_pins_obj_type;
extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
extern const mp_obj_type_t pin_board_pins_obj_type;
extern const mp_obj_dict_t pin_board_pins_locals_dict;
void machine_pin_ext_init(void);
void machine_pin_ext_set(machine_pin_obj_t *self, bool value);
bool machine_pin_ext_get(machine_pin_obj_t *self);
void machine_pin_ext_config(machine_pin_obj_t *self, int mode, int value);
const machine_pin_obj_t *machine_pin_find_named(const mp_obj_dict_t *named_pins, mp_obj_t name);
const machine_pin_af_obj_t *machine_pin_find_alt(const machine_pin_obj_t *pin, uint8_t fn);
const machine_pin_af_obj_t *machine_pin_find_alt_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx);
#endif // MICROPY_INCLUDED_RP2_MACHINE_PIN_H

Wyświetl plik

@ -0,0 +1,86 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016-2022 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 <stdio.h>
#include <string.h>
#include "py/runtime.h"
#include "py/mphal.h"
#if defined(MICROPY_PY_NETWORK_CYW43) && defined(MICROPY_HW_PIN_EXT_COUNT)
#include "modmachine.h"
#include "machine_pin.h"
#include "lib/cyw43-driver/src/cyw43.h"
void machine_pin_ext_init(void) {
}
void machine_pin_ext_set(machine_pin_obj_t *self, bool value) {
if (value != self->last_output_value || !self->is_output) {
cyw43_gpio_set(&cyw43_state, self->id, value);
}
self->last_output_value = value;
}
bool machine_pin_ext_get(machine_pin_obj_t *self) {
bool value = false;
cyw43_gpio_get(&cyw43_state, self->id, &value);
return value;
}
void machine_pin_ext_config(machine_pin_obj_t *self, int mode, int value) {
if (mode == MACHINE_PIN_MODE_IN) {
if (self->is_output) {
// TODO need to disable output
}
self->is_output = false;
} else if (mode == MACHINE_PIN_MODE_OUT) {
if (!self->is_output) {
// TODO need to enable output
// for now we just set the value
if (value == -1) {
value = self->last_output_value;
}
self->last_output_value = !self->last_output_value; // defeat shortcircuit
machine_pin_ext_set(self, value);
self->is_output = true;
}
} else {
mp_raise_ValueError("only Pin.OUT and Pin.IN are supported for this pin");
}
if (value != -1) {
if (self->is_output) {
machine_pin_ext_set(self, value);
} else {
// figure if you pass a value to IN it should still remember it (this is what regular GPIO does)
self->last_output_value = value;
}
}
}
#endif // defined(MICROPY_PY_NETWORK_CYW43) && defined(MICROPY_HW_PIN_EXT_COUNT)

Wyświetl plik

@ -100,11 +100,33 @@ STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) {
pwm_set_enabled(self->slice, false);
}
STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
// Returns: floor((16*F + offset) / div16)
// Avoids overflow in the numerator that would occur if
// 16*F + offset > 2**32
// F + offset/16 > 2**28 = 268435456 (approximately, due to flooring)
uint32_t get_slice_hz(uint32_t offset, uint32_t div16) {
uint32_t source_hz = clock_get_hz(clk_sys);
if (source_hz + offset / 16 > 268000000) {
return (16 * (uint64_t)source_hz + offset) / div16;
} else {
return (16 * source_hz + offset) / div16;
}
}
// Returns 16*F / denom, rounded.
uint32_t get_slice_hz_round(uint32_t div16) {
return get_slice_hz(div16 / 2, div16);
}
// Returns ceil(16*F / denom).
uint32_t get_slice_hz_ceil(uint32_t div16) {
return get_slice_hz(div16 - 1, div16);
}
STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
uint32_t div16 = pwm_hw->slice[self->slice].div;
uint32_t top = pwm_hw->slice[self->slice].top;
uint32_t pwm_freq = 16 * source_hz / div16 / (top + 1);
uint32_t pwm_freq = get_slice_hz_round(div16 * (top + 1));
return MP_OBJ_NEW_SMALL_INT(pwm_freq);
}
@ -113,30 +135,36 @@ STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) {
// Maximum "top" is set at 65534 to be able to achieve 100% duty with 65535.
#define TOP_MAX 65534
uint32_t source_hz = clock_get_hz(clk_sys);
uint32_t div16_top = 16 * source_hz / freq;
uint32_t top = 1;
for (;;) {
// Try a few small prime factors to get close to the desired frequency.
if (div16_top >= 16 * 5 && div16_top % 5 == 0 && top * 5 <= TOP_MAX) {
div16_top /= 5;
top *= 5;
} else if (div16_top >= 16 * 3 && div16_top % 3 == 0 && top * 3 <= TOP_MAX) {
div16_top /= 3;
top *= 3;
} else if (div16_top >= 16 * 2 && top * 2 <= TOP_MAX) {
div16_top /= 2;
top *= 2;
} else {
break;
}
uint32_t div16;
uint32_t top;
if ((source_hz + freq / 2) / freq < TOP_MAX) {
// If possible (based on the formula for TOP below), use a DIV of 1.
// This also prevents overflow in the DIV calculation.
div16 = 16;
// Same as get_slice_hz_round() below but canceling the 16s
// to avoid overflow for high freq.
top = (source_hz + freq / 2) / freq - 1;
} else {
// Otherwise, choose the smallest possible DIV for maximum
// duty cycle resolution.
// Constraint: 16*F/(div16*freq) < TOP_MAX
// So:
div16 = get_slice_hz_ceil(TOP_MAX * freq);
// Set TOP as accurately as possible using rounding.
top = get_slice_hz_round(div16 * freq) - 1;
}
if (div16_top < 16) {
if (div16 < 16) {
mp_raise_ValueError(MP_ERROR_TEXT("freq too large"));
} else if (div16_top >= 256 * 16) {
} else if (div16 >= 256 * 16) {
mp_raise_ValueError(MP_ERROR_TEXT("freq too small"));
}
pwm_hw->slice[self->slice].div = div16_top;
pwm_hw->slice[self->slice].top = top - 1;
pwm_hw->slice[self->slice].div = div16;
pwm_hw->slice[self->slice].top = top;
if (self->duty_type == DUTY_U16) {
mp_machine_pwm_duty_set_u16(self, self->duty);
} else if (self->duty_type == DUTY_NS) {
@ -148,12 +176,17 @@ STATIC mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) {
uint32_t top = pwm_hw->slice[self->slice].top;
uint32_t cc = pwm_hw->slice[self->slice].cc;
cc = (cc >> (self->channel ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB)) & 0xffff;
return MP_OBJ_NEW_SMALL_INT(cc * 65535 / (top + 1));
// Use rounding (instead of flooring) here to give as accurate an
// estimate as possible.
return MP_OBJ_NEW_SMALL_INT((cc * 65535 + (top + 1) / 2) / (top + 1));
}
STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16) {
uint32_t top = pwm_hw->slice[self->slice].top;
uint32_t cc = duty_u16 * (top + 1) / 65535;
// Use rounding here to set it as accurately as possible.
uint32_t cc = (duty_u16 * (top + 1) + 65535 / 2) / 65535;
pwm_set_chan_level(self->slice, self->channel, cc);
pwm_set_enabled(self->slice, true);
self->duty = duty_u16;
@ -161,17 +194,15 @@ STATIC void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u
}
STATIC mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) {
uint32_t source_hz = clock_get_hz(clk_sys);
uint32_t slice_hz = 16 * source_hz / pwm_hw->slice[self->slice].div;
uint32_t slice_hz = get_slice_hz_round(pwm_hw->slice[self->slice].div);
uint32_t cc = pwm_hw->slice[self->slice].cc;
cc = (cc >> (self->channel ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB)) & 0xffff;
return MP_OBJ_NEW_SMALL_INT((uint64_t)cc * 1000000000ULL / slice_hz);
return MP_OBJ_NEW_SMALL_INT(((uint64_t)cc * 1000000000ULL + slice_hz / 2) / slice_hz);
}
STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) {
uint32_t source_hz = clock_get_hz(clk_sys);
uint32_t slice_hz = 16 * source_hz / pwm_hw->slice[self->slice].div;
uint32_t cc = (uint64_t)duty_ns * slice_hz / 1000000000ULL;
uint32_t slice_hz = get_slice_hz_round(pwm_hw->slice[self->slice].div);
uint32_t cc = ((uint64_t)duty_ns * slice_hz + 500000000ULL) / 1000000000ULL;
if (cc > 65535) {
mp_raise_ValueError(MP_ERROR_TEXT("duty larger than period"));
}

Wyświetl plik

@ -234,7 +234,7 @@ void gc_collect(void) {
}
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught exception %p\n", val);
mp_printf(&mp_plat_print, "FATAL: uncaught exception %p\n", val);
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val));
for (;;) {
__breakpoint();

Wyświetl plik

@ -91,22 +91,31 @@ static inline unsigned int mp_hal_pin_name(mp_hal_pin_obj_t pin) {
}
static inline void mp_hal_pin_input(mp_hal_pin_obj_t pin) {
gpio_set_function(pin, GPIO_FUNC_SIO);
gpio_set_dir(pin, GPIO_IN);
machine_pin_open_drain_mask &= ~(1 << pin);
gpio_set_function(pin, GPIO_FUNC_SIO);
}
static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) {
gpio_set_function(pin, GPIO_FUNC_SIO);
gpio_set_dir(pin, GPIO_OUT);
machine_pin_open_drain_mask &= ~(1 << pin);
gpio_set_function(pin, GPIO_FUNC_SIO);
}
static inline void mp_hal_pin_open_drain_with_value(mp_hal_pin_obj_t pin, int v) {
if (v) {
gpio_set_dir(pin, GPIO_IN);
gpio_put(pin, 0);
} else {
gpio_put(pin, 0);
gpio_set_dir(pin, GPIO_OUT);
}
machine_pin_open_drain_mask |= 1 << pin;
gpio_set_function(pin, GPIO_FUNC_SIO);
}
static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) {
gpio_set_function(pin, GPIO_FUNC_SIO);
gpio_set_dir(pin, GPIO_IN);
gpio_put(pin, 0);
machine_pin_open_drain_mask |= 1 << pin;
mp_hal_pin_open_drain_with_value(pin, 1);
}
static inline void mp_hal_pin_config(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, uint32_t alt) {

Wyświetl plik

@ -120,6 +120,11 @@ STATIC mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) {
offset += mp_obj_get_int(args[3]);
}
memcpy(bufinfo.buf, (void *)(XIP_BASE + self->flash_base + offset), bufinfo.len);
// MICROPY_EVENT_POLL_HOOK_FAST is called here to avoid a fail in registering
// USB at boot time, if the board is busy loading files or scanning the file
// system. MICROPY_EVENT_POLL_HOOK_FAST calls tud_task(). As the alternative
// tud_task() should be called in the USB IRQ. See discussion in PR #10423.
MICROPY_EVENT_POLL_HOOK_FAST;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rp2_flash_readblocks_obj, 3, 4, rp2_flash_readblocks);
@ -134,7 +139,7 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
flash_range_erase(self->flash_base + offset, bufinfo.len);
MICROPY_END_ATOMIC_SECTION(atomic_state);
MICROPY_EVENT_POLL_HOOK
MICROPY_EVENT_POLL_HOOK_FAST;
// TODO check return value
} else {
offset += mp_obj_get_int(args[3]);
@ -143,7 +148,7 @@ STATIC mp_obj_t rp2_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
flash_range_program(self->flash_base + offset, bufinfo.buf, bufinfo.len);
MICROPY_END_ATOMIC_SECTION(atomic_state);
MICROPY_EVENT_POLL_HOOK
MICROPY_EVENT_POLL_HOOK_FAST;
// TODO check return value
return mp_const_none;
}

Wyświetl plik

@ -2,7 +2,7 @@ CFLAGS_MCU += -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float
MPY_CROSS_MCU_ARCH = armv6m
SRC_S += shared/runtime/gchelper_m0.s
SRC_S += shared/runtime/gchelper_thumb1.s
LIBM_SRC_C += $(addprefix lib/libm/,\
acoshf.c \

Wyświetl plik

@ -6,7 +6,7 @@ MICROPY_VFS_LFS2 ?= 1
MICROPY_VFS_FAT ?= 1
FROZEN_MANIFEST ?= mcu/$(MCU_SERIES_LOWER)/manifest.py
SRC_S += shared/runtime/gchelper_m3.s
SRC_S += shared/runtime/gchelper_thumb2.s
SRC_C += \
fatfs_port.c \

Wyświetl plik

@ -362,18 +362,18 @@ ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 g0 l0))
CSUPEROPT = -Os # save some code space
SRC_O += \
resethandler_m0.o \
shared/runtime/gchelper_m0.o
shared/runtime/gchelper_thumb1.o
else
ifeq ($(MCU_SERIES),l1)
CFLAGS += -DUSE_HAL_DRIVER
SRC_O += \
resethandler_m3.o \
shared/runtime/gchelper_m3.o
shared/runtime/gchelper_thumb2.o
else
SRC_O += \
system_stm32.o \
resethandler.o \
shared/runtime/gchelper_m3.o
shared/runtime/gchelper_thumb2.o
endif
endif
@ -546,7 +546,7 @@ define RUN_DFU
$(ECHO) "Writing $(1) to the board"
$(if $(filter $(USE_PYDFU),1),\
$(Q)$(PYTHON) $(PYDFU) --vid $(BOOTLOADER_DFU_USB_VID) --pid $(BOOTLOADER_DFU_USB_PID) -u $(1),
$(Q)$(DFU_UTIL) -a 0 -d $(BOOTLOADER_DFU_USB_VID):$(BOOTLOADER_DFU_USB_PID) -D $(1))
$(Q)$(DFU_UTIL) -a 0 -d $(BOOTLOADER_DFU_USB_VID):$(BOOTLOADER_DFU_USB_PID) -D $(1) -s :leave)
endef
define RUN_STLINK

Wyświetl plik

@ -44,15 +44,12 @@ _micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(DTCM) + LENGTH(DTCM);
_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS);
_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS);
REGION_ALIAS("FLASH_COMMON", FLASH_TEXT);
/* define output sections */
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH_TEXT
INCLUDE common_isr.ld
.text :
{
@ -65,6 +62,6 @@ SECTIONS
_etext = .;
} >FLASH_TEXT
INCLUDE common_extratext_data_in_flash_text.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
}

Wyświetl plik

@ -42,6 +42,8 @@ _heap_end = _sstack;
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_COMMON", FLASH_APP);
/* Define output sections */
SECTIONS
{
@ -56,22 +58,8 @@ SECTIONS
. = ALIGN(4);
} >FLASH_EXT
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH_APP
.text :
{
. = ALIGN(4);
*(.text*)
*(.rodata*)
. = ALIGN(4);
_etext = .;
} >FLASH_APP
INCLUDE common_extratext_data_in_flash_app.ld
INCLUDE common_isr.ld
INCLUDE common_text.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
}

Wyświetl plik

@ -41,15 +41,12 @@ _heap_end = _sstack;
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_COMMON", FLASH_APP);
/* Define output sections */
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH_APP
INCLUDE common_isr.ld
.text :
{
@ -62,6 +59,6 @@ SECTIONS
_etext = .;
} >FLASH_APP
INCLUDE common_extratext_data_in_flash_app.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
}

Wyświetl plik

@ -40,6 +40,8 @@ _heap_end = _sstack;
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_COMMON", FLASH_APP);
SECTIONS
{
/* Define the code that goes in QSPI flash */
@ -50,24 +52,8 @@ SECTIONS
. = ALIGN(4);
} >FLASH_QSPI
/* The startup code goes first into main flash */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH_APP
/* The program code and other data goes into flash */
.text :
{
. = ALIGN(4);
*(.text*)
*(.rodata*)
. = ALIGN(4);
_etext = .;
} >FLASH_APP
INCLUDE common_extratext_data_in_flash_app.ld
INCLUDE common_isr.ld
INCLUDE common_text.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
}

Wyświetl plik

@ -12,31 +12,13 @@
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_COMMON", FLASH);
/* define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text*) /* .text* sections (code) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
/* *(.glue_7) */ /* glue arm to thumb code */
/* *(.glue_7t) */ /* glue thumb to arm code */
. = ALIGN(4);
_etext = .; /* define a global symbol at end of code */
} >FLASH
INCLUDE common_isr.ld
INCLUDE common_text.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
}

Wyświetl plik

@ -12,31 +12,13 @@
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_COMMON", FLASH_APP);
/* define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH_APP
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text*) /* .text* sections (code) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
/* *(.glue_7) */ /* glue arm to thumb code */
/* *(.glue_7t) */ /* glue thumb to arm code */
. = ALIGN(4);
_etext = .; /* define a global symbol at end of code */
} >FLASH_APP
INCLUDE common_extratext_data_in_flash_app.ld
INCLUDE common_isr.ld
INCLUDE common_text.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
}

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