With a warning that this way of constructing software I2C/SPI is
deprecated. The check and warning will be removed in a future release.
This should help existing code to migrate to the new SoftI2C/SoftSPI types.
Signed-off-by: Damien George <damien@micropython.org>
Previous commits removed the ability for one I2C/SPI constructor to
construct both software- or hardware-based peripheral instances. Such
construction is now split to explicit soft and non-soft types.
This commit makes both types available in all ports that previously could
create both software and hardware peripherals: machine.I2C and machine.SPI
construct hardware instances, while machine.SoftI2C and machine.SoftSPI
create software instances.
This is a breaking change for use of software-based I2C and SPI. Code that
constructed I2C/SPI peripherals in the following way will need to be
changed:
machine.I2C(-1, ...) -> machine.SoftI2C(...)
machine.I2C(scl=scl, sda=sda) -> machine.SoftI2C(scl=scl, sda=sda)
machine.SPI(-1, ...) -> machine.SoftSPI(...)
machine.SPI(sck=sck, mosi=mosi, miso=miso)
-> machine.SoftSPI(sck=sck, mosi=mosi, miso=miso)
Code which uses machine.I2C and machine.SPI classes to access hardware
peripherals does not need to change.
Signed-off-by: Damien George <damien@micropython.org>
The SoftSPI constructor is now used soley to create SoftSPI instances, it
can no longer delegate to create a hardware-based SPI instance.
Signed-off-by: Damien George <damien@micropython.org>
Also rename machine_i2c_type to mp_machine_soft_i2c_type. These changes
make it clear that it's a soft-I2C implementation, and match SoftSPI.
Signed-off-by: Damien George <damien@micropython.org>
For time-based functions that work with absolute time there is the need for
an Epoch, to set the zero-point at which the absolute time starts counting.
Such functions include time.time() and filesystem stat return values. And
different ports may use a different Epoch.
To make it clearer what functions use the Epoch (whatever it may be), and
make the ports more consistent with their use of the Epoch, this commit
renames all Epoch related functions to include the word "epoch" in their
name (and remove references to "2000").
Along with this rename, the following things have changed:
- mp_hal_time_ns() is now specified to return the number of nanoseconds
since the Epoch, rather than since 1970 (but since this is an internal
function it doesn't change anything for the user).
- littlefs timestamps on the esp8266 have been fixed (they were previously
off by 30 years in nanoseconds).
Otherwise, there is no functional change made by this commit.
Signed-off-by: Damien George <damien@micropython.org>
To portably get the Epoch. This is simply aliased to localtime() on ports
that are not timezone aware.
Signed-off-by: Damien George <damien@micropython.org>
This commit removes release-specific builds for the esp8266 and makes the
normal build of the GENERIC board more like the release build. This makes
esp8266 like all the other ports, for which there is no difference between
a daily build and a release build, making things less confusing.
Release builds were previously defined by UART_OS=-1 (disable OS messages)
and using manifest_release.py to include more frozen modules.
The changes in this commit are:
- Remove manifest_release.py.
- Add existing modules from manifest_release.py (except example code)
to the GENERIC board's manifest.py file.
- Change UART_OS default to -1 to disable OS messages by default.
Signed-off-by: Damien George <damien@micropython.org>
The PWM driver uses a double buffer for the PWM timing array, one in
current use and the other one to update when changing duty parameters.
The issue was that once the duty parameters were changed the updated buffer
was applied immediately without synchronising to the start of the PWM
period. By moving the buffer toggling/swapping to the interrupt when the
cycle is done there are no more glitches.
Prior to e0905e85a7 it was possible to
disable btree support on build. This patch allows to configure btree
support on make again and also the two new introduced options for FAT and
LFS2 filesystems.
The ones that are moved out of iRAM should not need to be there, because
either they call functions in iROM (eg mp_hal_stdout_tx_str), or they are
only ever called from a function in iROM and not from an interrupt (eg
ets_esf_free_bufs).
This frees up about 800 bytes of iRAM.
GPIO interrupts can occur when the flash ROM cache is in use and so the
GPIO interrupt handler must be in iRAM. This commit moves the handler to
iRAM, and also moves mp_sched_schedule to iRAM which is called by
pin_intr_handler.
As part of this fix the Pin class can no longer support hard=True in the
Pin.irq() method, because the VM and runtime are too big to put in iRAM.
Fixes#5714.
This change is made for two reasons:
1. A 3rd-party library (eg berkeley-db-1.xx, axtls) may use the system
provided errno for certain errors, and yet MicroPython stream objects
that it calls will be using the internal mp_stream_errno. So if the
library returns an error it is not known whether the corresponding errno
code is stored in the system errno or mp_stream_errno. Using the system
errno in all cases (eg in the mp_stream_posix_XXX wrappers) fixes this
ambiguity.
2. For systems that have threading the system-provided errno should always
be used because the errno value is thread-local.
For systems that do not have an errno, the new lib/embed/__errno.c file is
provided.
Note: the uncrustify configuration is explicitly set to 'add' instead of
'force' in order not to alter the comments which use extra spaces after //
as a means of indenting text for clarity.
This commit changes the esp8266 boards to use littlefs v2 as the
filesystem, rather than FAT. Since the esp8266 doesn't expose the
filesystem to the PC over USB there's no strong reason to keep it as FAT.
Littlefs is smaller in code size, is more efficient in use of flash to
store data, is resilient over power failure, and using it saves about 4k of
heap RAM, which can now be used for other things.
This is a backwards incompatible change because all existing esp8266 boards
will need to update their filesystem after installing new firmware (eg
backup old files, install firmware, restore files to new filesystem).
As part of this commit the memory layout of the default board (GENERIC) has
changed. It now allocates all 1M of memory-mapped flash to the firmware,
so the filesystem area starts at the 2M point. This is done to allow more
frozen bytecode to be stored in the 1M of memory-mapped flash. This
requires an esp8266 module with 2M or more of flash to work, so a new board
called GENERIC_1M is added which has the old memory-mapping (but still
changed to use littlefs for the filesystem).
In summary there are now 3 esp8266 board definitions:
- GENERIC_512K: for 512k modules, doesn't have a filesystem.
- GENERIC_1M: for 1M modules, 572k for firmware+frozen code, 396k for
filesystem (littlefs).
- GENERIC: for 2M (or greater) modules, 968k for firmware+frozen code,
1M+ for filesystem (littlefs), FAT driver also included in firmware for
use on, eg, external SD cards.
This function is not used by the core but having it as part of the build
allows it to be used by user C modules, or board extensions. The linker
won't include it in the final firmware if it remains unused.
This string is recognised by uncrustify, to disable formatting in the
region marked by these comments. This is necessary in the qstrdef*.h files
to prevent modification of the strings within the Q(...). In other places
it is used to prevent excessive reformatting that would make the code less
readable.
It was originally in IRAM due to the linker script specification, but
since the function moved from lib/utils/interrupt_char.c to py/scheduler.c
it needs to be put back in IRAM.
Previous behaviour is when this argument is set to "true", in which case
the function will raise any pending exception. Setting it to "false" will
cancel any pending exception.
The ability to change the host is a frequently requested feature, so
explicitly document how it can be achieved using the existing code.
See issues #2121, #4385, #4622, #5122, #5536.
Prior to this commit, if the flash filesystem was not formatted then it
would error: "AttributeError: 'FlashBdev' object has no attribute 'mount'".
That is due to it not being able to detect the filesystem on the block
device and just trying to mount the block device directly.
This commit fixes the issue by just catching all exceptions. Also it's not
needed to try the mount if `flashbdev.bdev` is None.
Move webrepl support code from ports/esp8266/modules into extmod/webrepl
(to be alongside extmod/modwebrepl.c), and use frozen manifests to include
it in the build on esp8266 and esp32.
A small modification is made to webrepl.py to make it work on non-ESP
ports, i.e. don't call dupterm_notify if not available.
Implements text, rodata and bss generalised relocations, as well as generic
qstr-object linking. This allows importing dynamic native modules on all
supported architectures in a unified way.
This commit removes the Makefile-level MICROPY_FATFS config and moves the
MICROPY_VFS_FAT config to the Makefile level to replace it. It also moves
the include of the oofatfs source files in the build from each port to a
central place in extmod/extmod.mk.
For a port to enabled VFS FAT support it should now set MICROPY_VFS_FAT=1
at the level of the Makefile. This will include the relevant oofatfs files
in the build and set MICROPY_VFS_FAT=1 at the C (preprocessor) level.
This commit implements automatic module weak links for all built-in
modules, by searching for "ufoo" in the built-in module list if "foo"
cannot be found. This means that all modules named "ufoo" are always
available as "foo". Also, a port can no longer add any other weak links,
which makes strict the definition of a weak link.
It saves some code size (about 100-200 bytes) on ports that previously had
lots of weak links.
Some changes from the previous behaviour:
- It doesn't intern the non-u module names (eg "foo" is not interned),
which saves code size, but will mean that "import foo" creates a new qstr
(namely "foo") in RAM (unless the importing module is frozen).
- help('modules') no longer lists non-u module names, only the u-variants;
this reduces duplication in the help listing.
Weak links are effectively the same as having a set of symbolic links on
the filesystem that is searched last. So an "import foo" will search
built-in modules first, then all paths in sys.path, then weak links last,
importing "ufoo" if it exists. Thus a file called "foo.py" somewhere in
sys.path will still have precedence over the weak link of "foo" to "ufoo".
See issues: #1740, #4449, #5229, #5241.
When loading a manifest file, e.g. by include(), it will chdir first to the
directory of that manifest. This means that all file operations within a
manifest are relative to that manifest's location.
As a consequence of this, additional environment variables are needed to
find absolute paths, so the following are added: $(MPY_LIB_DIR),
$(PORT_DIR), $(BOARD_DIR). And rename $(MPY) to $(MPY_DIR) to be
consistent.
Existing manifests are updated to match.
The specific board can be selected with the BOARD makefile variable. This
defaults (if not specified) to BOARD=GENERIC, which is the original default
firmware build. For the 512k target use BOARD=GENERIC_512K.
The stm32 and nrf ports already had the behaviour that they would first
check if the script exists before executing it, and this patch makes all
other ports work the same way. This helps when developing apps because
it's hard to tell (when unconditionally trying to execute the scripts) if
the resulting OSError at boot up comes from missing boot.py or main.py, or
from some other error. And it's not really an error if these scripts don't
exist.
As mentioned in #4450, `websocket` was experimental with a single intended
user, `webrepl`. Therefore, we'll make this change without a weak
link `websocket` -> `uwebsocket`.
Replaces "PYB: soft reboot" with "MPY: soft reboot", etc.
Having a consistent prefix across ports reduces the difference between
ports, which is a general goal. And this change won't break pyboard.py
because that tool only looks for "soft reboot".
The original behaviour of open-drain-high was to use the open-drain mode of
the GPIO pin, and this seems to make driving a DHT more reliable. See
issue #4233.
So that the user can explicitly deactivate UART(0) if needed. See
issue #4314.
This introduces some risk to "brick" the device, if the user disables the
REPL without providing an alternative REPL (eg WebREPL), or any way to
reenable it. In such a case the device needs to be erased and
reprogrammed. This seems unavoidable, given the desire to have the option
to use the UART for something other than the REPL.
Building axtls gives a lot of warnings with -Wall enabled, and explicitly
disabling all of them cannot be done in a way compatible with gcc and
clang, and likely other compilers. So just use -Wno-all to prevent all of
the extra warnings (in addition to the necessary -Wno-unused-parameter,
-Wno-uninitialized, -Wno-sign-compare and -Wno-old-style-definition).
Fixes issue #4182.
This patch in effect renames MICROPY_DEBUG_PRINTER_DEST to
MICROPY_DEBUG_PRINTER, moving its default definition from
lib/utils/printf.c to py/mpconfig.h to make it official and documented, and
makes this macro a pointer rather than the actual mp_print_t struct. This
is done to get consistency with MICROPY_ERROR_PRINTER, and provide this
macro for use outside just lib/utils/printf.c.
Ports are updated to use the new macro name.
machine.Timer now takes a new argument in its constructor (or init method):
tick_hz which specified the units for the period argument. The period of
the timer in seconds is: period/tick_hz.
For backwards compatibility tick_hz defaults to 1000. If the user wants to
specify the period (numerator) in microseconds then tick_hz can be set to
1000000. The user can also specify a period of an arbitrary number of
cycles of an arbitrary frequency using these two arguments.
An additional freq argument has been added to allow frequencies to be
specified directly in Hertz. This supports floating point values when
available.
This patch allows scripts to have more control over the software WDT. If
an instance of machine.WDT is created then the underlying OS is prevented
from feeding the software WDT, and it is up to the user script to feed it
instead via WDT.feed(). The timeout for this WDT is currently fixed and
will be between 1.6 and 3.2 seconds.
A flash erase/write takes a while and during that time tasks may be
scheduled via an IRQ. To prevent overflow of the task queue (and loss of
tasks) call ets_loop_iter() before and after slow flash operations.
Note: if a task is posted to a full queue while a flash operation is in
progress then this leads to a fault when trying to print out the error
message that the queue is full. This patch doesn't try to fix this
particular issue, it just prevents it from happening in the first place.
This function may be called from a UART IRQ, which may interrupt the system
when it is erasing/reading/writing flash. In such a case all code
executing from the IRQ must be in iRAM (because the SPI flash is busy), so
put mp_keyboard_interrupt in iRAM so ctrl-C can be caught during flash
access.
This patch also takes get_fattime out of iRAM and puts it in iROM to make
space for mp_keyboard_interrupt. There's no real need to have get_fattime
in iRAM because it calls other functions in iROM.
Fixes issue #3897.
They are now efficient (in runtime performance) and provide a useful
feature that's hard to obtain without them enabled.
See issue #3644 and PR #3826 for background.
This patch makes it so that UART(0) can by dynamically attached to and
detached from the REPL by using the uos.dupterm function. Since WebREPL
uses dupterm slot 0 the UART uses dupterm slot 1 (a slot which is newly
introduced by this patch). UART(0) must now be attached manually in
boot.py (or otherwise) and inisetup.py is changed to provide code to do
this. For example, to attach use:
import uos, machine
uart = machine.UART(0, 115200)
uos.dupterm(uart, 1)
and to detach use:
uos.dupterm(None, 1)
When attached, all incoming chars on UART(0) go straight to stdin so
uart.read() will always return None. Use sys.stdin.read() if it's needed
to read characters from the UART(0) while it's also used for the REPL (or
detach, read, then reattach). When detached the UART(0) can be used for
other purposes.
If there are no objects in any of the dupterm slots when the REPL is
started (on hard or soft reset) then UART(0) is automatically attached.
Without this, the only way to recover a board without a REPL would be to
completely erase and reflash (which would install the default boot.py which
attaches the REPL).
Disabling this saves around 6000 bytes of code space and gets the 512k
build fitting in the available flash again (it increased lately due to an
increase in the size of the ESP8266 SDK).
Certain pins (eg 4 and 5) seem to behave differently at the hardware level
when in open-drain mode: they glitch when set "high" and drive the pin
active high for a brief period before disabling the output driver. To work
around this make the pin an input to let it float high.
This patch takes the software SPI implementation from extmod/machine_spi.c
and moves it to a dedicated file in drivers/bus/softspi.c. This allows the
SPI driver to be used independently of the uPy runtime, making it a more
general component.
The PWM at full value was not considered as an "active" channel so if no
other channel was used the timer used to mange PWM was not started. So
when another duty value was set the PWM timer restarted and there was a
visible glitch when driving LEDs. Such a glitch can be seen with the
following code (assuming active-low LED on pin 0):
p = machine.PWM(machine.Pin(0))
p.duty(1023) # full width, LED is off
p.duty(1022) # LED flashes brightly then goes dim
This patch fixes the glitch.
These were copied from the stm32 port (then stmhal) at the very beginning
of this port, with the anticipation that the esp8266 port would have board
definition files with a list of valid pins and their names. But that has
not been implemented and likely won't be, so remove the corresponding lines
from the Makefile.
Because otherwise the function can return with data still waiting to be
clocked out, and CS might then be disabled before the SPI transaction is
complete. Fixes issue #3487.
Prior to this fix, enabling WebREPL for the first time via webrepl_setup
did not work at all because "boot.py" did not contain any lines with
"webrepl" in them that could be uncommented.
This patch simplifies the str creation API to favour the common case of
creating a str object that is not forced to be interned. To force
interning of a new str the new mp_obj_new_str_via_qstr function is added,
and should only be used if warranted.
Apart from simplifying the mp_obj_new_str function (and making it have the
same signature as mp_obj_new_bytes), this patch also reduces code size by a
bit (-16 bytes for bare-arm and roughly -40 bytes on the bare-metal archs).
Recent vendor SDKs ship libs with code in .text section, which previously
was going into .irom0.text. Adjust the linker script to route these
sections back to iROM (follows upstream change).
Macros to convert big-endian values to host byte order and vice-versa.
These were defined in adhoc way for some ports (e.g. esp8266), allow
reuse, provide default implementations, while allow ports to override.
In the vendor SDK 2.1.0, some of the functions which previously didn't
have prototypes, finally acquired them. Change prototypes on our side
to match those in vendor headers, to avoid warnings-as-errors.
The uos.dupterm() signature and behaviour is updated to reflect the latest
enhancements in the docs. It has minor backwards incompatibility in that
it no longer accepts zero arguments.
The dupterm_rx helper function is moved from esp8266 to extmod and
generalised to support multiple dupterm slots.
A port can specify multiple slots by defining the MICROPY_PY_OS_DUPTERM
config macro to an integer, being the number of slots it wants to have;
0 means to disable the dupterm feature altogether.
The unix and esp8266 ports are updated to work with the new interface and
are otherwise unchanged with respect to functionality.
Header files that are considered internal to the py core and should not
normally be included directly are:
py/nlr.h - internal nlr configuration and declarations
py/bc0.h - contains bytecode macro definitions
py/runtime0.h - contains basic runtime enums
Instead, the top-level header files to include are one of:
py/obj.h - includes runtime0.h and defines everything to use the
mp_obj_t type
py/runtime.h - includes mpstate.h and hence nlr.h, obj.h, runtime0.h,
and defines everything to use the general runtime support functions
Additional, specific headers (eg py/objlist.h) can be included if needed.
This is to keep the top-level directory clean, to make it clear what is
core and what is a port, and to allow the repository to grow with new ports
in a sustainable way.